diff --git a/build.sbt b/build.sbt
index 6486ba2219..4090fcd3d8 100644
--- a/build.sbt
+++ b/build.sbt
@@ -272,10 +272,8 @@ lazy val ergoCore = (project in file("ergo-core"))
commonSettings,
name := "ergo-core",
libraryDependencies ++= Seq(
- "com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion,
"com.iheart" %% "ficus" % ficusVersion,
- "com.github.ben-manes.caffeine" % "caffeine" % "2.9.3", // use 3.x only for java 11+
effectiveSigma,
(effectiveSigma % Test).classifier("tests")
),
diff --git a/ergo-core/src/test/resources/application.conf b/ergo-core/src/test/resources/application.conf
deleted file mode 100644
index f64e12486a..0000000000
--- a/ergo-core/src/test/resources/application.conf
+++ /dev/null
@@ -1,209 +0,0 @@
-ergo {
- # Directory to keep data
- directory = ${user.dir}"/.ergo_test/data"
-
- networkType = "testnet"
-
- # Settings for node view holder regime. See papers.yellow.ModifiersProcessing.md
- node {
- # State type. Possible options are:
- # "utxo" - keep full utxo set, that allows to validate arbitrary block and generate ADProofs
- # "digest" - keep state root hash only and validate transactions via ADProofs
- stateType = "utxo"
-
- # Download block transactions and verify them (requires BlocksToKeep == 0 if disabled)
- verifyTransactions = true
-
- # Number of last blocks to keep with transactions and ADproofs, for all other blocks only header will be stored.
- # Keep all blocks from genesis if negative
- blocksToKeep = 1000
-
- # Download PoPoW proof on node bootstrap
- popowBootstrap = false
-
- # Minimal suffix size for PoPoW proof (may be pre-defined constant or settings parameter)
- popowSuffix = 10
-
- # Is the node is doing mining
- mining = true
-
- # maximum cost of transaction for it to not be considered malicious
- maxTransactionCost = 1000000
-
- useExternalMiner = false
-
- # Public key mining rewards will be dedicated to
- miningPubKeyHex = null
-
- # If true, a node generates blocks being offline. The only really useful case for it probably is to start a new
- # blockchain
- offlineGeneration = false
-
- # Interval of polling for a candidate
- internalMinerPollingInterval = 1s
-
- mempoolCapacity = 100000
-
- mempoolCleanupDuration = 10s
-
- mempoolSorting = "bySize"
-
- # Number of transactions from mempool to be re-broadcasted at each epoch
- rebroadcastCount = 3
-
- # Minimal fee amount of transactions mempool accepts
- minimalFeeAmount = 0
-
- # A node is considering that the chain is synced if sees a block header with timestamp no more
- # than headerChainDiff blocks on average from future
- # for tests, the value is 100 (as in mainnet)
- headerChainDiff = 100
-
- # Dump ADProofs only for the suffix given during bootstrapping
- adProofsSuffixLength = 114688 // 112k
- }
-
- cache {
- history {
- # Number of recently used block sections that will be kept in memory
- blockSectionsCacheSize = 12
-
- # Number of recently used headers that will be kept in memory
- headersCacheSize = 100
-
- # Number of recently used indexes that will be kept in memory
- indexesCacheSize = 1000
- }
- network {
- # Maximum number of invalid modifiers in bloom filters
- invalidModifiersBloomFilterCapacity = 10000000
-
- # Non-zero fraction of 1 as a rate of element expiration when capacity is full, the lower the more gradual expiration.
- # example : 0.1 is represented as 10 bloom filters expiring one by one
- invalidModifiersBloomFilterExpirationRate = 0.1
-
- # Maximum number of invalid modifiers to keep in cache, following modifiers are kept in bloom filters
- invalidModifiersCacheSize = 10000
-
- # For how long to keep invalid modifiers in cache
- invalidModifiersCacheExpiration = 6h
- }
- mempool {
- # Maximum number of invalid modifiers in bloom filters
- invalidModifiersBloomFilterCapacity = 10000000
-
- # Non-zero fraction of 1 as a rate of element expiration when capacity is full, the lower the more gradual expiration.
- # example : 0.1 is represented as 10 bloom filters expiring one by one
- invalidModifiersBloomFilterExpirationRate = 0.1
-
- # Maximum number of invalid modifiers to keep in cache, following modifiers are kept in bloom filters
- invalidModifiersCacheSize = 10000
-
- # For how long to keep invalid modifiers in cache
- invalidModifiersCacheExpiration = 6h
- }
- }
-
- #Chain-specific settings. Change only if you are going to launch a new chain!
- chain {
-
- genesisId = null
-
- monetary {
- # delay between the block mined and a time, when the reward can be spent. ~ 1 day.
- minerRewardDelay = -1000
- }
-
- # Public keys of founders for tests. Two keys from defaultProver and one random one.
- foundersPubkeys = [
- "038b0f29a60fa8d7e1aeafbe512288a6c6bc696547bbf8247db23c95e83014513c",
- "031ee1ab3b729f21e0dcee05642a63745286354d8e511e6376838e235a28078c01",
- "0248502b73f35bb2b77eb5ad16f80f55beff178ccd104488edd2d8b69c192c109d"
- ]
-
- # Base16 representation of genesis state roothash
- genesisStateDigestHex = "93914ecff82cea3b53b32d0f0527069f7361ef3b426271235eb6f4d76337900202"
-
- # Network address prefix, currently reserved values are 0x00 (money chain mainnet) and 0x10 (16 in decimal,
- # money chain testnet)
- addressPrefix = 16
-
- # Desired time interval between blocks
- blockInterval = 1m
-
- # Difficulty network start with
- initialDifficultyHex = "01"
-
- # length of an epoch in difficulty recalculation
- epochLength = 100
-
- //Proof-of-Work algorithm and its parameters. Possible options are "fake" and "autolykos".
- powScheme {
- powType = "fake"
- }
-
- makeSnapshotEvery = 128
- }
-
- wallet {
-
- secretStorage {
-
- secretDir = ${ergo.directory}"/wallet/keystore"
-
- encryption {
-
- # Pseudo-random function with output of length `dkLen` (PBKDF2 param)
- prf = "HmacSHA256"
-
- # Number of PBKDF2 iterations (PBKDF2 param)
- c = 128000
-
- # Desired bit-length of the derived key (PBKDF2 param)
- dkLen = 256
- }
-
- }
-
- # Generating seed length in bits
- # Options: 128, 160, 192, 224, 256
- seedStrengthBits = 160
-
- # Language to be used in mnemonic seed
- # Options: "chinese_simplified", "chinese_traditional", "english", "french", "italian", "japanese", "korean", "spanish"
- mnemonicPhraseLanguage = "english"
-
- defaultTransactionFee = 10000
-
- # Boxes with value smaller than dustLimit are disregarded in wallet scan logic
- dustLimit = 999
-
- # Save used boxes (may consume additinal disk space) or delete them immediately
- keepSpentBoxes = false
-
- # Mnemonic seed used in wallet for tests
- testMnemonic = "ozone drill grab fiber curtain grace pudding thank cruise elder eight picnic"
-
- # Number of keys to be generated for tests
- testKeysQty = 5
- }
-
-}
-
-scorex {
- restApi {
- apiKeyHash = null
- publicUrl = "https://example.com:80"
- }
-}
-
-
-akka {
- test {
- timefactor = 3 # duration scale factor to prevent spurious test failures on the heavily loaded CI servers
- }
- # Don't terminate ActorSystem via CoordinatedShutdown in tests
- coordinated-shutdown.terminate-actor-system = off
- coordinated-shutdown.run-by-actor-system-terminate = off
- coordinated-shutdown.run-by-jvm-shutdown-hook = off
-}
diff --git a/ergo-core/src/test/resources/difficulty.csv b/ergo-core/src/test/resources/difficulty.csv
deleted file mode 100644
index b91f7bbc0e..0000000000
--- a/ergo-core/src/test/resources/difficulty.csv
+++ /dev/null
@@ -1,30209 +0,0 @@
-height,timestamp,requiredDifficulty
-0,1512376702808,1
-1,1512376710654,1
-2,1512376717432,1
-3,1512376724339,1
-4,1512376728328,1
-5,1512376732220,1
-6,1512376736177,1
-7,1512376740239,1
-8,1512376744176,1
-9,1512376748188,1
-10,1512376752090,1
-11,1512376755962,1
-12,1512376759932,1
-13,1512376763919,1
-14,1512376767935,1
-15,1512376771852,1
-16,1512376775927,1
-17,1512376779911,1
-18,1512376783860,1
-19,1512376787761,1
-20,1512376791808,1
-21,1512376795699,1
-22,1512376799555,1
-23,1512376803585,1
-24,1512376807568,1
-25,1512376811411,1
-26,1512376816170,1
-27,1512376820230,1
-28,1512376928330,1
-29,1512376934622,1
-30,1512376939460,1
-31,1512376943403,1
-32,1512376947512,1
-33,1512376951541,1
-34,1512376955546,1
-35,1512376959564,1
-36,1512376963639,1
-37,1512376967580,1
-38,1512376971575,1
-39,1512376975547,1
-40,1512376979559,1
-41,1512376983535,1
-42,1512376988400,1
-43,1512376992096,1
-44,1512376996156,1
-45,1512377000125,1
-46,1512377004064,1
-47,1512377007974,1
-48,1512377011880,1
-49,1512377015762,1
-50,1512377019740,1
-51,1512377024191,1
-52,1512377028141,1
-53,1512377032070,1
-54,1512377036014,1
-55,1512377039969,1
-56,1512377043907,1
-57,1512377047826,1
-58,1512377051671,1
-59,1512377056107,1
-60,1512377059990,1
-61,1512377063895,1
-62,1512377067814,1
-63,1512377071710,1
-64,1512377075693,1
-65,1512377079857,1
-66,1512377083788,1
-67,1512377087710,1
-68,1512377091621,1
-69,1512377095570,1
-70,1512377100010,1
-71,1512377104491,1
-72,1512377108678,1
-73,1512377115336,1
-74,1512377119269,1
-75,1512377126164,1
-76,1512377130094,1
-77,1512377134546,1
-78,1512377138473,1
-79,1512377142365,1
-80,1512377146328,1
-81,1512377150225,1
-82,1512377154212,1
-83,1512377161021,1
-84,1512377165104,1
-85,1512377171793,1
-86,1512377175731,1
-87,1512377179652,1
-88,1512377183568,1
-89,1512377187518,1
-90,1512377191454,1
-91,1512377195549,1
-92,1512377199497,1
-93,1512377203366,1
-94,1512377207321,1
-95,1512377214132,1
-96,1512377218034,1
-97,1512377221973,1
-98,1512377226221,1
-99,1512377230160,1
-100,1512377234090,1
-101,1512377238006,13
-102,1512377253487,20
-103,1512377272207,22
-104,1512377296486,24
-105,1512377303341,26
-106,1512377328053,34
-107,1512379794273,37
-108,1512379875509,36
-109,1512380096763,36
-110,1512380110870,35
-111,1512380183985,42
-112,1512380247017,43
-113,1512380307408,43
-114,1512380402090,43
-115,1512380640913,43
-116,1512380699580,42
-117,1512380731056,43
-118,1512380773113,45
-119,1512380828976,47
-120,1512380849902,48
-121,1512380948176,53
-122,1512381015071,52
-123,1512381056122,53
-124,1512381224581,54
-125,1512381470518,54
-126,1512381565769,53
-127,1512381587092,53
-128,1512381634900,58
-129,1512381659183,59
-130,1512381718624,63
-131,1512381775798,65
-132,1512381929226,65
-133,1512381959161,65
-134,1512382079796,69
-135,1512382265782,68
-136,1512382306708,67
-137,1512382416888,70
-138,1512382488190,69
-139,1512382517772,69
-140,1512382698363,73
-141,1512382804251,72
-142,1512382951735,73
-143,1512382962084,72
-144,1512382980407,86
-145,1512382987879,96
-146,1512383175798,124
-147,1512383189916,123
-148,1512383231195,141
-149,1512383584870,147
-150,1512383715201,144
-151,1512383761593,143
-152,1512383955938,148
-153,1512384163159,146
-154,1512384340686,144
-155,1512384573829,143
-156,1512384880262,141
-157,1512385078230,138
-158,1512385216690,137
-159,1512385393268,136
-160,1512385521442,135
-161,1512385603247,134
-162,1512385732154,134
-163,1512385813822,132
-164,1512385833400,133
-165,1512386065649,146
-166,1512386149061,143
-167,1512386198044,143
-168,1512386442829,147
-169,1512386548732,144
-170,1512387029948,144
-171,1512387040002,140
-172,1512387262252,169
-173,1512387389646,167
-174,1512387647248,164
-175,1512388234899,162
-176,1512388458448,157
-177,1512388466008,155
-178,1512389172537,199
-179,1512389729013,194
-180,1512390062663,190
-181,1512390179091,185
-182,1512390703660,185
-183,1512390757180,179
-184,1512391094809,182
-185,1512391449128,178
-186,1512392701770,173
-187,1512392846519,168
-188,1512392964651,165
-189,1512393004889,162
-190,1512393035216,167
-191,1512393210624,174
-192,1512393253838,170
-193,1512393432894,174
-194,1512393528564,170
-195,1512393672846,168
-196,1512393781623,164
-197,1512394331616,162
-198,1512394346138,157
-199,1512394623139,176
-200,1512394787236,170
-201,1512394967251,167
-202,1512394978109,165
-203,1512395243253,197
-204,1512395336415,192
-205,1512395430865,191
-206,1512395569241,193
-207,1512396103876,191
-208,1512396501632,184
-209,1512397128525,178
-210,1512397307764,171
-211,1512397625277,169
-212,1512397668726,164
-213,1512399122295,167
-214,1512399166932,159
-215,1512399464577,160
-216,1512399624673,154
-217,1512399935645,150
-218,1512400583173,145
-219,1512400685184,139
-220,1512400718966,136
-221,1512400831848,141
-222,1512401066067,137
-223,1512401137712,132
-224,1512401161613,130
-225,1512401214219,135
-226,1512401570074,135
-227,1512402084183,128
-228,1512402197199,125
-229,1512402354842,121
-230,1512402629700,118
-231,1512402972920,112
-232,1512402988542,106
-233,1512403820885,116
-234,1512458304892,111
-235,1512458864155,104
-236,1512458910949,96
-237,1512458972974,96
-238,1512459063261,92
-239,1512459081039,88
-240,1512459149627,95
-241,1512459174348,90
-242,1512459325602,92
-243,1512459379328,85
-244,1512459415232,90
-245,1512459435076,93
-246,1512459685910,113
-247,1512459774830,107
-248,1512459971221,113
-249,1512460056453,111
-250,1512460066731,108
-251,1512460290384,126
-252,1512460377195,124
-253,1512460461812,122
-254,1512460529906,118
-255,1512460711200,116
-256,1512460995832,111
-257,1512461316902,105
-258,1512461442790,99
-259,1512461524475,94
-260,1512461606197,90
-261,1512461821261,87
-262,1512461838770,82
-263,1512461865205,86
-264,1512461920316,89
-265,1512462101346,94
-266,1512462461697,88
-267,1512462467447,83
-268,1512462626554,114
-269,1512463472231,108
-270,1512464239625,102
-271,1512464334653,95
-272,1512464433864,107
-273,1512464857940,103
-274,1512465017261,98
-275,1512465399571,93
-276,1512466482393,86
-277,1512467473832,80
-278,1512468026867,98
-279,1512487875104,92
-280,1512488003896,86
-281,1512488022209,82
-282,1512488096062,88
-283,1512488436839,85
-284,1512488495191,82
-285,1512488515213,80
-286,1512488653765,84
-287,1512488766603,78
-288,1512488878103,74
-289,1512488939726,71
-290,1512488982106,72
-291,1512489154149,77
-292,1512489182748,73
-293,1512489214778,77
-294,1512489245226,77
-295,1512489314703,79
-296,1512489337370,76
-297,1512489641088,80
-298,1512489931149,75
-299,1512492427170,82
-300,1512492507174,76
-301,1512494254981,73
-302,1512494306451,68
-303,1512494417876,85
-304,1512494540707,82
-305,1512494598585,80
-306,1512494662335,80
-307,1512494740838,79
-308,1512495091393,77
-309,1512495495971,72
-310,1512496344448,68
-311,1512496630012,64
-312,1512496743642,60
-313,1512496851903,59
-314,1512497062602,56
-315,1512497113445,55
-316,1512497311410,53
-317,1512497326593,49
-318,1512497442286,53
-319,1512497500767,49
-320,1512497627777,47
-321,1512497736897,47
-322,1512497835899,45
-323,1512497919947,41
-324,1512498017360,39
-325,1512498075810,42
-326,1512498219549,42
-327,1512498322606,38
-328,1512498449993,35
-329,1512498523665,31
-330,1512498566822,28
-331,1512498598583,26
-332,1512498655322,23
-333,1512498799352,28
-334,1512498806267,24
-335,1512498849886,27
-336,1512498904793,24
-337,1512498912968,23
-338,1512498978317,27
-339,1512498994248,25
-340,1512499027307,29
-341,1512499067828,29
-342,1512499128507,30
-343,1512499203773,27
-344,1512499207722,26
-345,1512499330939,40
-346,1512499387166,42
-347,1512499417108,40
-348,1512499494973,40
-349,1512499620427,38
-350,1512499704750,35
-351,1512499805896,45
-352,1512499860224,42
-353,1512499871074,42
-354,1512499904799,49
-355,1512500103923,51
-356,1512500124571,48
-357,1512500170697,50
-358,1512500254470,49
-359,1512500322846,47
-360,1512500499014,46
-361,1512500706343,44
-362,1512500739374,40
-363,1512500798767,45
-364,1512501154392,47
-365,1512501417124,45
-366,1512501429988,42
-367,1512501474558,47
-368,1512501505585,62
-369,1512501566421,64
-370,1512501611738,63
-371,1512501624492,63
-372,1512501775277,73
-373,1512501875606,73
-374,1512501939481,69
-375,1512502018809,69
-376,1512502030744,68
-377,1512502037346,79
-378,1512502196206,104
-379,1512502246876,101
-380,1512502341931,101
-381,1512502559174,100
-382,1512502793321,102
-383,1512502854013,100
-384,1512502876202,101
-385,1512502995108,109
-386,1512503178349,111
-387,1512503184979,109
-388,1512503189269,145
-389,1512503217084,221
-390,1512503291289,236
-391,1512503469587,240
-392,1512503914938,237
-393,1512504029263,234
-394,1512504225082,235
-395,1512505047193,235
-396,1512505188486,231
-397,1512505419819,233
-398,1512505797574,229
-399,1512505959982,224
-400,1512507277787,221
-401,1512507324869,217
-402,1512507332475,221
-403,1512507551193,286
-404,1512507620188,283
-405,1512507628194,286
-406,1512508024076,365
-407,1512508063223,360
-408,1512508350624,375
-409,1512508992973,369
-410,1512509566808,361
-411,1512509857420,354
-412,1512511132041,348
-413,1512511403903,340
-414,1512511411233,334
-415,1512511891477,434
-416,1512512755692,426
-417,1512512856141,417
-418,1512513295968,420
-419,1512513577817,412
-420,1512514193824,405
-421,1512514893284,397
-422,1512515231118,388
-423,1512515484375,379
-424,1512515966461,373
-425,1512516142148,364
-426,1512517216694,359
-427,1512517298738,348
-428,1512517527972,348
-429,1512518728049,341
-430,1512518975274,330
-431,1512519382942,323
-432,1512519744440,314
-433,1512521958323,306
-434,1512523591163,295
-435,1512523866717,288
-436,1512524328418,280
-437,1512524535268,271
-438,1512524687222,266
-439,1512525148378,259
-440,1512525450766,251
-441,1512525869862,243
-442,1512526509332,234
-443,1512526542284,224
-444,1512526734150,230
-445,1512526784201,229
-446,1512527351400,229
-447,1512527489872,220
-448,1512528173588,213
-449,1512528210608,203
-450,1512528545893,205
-451,1512528817177,195
-452,1512529121145,186
-453,1512530127674,177
-454,1512531147750,171
-455,1512531271817,161
-456,1512531902544,153
-457,1512532007011,146
-458,1512532062456,139
-459,1512532435215,134
-460,1512532573747,124
-461,1512532869309,114
-462,1512532900231,104
-463,1512533205858,102
-464,1512533327972,92
-465,1512533427587,83
-466,1512533840566,73
-467,1512534341716,66
-468,1512534398577,56
-469,1512534548234,50
-470,1512534569387,40
-471,1512534593905,35
-472,1512534734625,34
-473,1512534886663,23
-474,1512535029547,13
-475,1512535068986,4
-476,1512535089183,1
-477,1512535119719,1
-478,1512535137488,1
-479,1512535154132,1
-480,1512535170950,1
-481,1512535197279,1
-482,1512535214967,1
-483,1512535228522,1
-484,1512535256454,1
-485,1512535270372,1
-486,1512535284915,1
-487,1512535304246,1
-488,1512535332702,1
-489,1512535349387,1
-490,1512535370730,1
-491,1512535390581,1
-492,1512535438794,1
-493,1512535474944,1
-494,1512535501972,1
-495,1512535557013,1
-496,1512535576032,1
-497,1512535596332,1
-498,1512535607604,1
-499,1512535624005,1
-500,1512535641003,1
-501,1512535649075,1
-502,1512535655810,1
-503,1512535663358,1
-504,1512535669728,1
-505,1512535676989,1
-506,1512535683785,1
-507,1512535696189,1
-508,1512535703333,1
-509,1512535710044,1
-510,1512535717402,1
-511,1512535724142,1
-512,1512535731647,1
-513,1512535738689,1
-514,1512535752088,1
-515,1512535759417,1
-516,1512535765817,1
-517,1512535773314,1
-518,1512535780495,1
-519,1512535793525,1
-520,1512535799886,1
-521,1512535806662,1
-522,1512535813857,1
-523,1512535820652,1
-524,1512535827468,1
-525,1512535834216,1
-526,1512535841044,1
-527,1512535847909,1
-528,1512535860406,1
-529,1512535867219,1
-530,1512535879904,1
-531,1512535886504,1
-532,1512535893489,1
-533,1512535900416,1
-534,1512535907437,1
-535,1512535913682,1
-536,1512535926135,1
-537,1512535934104,1
-538,1512535941206,1
-539,1512535948649,1
-540,1512535955907,1
-541,1512535963638,1
-542,1512535976705,1
-543,1512535983099,1
-544,1512535990407,1
-545,1512535996473,1
-546,1512536003205,1
-547,1512536009500,1
-548,1512536016298,1
-549,1512536023322,1
-550,1512536029590,1
-551,1512536041397,1
-552,1512536048849,1
-553,1512536055591,1
-554,1512536061967,1
-555,1512536068417,1
-556,1512536074778,1
-557,1512536082030,1
-558,1512536088878,1
-559,1512536095480,1
-560,1512536107430,1
-561,1512536114004,1
-562,1512536120910,1
-563,1512536127450,2
-564,1512536134552,4
-565,1512536152452,5
-566,1512536159490,6
-567,1512536189801,8
-568,1512536214119,8
-569,1512536248653,9
-570,1512536266210,8
-571,1512536273365,12
-572,1512536329498,18
-573,1512536377535,19
-574,1512536536609,19
-575,1512536560837,19
-576,1512536573243,20
-577,1512536662489,24
-578,1512536669748,24
-579,1512536816603,31
-580,1512537035121,31
-581,1512537284829,30
-582,1512537317214,30
-583,1512537358857,31
-584,1512537510776,33
-585,1512537535872,32
-586,1512537549211,35
-587,1512537782607,40
-588,1512538223229,39
-589,1512538237452,39
-590,1512538597625,45
-591,1512538616387,44
-592,1512538671449,48
-593,1512538876287,49
-594,1512539130146,48
-595,1512539159717,47
-596,1512539314274,50
-597,1512539357705,50
-598,1512539491061,52
-599,1512539546390,52
-600,1512539680632,52
-601,1512539723789,52
-602,1512539731153,54
-603,1512539779578,70
-604,1512539831462,72
-605,1512539958141,74
-606,1512540120218,73
-607,1512540249747,73
-608,1512540435427,73
-609,1512540528182,72
-610,1512540954317,72
-611,1512541715158,71
-612,1512542086199,70
-613,1512542187357,68
-614,1512542561951,68
-615,1512543210561,67
-616,1512543637180,65
-617,1512543781357,64
-618,1512543825419,63
-619,1512544109254,65
-620,1512544148978,64
-621,1512544414732,66
-622,1512544523952,65
-623,1512544591298,64
-624,1512544801098,64
-625,1512545339876,64
-626,1512545412009,62
-627,1512545929329,63
-628,1512546388559,60
-629,1512546763934,59
-630,1512547051225,57
-631,1512547300485,56
-632,1512547626987,55
-633,1512548220327,53
-634,1512548639262,52
-635,1512548666413,50
-636,1512548769928,53
-637,1512548961609,51
-638,1512549224802,50
-639,1512549423311,49
-640,1512549582141,47
-641,1512549835658,46
-642,1512549868600,44
-643,1512550399590,45
-644,1512550455361,44
-645,1512550577040,43
-646,1512551122603,43
-647,1512551129892,40
-648,1512551339801,52
-649,1512551415302,50
-650,1512551498270,49
-651,1512551819281,48
-652,1512551990991,46
-653,1512552138227,44
-654,1512552366760,42
-655,1512552391240,40
-656,1512552475891,42
-657,1512552696369,41
-658,1512552846620,40
-659,1512552917426,38
-660,1512552972926,37
-661,1512553260743,36
-662,1512553492791,33
-663,1512553735976,32
-664,1512553913798,30
-665,1512553955106,28
-666,1512553979638,28
-667,1512554275827,29
-668,1512554324251,27
-669,1512554508871,26
-670,1512554666138,24
-671,1512554823719,22
-672,1512555002937,23
-673,1512555069784,20
-674,1512555123292,19
-675,1512555158872,17
-676,1512555227536,17
-677,1512555257692,17
-678,1512555274063,17
-679,1512555281395,21
-680,1512555300458,25
-681,1512555334056,26
-682,1512555386333,25
-683,1512555454482,26
-684,1512555639445,24
-685,1512555815284,22
-686,1512555866834,22
-687,1512556140741,23
-688,1512556296508,22
-689,1512556692578,19
-690,1512557130201,21
-691,1512557197221,18
-692,1512557251748,20
-693,1512557305501,19
-694,1512557370608,19
-695,1512557436546,17
-696,1512557504851,18
-697,1512557527956,17
-698,1512557564107,18
-699,1512557612748,18
-700,1512557619766,17
-701,1512557680664,21
-702,1512557729717,22
-703,1512557844439,29
-704,1512558247774,30
-705,1512558260947,29
-706,1512558477900,34
-707,1512558899449,34
-708,1512559033646,31
-709,1512559413510,30
-710,1512559709204,30
-711,1512559896694,29
-712,1512560112080,28
-713,1512560173030,27
-714,1512560204925,27
-715,1512560425039,27
-716,1512560672967,26
-717,1512560679923,24
-718,1512561115371,31
-719,1512561662901,30
-720,1512561794263,29
-721,1512561948868,29
-722,1512562042692,29
-723,1512562208869,29
-724,1512562322577,28
-725,1512562385947,27
-726,1512562448367,27
-727,1512562589988,27
-728,1512562598150,26
-729,1512562651718,32
-730,1512562832048,30
-731,1512563027460,31
-732,1512563071270,30
-733,1512563111550,29
-734,1512563204108,29
-735,1512563319435,28
-736,1512563359448,29
-737,1512563384787,29
-738,1512563416967,30
-739,1512563763455,31
-740,1512563900615,30
-741,1512565185585,28
-742,1512565379792,27
-743,1512565410123,27
-744,1512565436876,27
-745,1512565540048,28
-746,1512565671385,27
-747,1512565775518,27
-748,1512565816619,32
-749,1512565882370,33
-750,1512566006490,33
-751,1512566042077,32
-752,1512566125345,32
-753,1512566222914,31
-754,1512566298643,30
-755,1512566412589,30
-756,1512566531464,32
-757,1512566691529,31
-758,1512566867683,29
-759,1512567086161,28
-760,1512567284192,28
-761,1512639141123,27
-762,1512639167140,26
-763,1512639205457,27
-764,1512639222716,27
-765,1512639398175,29
-766,1512639595440,28
-767,1512639701448,28
-768,1512639749907,27
-769,1512639793593,28
-770,1512639839392,28
-771,1512639860073,27
-772,1512639864996,29
-773,1512639881503,41
-774,1512639977759,46
-775,1512640127745,45
-776,1512640176930,44
-777,1512640197991,44
-778,1512640452491,48
-779,1512640812346,48
-780,1512641182069,49
-781,1512641509243,49
-782,1512641581105,49
-783,1512641599163,49
-784,1512641617255,53
-785,1512642473780,59
-786,1512642515397,57
-787,1512642532067,58
-788,1512642846035,65
-789,1512643164703,63
-790,1512643363048,61
-791,1512643379546,59
-792,1512643477461,66
-793,1512643494225,65
-794,1512643666018,73
-795,1512643960473,71
-796,1512644012256,69
-797,1512644215647,70
-798,1512644373025,69
-799,1512644413338,68
-800,1512644433787,71
-801,1512644678190,79
-802,1512644742855,78
-803,1512644837531,78
-804,1512644944367,78
-805,1512645037630,76
-806,1512645095922,79
-807,1512645147135,79
-808,1512645617887,80
-809,1512645792421,78
-810,1512645829401,76
-811,1512645838128,78
-812,1512645963248,97
-813,1512646003333,96
-814,1512646137056,99
-815,1512646272298,98
-816,1512646418027,97
-817,1512646477143,95
-818,1512646606721,100
-819,1512646710029,98
-820,1512646718849,98
-821,1512646723708,121
-822,1512646739965,177
-823,1512646994144,199
-824,1512647112924,196
-825,1512647269913,195
-826,1512648302951,193
-827,1512648464081,189
-828,1512648975612,188
-829,1512649677788,187
-830,1512649782738,183
-831,1512649877464,182
-832,1512650173941,182
-833,1512651005986,179
-834,1512651072855,175
-835,1512651267408,177
-836,1512651562939,174
-837,1512651807355,171
-838,1512651869610,169
-839,1512652317056,172
-840,1512652458347,167
-841,1512652467117,164
-842,1512652588029,204
-843,1512652639658,202
-844,1512654613444,206
-845,1512654629948,202
-846,1512654860411,226
-847,1512654903708,221
-848,1512655760142,227
-849,1512656602947,222
-850,1512657358576,217
-851,1512657635689,211
-852,1512658153591,207
-853,1512658566669,201
-854,1512658586699,197
-855,1512658860776,214
-856,1512659226399,208
-857,1512659841235,203
-858,1512660381066,197
-859,1512725284693,190
-860,1512725683635,183
-861,1512725764251,178
-862,1512726235899,176
-863,1512726306006,170
-864,1512726370634,170
-865,1512727362440,171
-866,1512727531219,164
-867,1512728148684,159
-868,1512729043485,152
-869,1512729936889,147
-870,1512730081878,140
-871,1512730284491,136
-872,1512730925040,132
-873,1512730944241,132
-874,1512731615233,145
-875,1512731645258,138
-876,1512732253610,143
-877,1512732720629,137
-878,1512733568488,133
-879,1512733587059,125
-880,1512733805736,135
-881,1512734201939,128
-882,1512734519647,122
-883,1512735478451,117
-884,1512735690117,112
-885,1512736783607,110
-886,1512737000092,103
-887,1512737375509,98
-888,1512737763714,95
-889,1512737988739,89
-890,1512738175411,83
-891,1512738403681,77
-892,1512738468520,74
-893,1512738916233,72
-894,1512739028281,69
-895,1512739035251,64
-896,1512739125197,79
-897,1512739226177,76
-898,1512739256883,70
-899,1512739292999,69
-900,1512739841214,68
-901,1512739859933,66
-902,1512740212358,67
-903,1512740312347,61
-904,1512740377991,57
-905,1512740467168,52
-906,1512740491477,47
-907,1512740602517,46
-908,1512740738566,41
-909,1512740745639,35
-910,1512741127218,40
-911,1512741163045,35
-912,1512741466238,41
-913,1512741773610,36
-914,1512741791906,31
-915,1512741869050,29
-916,1512741905286,24
-917,1512741971781,19
-918,1512741990876,15
-919,1512742103852,11
-920,1512742197739,5
-921,1512742263015,11
-922,1512742275489,36
-923,1512742282342,50
-924,1512742490633,64
-925,1512742538545,61
-926,1512742568656,60
-927,1512742628304,60
-928,1512742710206,57
-929,1512742845371,54
-930,1512743138616,49
-931,1512743198457,46
-932,1512743411229,45
-933,1512743435557,40
-934,1512743754203,39
-935,1512743796108,36
-936,1512743884375,35
-937,1512744118018,30
-938,1512744363457,27
-939,1512744376589,24
-940,1512744501136,23
-941,1512744547192,20
-942,1512744589192,38
-943,1512744625586,39
-944,1512744673316,41
-945,1512744796306,38
-946,1512744838956,49
-947,1512745370166,49
-948,1512745481976,52
-949,1512745518329,49
-950,1512745872239,48
-951,1512745995180,45
-952,1512746252020,43
-953,1512746299658,39
-954,1512746329820,37
-955,1512746466410,49
-956,1512746538052,46
-957,1512746736705,45
-958,1512746761047,42
-959,1512746791300,43
-960,1512746850919,43
-961,1512746857702,41
-962,1512746910933,54
-963,1512747312066,54
-964,1512747934845,53
-965,1512748296071,52
-966,1512748360744,49
-967,1512748426195,48
-968,1512748438985,46
-969,1512748655485,51
-970,1512748819762,48
-971,1512748952162,46
-972,1512748977296,44
-973,1512748990127,44
-974,1512749414571,57
-975,1512749469472,53
-976,1512749540412,58
-977,1512749699132,56
-978,1512749735927,53
-979,1512749894001,53
-980,1512750133073,59
-981,1512750215919,56
-982,1512750269158,54
-983,1512750415365,54
-984,1512750987740,52
-985,1512751717102,48
-986,1512751884300,45
-987,1512751913449,43
-988,1512752077776,43
-989,1512752471164,40
-990,1512752507505,37
-991,1512752640035,37
-992,1512752678908,34
-993,1512752775398,34
-994,1512752780968,31
-995,1512752814809,41
-996,1512752873046,52
-997,1512753002794,52
-998,1512753498464,51
-999,1512753627404,50
-1000,1512754058592,49
-1001,1512754123877,47
-1002,1512754203338,49
-1003,1512754359381,48
-1004,1512754394068,45
-1005,1512754409676,46
-1006,1512754534591,51
-1007,1512754601329,51
-1008,1512754649417,50
-1009,1512754673929,49
-1010,1512754759688,57
-1011,1512754769844,55
-1012,1512755016190,66
-1013,1512755064705,64
-1014,1512755190021,63
-1015,1512755398297,63
-1016,1512755487051,61
-1017,1512755549550,59
-1018,1512755635049,58
-1019,1512755728237,57
-1020,1512756015027,56
-1021,1512756035393,53
-1022,1512756216470,56
-1023,1512756327870,57
-1024,1512756664661,64
-1025,1512756749371,61
-1026,1512756826206,62
-1027,1512756904284,63
-1028,1512756999522,62
-1029,1512757029077,62
-1030,1512757081727,64
-1031,1512757230481,64
-1032,1512757263424,62
-1033,1512757293779,64
-1034,1512757384680,67
-1035,1512757509086,66
-1036,1512757645447,65
-1037,1512757729747,63
-1038,1512757979460,62
-1039,1512757999525,60
-1040,1512758263456,65
-1041,1512758461350,63
-1042,1512758519205,61
-1043,1512758663635,60
-1044,1512758723539,59
-1045,1512758801326,60
-1046,1512758917415,58
-1047,1512758964541,57
-1048,1512759219273,57
-1049,1512759337057,55
-1050,1512759351896,54
-1051,1512759515203,58
-1052,1512759528535,57
-1053,1512759747383,65
-1054,1512759813181,61
-1055,1512759936059,61
-1056,1512760060207,59
-1057,1512760202641,58
-1058,1512760400582,56
-1059,1512760417090,55
-1060,1512760510382,60
-1061,1512760653210,60
-1062,1512760683758,65
-1063,1512760708344,68
-1064,1512760886813,71
-1065,1512761141615,69
-1066,1512761189711,66
-1067,1512761200075,66
-1068,1512761278510,79
-1069,1512761391285,82
-1070,1512761568225,80
-1071,1512761793696,77
-1072,1512761883114,76
-1073,1512761946014,76
-1074,1512762147355,79
-1075,1512762172024,76
-1076,1512762349022,81
-1077,1512762367684,80
-1078,1512762515954,86
-1079,1512762644069,86
-1080,1512762691167,85
-1081,1512762959954,85
-1082,1512763154591,83
-1083,1512763207819,81
-1084,1512763260405,82
-1085,1512763332360,81
-1086,1512763399798,79
-1087,1512763456758,79
-1088,1512763966539,80
-1089,1512764012917,76
-1090,1512764049943,77
-1091,1512764063203,79
-1092,1512764315819,89
-1093,1512764402885,87
-1094,1512764416857,85
-1095,1512764640420,103
-1096,1512764838811,100
-1097,1512764860436,99
-1098,1512764864703,105
-1099,1512765025158,161
-1100,1512765106744,158
-1101,1512765509616,157
-1102,1512766069493,153
-1103,1512766593736,150
-1104,1512766668769,146
-1105,1512766672896,146
-1106,1512766718702,229
-1107,1512767031286,235
-1108,1512767051794,231
-1109,1512767224258,252
-1110,1512767423046,252
-1111,1512767682014,248
-1112,1512767692742,250
-1113,1512768468580,299
-1114,1512769525696,294
-1115,1512770068202,287
-1116,1512771462276,281
-1117,1512772299557,275
-1118,1512772583109,269
-1119,1512775140605,264
-1120,1512777709527,257
-1121,1512778312557,250
-1122,1512779604479,246
-1123,1512780362352,239
-1124,1512781996106,234
-1125,1512782992140,226
-1126,1512783916134,220
-1127,1512784504823,214
-1128,1512785106927,208
-1129,1512785767619,202
-1130,1512786468803,197
-1131,1512786890051,192
-1132,1512787716744,186
-1133,1512789136789,182
-1134,1512789917484,177
-1135,1512790672413,171
-1136,1512791406292,165
-1137,1512792527677,159
-1138,1512793733998,152
-1139,1512794735158,146
-1140,1512795126528,143
-1141,1512795549325,136
-1142,1512795932700,130
-1143,1512796073774,126
-1144,1512796202009,120
-1145,1512796322918,117
-1146,1512797207441,113
-1147,1512797957799,107
-1148,1512798380977,102
-1149,1512798827974,96
-1150,1512799382954,89
-1151,1512799592692,86
-1152,1512799644047,81
-1153,1512799670976,84
-1154,1512799763778,84
-1155,1512799972150,81
-1156,1512800162622,75
-1157,1512801002937,70
-1158,1512801622141,63
-1159,1512801770918,57
-1160,1512801916035,55
-1161,1512802026524,50
-1162,1512802292776,45
-1163,1512802462458,40
-1164,1512802536984,37
-1165,1512802611518,32
-1166,1512802688297,27
-1167,1512802733283,23
-1168,1512802776376,25
-1169,1512802850064,22
-1170,1512802958904,17
-1171,1512803046980,11
-1172,1512803109022,5
-1173,1512803120955,1
-1174,1512803134680,1
-1175,1512803149522,1
-1176,1512803164587,1
-1177,1512803179600,1
-1178,1512803194524,1
-1179,1512803210999,1
-1180,1512803224090,1
-1181,1512803229793,1
-1182,1512803242750,1
-1183,1512803254642,1
-1184,1512803269570,1
-1185,1512803284699,1
-1186,1512803299510,1
-1187,1512803314713,1
-1188,1512803329499,1
-1189,1512803345862,1
-1190,1512803359730,1
-1191,1512803374535,1
-1192,1512803389744,1
-1193,1512803404819,1
-1194,1512803420072,1
-1195,1512803434535,1
-1196,1512803449679,1
-1197,1512803464793,1
-1198,1512803480936,1
-1199,1512803494525,1
-1200,1512803509576,1
-1201,1512803524715,1
-1202,1512803539819,1
-1203,1512803554847,1
-1204,1512803569758,1
-1205,1512803584711,1
-1206,1512803599659,1
-1207,1512803614752,1
-1208,1512803631213,1
-1209,1512803644621,1
-1210,1512803656050,1
-1211,1512803664355,1
-1212,1512803677917,1
-1213,1512803691826,3
-1214,1512803707719,3
-1215,1512803721116,3
-1216,1512803737770,3
-1217,1512803764829,3
-1218,1512803798583,3
-1219,1512803867075,3
-1220,1512803889685,3
-1221,1512803911174,2
-1222,1512803917451,1
-1223,1512803930986,2
-1224,1512803949832,2
-1225,1512803963312,1
-1226,1512803976827,1
-1227,1512803990957,1
-1228,1512804003514,1
-1229,1512804020948,1
-1230,1512804033548,1
-1231,1512804045310,1
-1232,1512804054662,1
-1233,1512804068871,1
-1234,1512804080292,1
-1235,1512804096566,1
-1236,1512804108645,1
-1237,1512804114937,1
-1238,1512804127412,1
-1239,1512804139281,1
-1240,1512804145006,1
-1241,1512804158514,1
-1242,1512804170092,1
-1243,1512804184963,1
-1244,1512804202694,1
-1245,1512804214811,1
-1246,1512804229609,1
-1247,1512804244660,1
-1248,1512804259689,1
-1249,1512804278364,1
-1250,1512804291761,1
-1251,1512804307251,1
-1252,1512804320506,1
-1253,1512804337529,1
-1254,1512804349772,1
-1255,1512804364790,1
-1256,1512804379602,1
-1257,1512804394844,1
-1258,1512804409685,2
-1259,1512804428746,1
-1260,1512804442555,2
-1261,1512804454885,2
-1262,1512804470417,2
-1263,1512804486957,3
-1264,1512804499611,3
-1265,1512804519876,3
-1266,1512804543690,4
-1267,1512804559863,4
-1268,1512804593392,5
-1269,1512804620023,6
-1270,1512804652533,7
-1271,1512804666168,7
-1272,1512804714434,8
-1273,1512804736620,8
-1274,1512804769314,9
-1275,1512804832586,9
-1276,1512804886693,9
-1277,1512804894805,10
-1278,1512804921608,12
-1279,1512804953609,12
-1280,1512804983377,13
-1281,1512805012308,14
-1282,1512805044501,15
-1283,1512805086946,16
-1284,1512805116652,16
-1285,1512805156590,17
-1286,1512805238580,17
-1287,1512805412893,17
-1288,1512805576558,18
-1289,1512805612322,17
-1290,1512805627828,17
-1291,1512805689049,20
-1292,1512805716086,21
-1293,1512805802873,22
-1294,1512805830909,22
-1295,1512805880089,23
-1296,1512805924988,24
-1297,1512805956547,24
-1298,1512805971699,26
-1299,1512806091570,29
-1300,1512806109423,29
-1301,1512806167237,32
-1302,1512806222164,33
-1303,1512806271626,33
-1304,1512806439749,34
-1305,1512806597255,34
-1306,1512806826361,33
-1307,1512807033593,33
-1308,1512807138648,33
-1309,1512807188967,33
-1310,1512807859108,33
-1311,1512808225229,32
-1312,1512808327620,32
-1313,1512808547765,32
-1314,1512808626755,31
-1315,1512808715558,31
-1316,1512808847007,31
-1317,1512809035043,31
-1318,1512809182805,31
-1319,1512809785346,31
-1320,1512810113631,30
-1321,1512810227512,29
-1322,1512810317403,29
-1323,1512810531330,29
-1324,1512810729863,29
-1325,1512810857588,28
-1326,1512810955245,28
-1327,1512811020475,28
-1328,1512811158464,27
-1329,1512811509161,28
-1330,1512811686414,26
-1331,1512811762916,26
-1332,1512811866413,26
-1333,1512812013472,26
-1334,1512812151717,25
-1335,1512812299308,24
-1336,1512812420616,24
-1337,1512812583608,24
-1338,1512812677379,23
-1339,1512812751827,23
-1340,1512812829153,22
-1341,1512812949301,22
-1342,1512813095154,22
-1343,1512813204358,21
-1344,1512813288826,21
-1345,1512813348567,21
-1346,1512813380450,20
-1347,1512813415093,20
-1348,1512813468996,21
-1349,1512813573566,21
-1350,1512813636278,20
-1351,1512813677147,20
-1352,1512813696937,20
-1353,1512813816477,21
-1354,1512813966762,20
-1355,1512814053532,18
-1356,1512814128506,19
-1357,1512814188577,18
-1358,1512814220782,18
-1359,1512814282217,18
-1360,1512814345045,18
-1361,1512814382598,18
-1362,1512814476173,17
-1363,1512814521106,17
-1364,1512814642877,17
-1365,1512814669996,16
-1366,1512814698889,16
-1367,1512814733724,17
-1368,1512814859791,16
-1369,1512814921611,16
-1370,1512815018431,16
-1371,1512815134290,15
-1372,1512815166669,14
-1373,1512815208278,14
-1374,1512815255207,14
-1375,1512815298799,14
-1376,1512815334968,13
-1377,1512815372310,14
-1378,1512815435122,14
-1379,1512815482855,14
-1380,1512815511691,15
-1381,1512815673458,14
-1382,1512815795703,14
-1383,1512815889883,14
-1384,1512815948924,14
-1385,1512816007988,14
-1386,1512816067043,14
-1387,1512816125694,13
-1388,1512816364379,13
-1389,1512816474263,12
-1390,1512816496400,11
-1391,1512816542918,12
-1392,1512816563677,12
-1393,1512816591195,13
-1394,1512816624883,13
-1395,1512816721907,15
-1396,1512816785090,14
-1397,1512816856651,14
-1398,1512816918220,15
-1399,1512816950522,16
-1400,1512817008251,16
-1401,1512817024953,18
-1402,1512817073535,20
-1403,1512817103310,21
-1404,1512817187425,22
-1405,1512817280050,21
-1406,1512817372183,22
-1407,1512817488032,22
-1408,1512817539219,21
-1409,1512817641396,21
-1410,1512817691316,21
-1411,1512817747103,21
-1412,1512817839492,21
-1413,1512818039801,21
-1414,1512818139671,21
-1415,1512818199894,20
-1416,1512818272999,21
-1417,1512818369814,20
-1418,1512818400572,20
-1419,1512818446876,21
-1420,1512818507482,21
-1421,1512818583021,21
-1422,1512818613910,20
-1423,1512818658000,21
-1424,1512818792936,22
-1425,1512818855037,21
-1426,1512818901567,21
-1427,1512818930179,21
-1428,1512819032476,23
-1429,1512819198041,22
-1430,1512819288248,22
-1431,1512819321636,21
-1432,1512819437490,22
-1433,1512819488029,21
-1434,1512819620007,22
-1435,1512819691404,21
-1436,1512819740732,21
-1437,1512819876862,20
-1438,1512819994941,19
-1439,1512820159433,19
-1440,1512820222761,19
-1441,1512820269495,19
-1442,1512820357629,19
-1443,1512820385127,19
-1444,1512820401806,19
-1445,1512820492165,20
-1446,1512820550304,19
-1447,1512820640299,21
-1448,1512820747774,21
-1449,1512820778298,20
-1450,1512820794842,21
-1451,1512820822408,23
-1452,1512820852534,25
-1453,1512820955518,27
-1454,1512821060123,27
-1455,1512821094957,26
-1456,1512821179794,27
-1457,1512821252484,26
-1458,1512821271308,27
-1459,1512821359365,29
-1460,1512821408889,29
-1461,1512821493182,29
-1462,1512821540210,30
-1463,1512821686973,30
-1464,1512821866164,29
-1465,1512821954846,29
-1466,1512822008081,29
-1467,1512822063474,29
-1468,1512822369742,30
-1469,1512822545265,29
-1470,1512822577211,29
-1471,1512822754572,29
-1472,1512822841483,28
-1473,1512822866544,28
-1474,1512822920485,30
-1475,1512822959317,30
-1476,1512823059537,32
-1477,1512823191502,31
-1478,1512823368399,31
-1479,1512823463687,30
-1480,1512823551785,30
-1481,1512823630213,30
-1482,1512823660090,30
-1483,1512823761632,30
-1484,1512823870203,30
-1485,1512823925326,30
-1486,1512823955184,30
-1487,1512824133323,31
-1488,1512824183320,30
-1489,1512824209078,31
-1490,1512824227530,32
-1491,1512824271846,35
-1492,1512824496849,36
-1493,1512824692259,35
-1494,1512824708111,35
-1495,1512824721689,39
-1496,1512824783557,44
-1497,1512824840212,44
-1498,1512824932556,45
-1499,1512825122492,44
-1500,1512825241626,44
-1501,1512825414229,44
-1502,1512825493584,43
-1503,1512825653223,43
-1504,1512825738252,43
-1505,1512825798467,43
-1506,1512825864354,43
-1507,1512825952326,43
-1508,1512826086928,43
-1509,1512826210350,42
-1510,1512826296382,41
-1511,1512826372427,41
-1512,1512826431908,41
-1513,1512826552718,41
-1514,1512826727025,41
-1515,1512826881477,39
-1516,1512826972465,39
-1517,1512827000547,38
-1518,1512827180738,40
-1519,1512827282142,39
-1520,1512827326145,40
-1521,1512827402567,39
-1522,1512827464779,39
-1523,1512827523537,40
-1524,1512827555835,40
-1525,1512827751391,41
-1526,1512827858322,41
-1527,1512827978085,40
-1528,1512828052127,39
-1529,1512828081884,39
-1530,1512828142599,41
-1531,1512828280250,40
-1532,1512828380136,40
-1533,1512828437028,40
-1534,1512828502125,40
-1535,1512828565301,39
-1536,1512828692602,40
-1537,1512828924804,38
-1538,1512829159449,36
-1539,1512829195157,35
-1540,1512829372325,36
-1541,1512829771890,35
-1542,1512829896563,32
-1543,1512829927197,32
-1544,1512830252431,32
-1545,1512830498086,32
-1546,1512830558935,31
-1547,1512830601595,31
-1548,1512830794735,32
-1549,1512830899624,29
-1550,1512830976821,29
-1551,1512831231534,30
-1552,1512831337765,29
-1553,1512831396835,29
-1554,1512831487620,28
-1555,1512831520419,27
-1556,1512831577302,29
-1557,1512831767437,28
-1558,1512831863808,27
-1559,1512831893143,28
-1560,1512831949254,28
-1561,1512832009070,28
-1562,1512832131956,28
-1563,1512832217296,27
-1564,1512832252756,26
-1565,1512832400886,26
-1566,1512832730554,26
-1567,1512832852540,24
-1568,1512832898589,23
-1569,1512832940587,23
-1570,1512832960320,22
-1571,1512833072711,23
-1572,1512833199729,22
-1573,1512833267586,22
-1574,1512833301778,21
-1575,1512833378574,22
-1576,1512833409504,21
-1577,1512833437355,22
-1578,1512833479833,22
-1579,1512833539323,22
-1580,1512833586704,21
-1581,1512833777553,21
-1582,1512833873832,19
-1583,1512833903168,19
-1584,1512833932258,19
-1585,1512833958109,19
-1586,1512833976738,20
-1587,1512834000921,21
-1588,1512834040069,22
-1589,1512834138841,22
-1590,1512834201756,22
-1591,1512834322045,23
-1592,1512834454502,23
-1593,1512834710623,21
-1594,1512834978021,19
-1595,1512835118712,21
-1596,1512835201207,23
-1597,1512835523716,22
-1598,1512835689524,23
-1599,1512835732363,21
-1600,1512835822070,22
-1601,1512835910589,21
-1602,1512835945377,20
-1603,1512836087216,20
-1604,1512836149702,19
-1605,1512836197726,20
-1606,1512836493310,20
-1607,1512836634804,19
-1608,1512836687650,18
-1609,1512836739395,18
-1610,1512836778693,17
-1611,1512836917006,18
-1612,1512837022167,17
-1613,1512837062445,17
-1614,1512837107519,17
-1615,1512837173926,16
-1616,1512837201901,15
-1617,1512837271756,15
-1618,1512837429822,16
-1619,1512837550429,15
-1620,1512837617708,15
-1621,1512837681829,15
-1622,1512837766697,14
-1623,1512837802620,14
-1624,1512837900160,15
-1625,1512837948991,15
-1626,1512837964137,15
-1627,1512838006759,16
-1628,1512838024094,16
-1629,1512838043887,18
-1630,1512838144359,20
-1631,1512838194756,20
-1632,1512838206690,19
-1633,1512838239800,23
-1634,1512838309324,23
-1635,1512838370362,23
-1636,1512838444363,24
-1637,1512838683467,23
-1638,1512838881693,22
-1639,1512838965752,22
-1640,1512838988750,22
-1641,1512839029458,22
-1642,1512839131809,24
-1643,1512839179268,23
-1644,1512839215105,23
-1645,1512839267427,23
-1646,1512839303655,23
-1647,1512839330145,24
-1648,1512839365112,26
-1649,1512839404289,27
-1650,1512839423618,27
-1651,1512839454546,29
-1652,1512839538867,30
-1653,1512839664916,30
-1654,1512839828169,29
-1655,1512839900278,29
-1656,1512839948580,29
-1657,1512839994508,29
-1658,1512840095040,30
-1659,1512840154231,29
-1660,1512840189010,30
-1661,1512840265276,31
-1662,1512840354190,31
-1663,1512840399400,31
-1664,1512840484426,31
-1665,1512840576782,31
-1666,1512840616903,31
-1667,1512840662442,31
-1668,1512840691288,31
-1669,1512840742512,33
-1670,1512840887527,34
-1671,1512840948955,33
-1672,1512841051304,34
-1673,1512841208594,34
-1674,1512841415451,33
-1675,1512841534936,32
-1676,1512841773076,32
-1677,1512841908827,31
-1678,1512841942174,31
-1679,1512841984519,33
-1680,1512842014662,33
-1681,1512842063398,35
-1682,1512842078596,35
-1683,1512842170442,39
-1684,1512842254648,39
-1685,1512842300400,39
-1686,1512842554845,41
-1687,1512842691905,40
-1688,1512842732817,41
-1689,1512842871348,42
-1690,1512842959685,42
-1691,1512843122981,42
-1692,1512843347939,40
-1693,1512843438654,39
-1694,1512843485529,38
-1695,1512843614838,39
-1696,1512843700135,38
-1697,1512843760271,38
-1698,1512843904857,38
-1699,1512844073384,37
-1700,1512844102551,36
-1701,1512844299693,38
-1702,1512844420934,37
-1703,1512844596482,37
-1704,1512844733728,36
-1705,1512844833012,35
-1706,1512844865083,34
-1707,1512844936315,35
-1708,1512845033516,35
-1709,1512845091667,34
-1710,1512845167574,34
-1711,1512845267645,34
-1712,1512845350184,33
-1713,1512845442585,32
-1714,1512845482072,32
-1715,1512845544449,32
-1716,1512845570684,32
-1717,1512845585034,34
-1718,1512845990085,38
-1719,1512846214473,36
-1720,1512846409511,35
-1721,1512846558366,33
-1722,1512846604503,31
-1723,1512846698503,32
-1724,1512846789565,32
-1725,1512846844144,31
-1726,1512846932412,31
-1727,1512846983185,30
-1728,1512847083257,31
-1729,1512847174485,31
-1730,1512847266931,30
-1731,1512847478748,30
-1732,1512847671960,28
-1733,1512847942450,29
-1734,1512848138660,28
-1735,1512848222330,27
-1736,1512848268408,26
-1737,1512848403497,26
-1738,1512848496021,24
-1739,1512848539352,24
-1740,1512848581764,24
-1741,1512848630520,24
-1742,1512848735885,24
-1743,1512848783390,23
-1744,1512848797185,23
-1745,1512848837646,26
-1746,1512848871706,26
-1747,1512848900315,26
-1748,1512848990892,28
-1749,1512849038011,28
-1750,1512849110191,28
-1751,1512849214789,29
-1752,1512849366582,28
-1753,1512849467809,28
-1754,1512849723337,27
-1755,1512849854453,25
-1756,1512849875859,25
-1757,1512849889606,27
-1758,1512849895203,30
-1759,1512850117620,42
-1760,1512850191982,41
-1761,1512850373213,41
-1762,1512850778191,40
-1763,1512850943185,39
-1764,1512850970811,37
-1765,1512851196516,39
-1766,1512851404719,38
-1767,1512851646083,37
-1768,1512851838458,37
-1769,1512851900779,36
-1770,1512852019908,37
-1771,1512852271391,35
-1772,1512852393616,35
-1773,1512852451970,34
-1774,1512852535383,34
-1775,1512852668809,32
-1776,1512852888086,32
-1777,1512852977483,30
-1778,1512853022815,29
-1779,1512853157138,31
-1780,1512853249006,29
-1781,1512853270278,29
-1782,1512853400574,31
-1783,1512853536477,33
-1784,1512853624084,33
-1785,1512853685961,32
-1786,1512853732762,33
-1787,1512853793819,32
-1788,1512853834579,32
-1789,1512854138117,34
-1790,1512854309937,32
-1791,1512854345648,32
-1792,1512854586937,33
-1793,1512854723357,30
-1794,1512854766586,31
-1795,1512854840632,30
-1796,1512854885728,30
-1797,1512855242403,30
-1798,1512855472237,30
-1799,1512855564914,28
-1800,1512855632479,27
-1801,1512855652155,28
-1802,1512855680377,30
-1803,1512855709125,30
-1804,1512855759203,31
-1805,1512855825939,31
-1806,1512855887276,31
-1807,1512855991912,31
-1808,1512856037089,31
-1809,1512856161931,31
-1810,1512856190985,31
-1811,1512856345391,31
-1812,1512856638711,31
-1813,1512856744013,30
-1814,1512856868566,29
-1815,1512857032424,29
-1816,1512857107751,28
-1817,1512857198199,29
-1818,1512857299651,31
-1819,1512857523011,28
-1820,1512857629531,28
-1821,1512857690137,27
-1822,1512857867886,26
-1823,1512857932933,26
-1824,1512858020167,25
-1825,1512858075269,25
-1826,1512858096822,25
-1827,1512858173724,26
-1828,1512858234582,26
-1829,1512858259577,26
-1830,1512858275337,27
-1831,1512858310124,30
-1832,1512858352375,30
-1833,1512858451747,30
-1834,1512858664834,29
-1835,1512858812524,28
-1836,1512858848915,27
-1837,1512859023857,27
-1838,1512859192288,26
-1839,1512859284484,24
-1840,1512859309988,24
-1841,1512859402206,25
-1842,1512859502529,24
-1843,1512859520610,23
-1844,1512859645171,25
-1845,1512859731331,25
-1846,1512860162302,25
-1847,1512860360031,24
-1848,1512860402896,24
-1849,1512860446678,24
-1850,1512860466891,24
-1851,1512860590118,25
-1852,1512860678860,24
-1853,1512860734709,23
-1854,1512860795218,23
-1855,1512860897128,22
-1856,1512860935421,21
-1857,1512860948636,21
-1858,1512861142851,26
-1859,1512861318184,31
-1860,1512861384596,30
-1861,1512861436042,30
-1862,1512861532161,30
-1863,1512861620506,29
-1864,1512861682339,29
-1865,1512861997061,30
-1866,1512862339834,28
-1867,1512862374399,26
-1868,1512862473495,27
-1869,1512862489786,27
-1870,1512862551933,30
-1871,1512862585000,30
-1872,1512862608256,30
-1873,1512862628541,32
-1874,1512862660394,35
-1875,1512862717486,36
-1876,1512862875165,36
-1877,1512862970853,35
-1878,1512863047916,34
-1879,1512863092953,35
-1880,1512863302810,35
-1881,1512863408331,33
-1882,1512863420002,34
-1883,1512863494354,40
-1884,1512863510961,39
-1885,1512863544265,43
-1886,1512863949741,45
-1887,1512864156805,44
-1888,1512864278431,43
-1889,1512864408054,43
-1890,1512864534807,42
-1891,1512864649833,41
-1892,1512864767750,42
-1893,1512864849267,40
-1894,1512864908145,40
-1895,1512864985871,40
-1896,1512865192413,40
-1897,1512865390685,40
-1898,1512865472148,38
-1899,1512865507708,38
-1900,1512865788853,39
-1901,1512866061824,37
-1902,1512866343416,37
-1903,1512866465749,37
-1904,1512866574702,37
-1905,1512866719693,36
-1906,1512866766200,36
-1907,1512866837881,36
-1908,1512866992048,36
-1909,1512867085619,36
-1910,1512867213579,35
-1911,1512867278035,34
-1912,1512867318857,35
-1913,1512867424149,35
-1914,1512867475148,34
-1915,1512867529841,34
-1916,1512867574726,34
-1917,1512867737959,34
-1918,1512867874790,33
-1919,1512868012537,31
-1920,1512868171678,31
-1921,1512868266723,30
-1922,1512868293360,29
-1923,1512868457853,30
-1924,1512868597458,29
-1925,1512868642811,27
-1926,1512868699799,28
-1927,1512868777175,28
-1928,1512868818367,27
-1929,1512868840745,28
-1930,1512868908885,30
-1931,1512868959496,30
-1932,1512869030647,32
-1933,1512869044799,32
-1934,1512869124526,36
-1935,1512869281660,36
-1936,1512869390045,34
-1937,1512869469804,34
-1938,1512869680756,32
-1939,1512869913946,31
-1940,1512870064762,30
-1941,1512870094725,30
-1942,1512870171835,31
-1943,1512870692894,30
-1944,1512870925303,29
-1945,1512870990954,28
-1946,1512871082932,27
-1947,1512871162824,26
-1948,1512871458000,25
-1949,1512871638980,25
-1950,1512871698916,24
-1951,1512871714876,24
-1952,1512871733794,26
-1953,1512871787201,28
-1954,1512871852677,28
-1955,1512872057069,27
-1956,1512872227428,26
-1957,1512872284759,25
-1958,1512872364601,26
-1959,1512872432879,25
-1960,1512872450667,24
-1961,1512872529999,26
-1962,1512872553983,26
-1963,1512872614675,27
-1964,1512872704359,26
-1965,1512872737226,25
-1966,1512872794358,25
-1967,1512872824915,24
-1968,1512873005136,25
-1969,1512873125269,23
-1970,1512873172160,24
-1971,1512873324148,24
-1972,1512873481749,23
-1973,1512873533862,23
-1974,1512873562397,24
-1975,1512873579487,26
-1976,1512873592054,28
-1977,1512873634786,32
-1978,1512873680820,32
-1979,1512873772183,32
-1980,1512874045351,32
-1981,1512874188996,31
-1982,1512874253786,30
-1983,1512874426303,33
-1984,1512874504998,32
-1985,1512874566037,34
-1986,1512874669040,35
-1987,1512874731974,34
-1988,1512874765700,34
-1989,1512874897438,35
-1990,1512875035217,35
-1991,1512875090943,34
-1992,1512875139415,34
-1993,1512875155454,34
-1994,1512875167666,38
-1995,1512875275886,44
-1996,1512875317914,44
-1997,1512875422378,45
-1998,1512875506317,44
-1999,1512875617257,44
-2000,1512875769014,44
-2001,1512876197938,43
-2002,1512876383263,41
-2003,1512876443552,41
-2004,1512876540912,40
-2005,1512876625024,40
-2006,1512876679858,39
-2007,1512876829480,40
-2008,1512876907673,39
-2009,1512877038073,38
-2010,1512877103932,38
-2011,1512877261767,37
-2012,1512877366816,36
-2013,1512877404906,37
-2014,1512877434905,37
-2015,1512877502265,39
-2016,1512877518541,39
-2017,1512877569073,44
-2018,1512877750537,44
-2019,1512878074941,43
-2020,1512878416819,41
-2021,1512878679363,39
-2022,1512878903095,38
-2023,1512878945376,38
-2024,1512878994344,39
-2025,1512879093034,38
-2026,1512879136815,38
-2027,1512879159796,39
-2028,1512879184491,41
-2029,1512879347220,43
-2030,1512879725256,43
-2031,1512880128158,42
-2032,1512880238384,41
-2033,1512880368094,40
-2034,1512880609971,41
-2035,1512880869581,41
-2036,1512880952305,39
-2037,1512881050774,38
-2038,1512881138021,38
-2039,1512881166017,37
-2040,1512881212734,38
-2041,1512881347306,39
-2042,1512881482287,38
-2043,1512881559605,37
-2044,1512881716513,37
-2045,1512881899921,34
-2046,1512881993202,34
-2047,1512882181915,33
-2048,1512882365211,32
-2049,1512882664723,30
-2050,1512882768580,29
-2051,1512882802213,28
-2052,1512882865215,29
-2053,1512882951021,30
-2054,1512882997895,29
-2055,1512883070786,29
-2056,1512883130053,29
-2057,1512883173489,27
-2058,1512883351918,27
-2059,1512883432330,26
-2060,1512883474968,26
-2061,1512883608781,27
-2062,1512883654958,26
-2063,1512883716248,26
-2064,1512883794295,25
-2065,1512883913700,25
-2066,1512884028054,24
-2067,1512884108312,23
-2068,1512884224494,23
-2069,1512884391124,21
-2070,1512884543805,20
-2071,1512884749545,19
-2072,1512884883632,17
-2073,1512884914881,16
-2074,1512884987299,16
-2075,1512885039781,15
-2076,1512885068347,15
-2077,1512885096794,18
-2078,1512885155022,18
-2079,1512885218340,18
-2080,1512885228747,17
-2081,1512885247164,19
-2082,1512885275051,21
-2083,1512885309961,21
-2084,1512885354941,21
-2085,1512885380994,21
-2086,1512885408533,22
-2087,1512885440072,22
-2088,1512885456321,23
-2089,1512885486400,25
-2090,1512885542366,25
-2091,1512885602328,25
-2092,1512885622439,25
-2093,1512885721827,26
-2094,1512885772120,27
-2095,1512885815747,30
-2096,1512885877358,30
-2097,1512885909852,31
-2098,1512885937788,33
-2099,1512886172290,34
-2100,1512886307136,33
-2101,1512886414517,33
-2102,1512886463008,30
-2103,1512887161886,30
-2104,1512887540007,30
-2105,1512887589029,29
-2106,1512887630991,29
-2107,1512887918569,30
-2108,1512888082883,28
-2109,1512888156031,27
-2110,1512888203019,27
-2111,1512888317355,27
-2112,1512888476049,27
-2113,1512888565242,25
-2114,1512888640783,26
-2115,1512888782418,26
-2116,1512888879395,25
-2117,1512888965497,27
-2118,1512889001437,27
-2119,1512889075511,26
-2120,1512889219845,27
-2121,1512889378123,25
-2122,1512889480319,25
-2123,1512889534704,23
-2124,1512889687307,25
-2125,1512889774642,23
-2126,1512889824506,23
-2127,1512889925248,24
-2128,1512889970396,25
-2129,1512890014678,26
-2130,1512890067702,26
-2131,1512890104635,26
-2132,1512890123693,26
-2133,1512890163876,29
-2134,1512890186426,30
-2135,1512890243400,31
-2136,1512890284299,31
-2137,1512890342731,31
-2138,1512890405407,32
-2139,1512890471727,32
-2140,1512890652595,32
-2141,1512890826863,33
-2142,1512890936571,32
-2143,1512891049654,31
-2144,1512891138209,30
-2145,1512891207545,30
-2146,1512891249293,30
-2147,1512891319234,30
-2148,1512891355691,30
-2149,1512891370640,30
-2150,1512891484212,33
-2151,1512891744260,33
-2152,1512891863510,32
-2153,1512892055468,31
-2154,1512892163305,30
-2155,1512892285588,31
-2156,1512892466711,30
-2157,1512892641976,28
-2158,1512892854442,27
-2159,1512893062858,27
-2160,1512893153724,26
-2161,1512893184822,26
-2162,1512893239299,27
-2163,1512893396099,26
-2164,1512893472640,26
-2165,1512893572619,25
-2166,1512893794223,24
-2167,1512894005438,23
-2168,1512894123477,22
-2169,1512894178259,22
-2170,1512894274632,20
-2171,1512894334620,20
-2172,1512894381909,18
-2173,1512894469331,18
-2174,1512894591915,17
-2175,1512894653686,16
-2176,1512894695045,16
-2177,1512894981853,16
-2178,1512895160415,15
-2179,1512895252360,14
-2180,1512895299290,13
-2181,1512895359268,14
-2182,1512895404489,14
-2183,1512895450358,14
-2184,1512895479625,14
-2185,1512895505454,14
-2186,1512895585728,15
-2187,1512895629311,15
-2188,1512895643397,15
-2189,1512895704955,18
-2190,1512895744563,18
-2191,1512895894598,18
-2192,1512896019248,17
-2193,1512896106867,18
-2194,1512896142836,18
-2195,1512896225845,18
-2196,1512896245359,18
-2197,1512896276756,20
-2198,1512896317882,20
-2199,1512896424451,22
-2200,1512896510378,21
-2201,1512896574383,21
-2202,1512896723164,20
-2203,1512896809587,20
-2204,1512896900316,19
-2205,1512897037835,18
-2206,1512897235300,18
-2207,1512897319619,17
-2208,1512897343198,17
-2209,1512897380030,18
-2210,1512897399676,17
-2211,1512897455259,20
-2212,1512897515366,19
-2213,1512897546195,18
-2214,1512897563417,19
-2215,1512897667758,21
-2216,1512897717489,20
-2217,1512897740301,20
-2218,1512897799565,20
-2219,1512897833306,21
-2220,1512897905259,22
-2221,1512898163085,21
-2222,1512898310210,20
-2223,1512898357573,19
-2224,1512898417092,19
-2225,1512898523440,18
-2226,1512898601925,18
-2227,1512898673538,18
-2228,1512898781554,17
-2229,1512898850253,16
-2230,1512898885790,16
-2231,1512898909931,17
-2232,1512898928371,18
-2233,1512899022453,20
-2234,1512899112623,20
-2235,1512899254071,21
-2236,1512899391811,21
-2237,1512899479509,21
-2238,1512899585252,21
-2239,1512899649204,21
-2240,1512899689104,20
-2241,1512899720648,21
-2242,1512899825307,21
-2243,1512899914141,20
-2244,1512899988449,20
-2245,1512900027206,20
-2246,1512900080635,21
-2247,1512900245302,20
-2248,1512900326594,21
-2249,1512900425264,21
-2250,1512900484416,23
-2251,1512900624277,23
-2252,1512900769493,22
-2253,1512901039937,21
-2254,1512901235744,21
-2255,1512901295936,20
-2256,1512901356444,20
-2257,1512901429809,20
-2258,1512901580579,18
-2259,1512901732277,19
-2260,1512901796235,18
-2261,1512901835884,18
-2262,1512901910981,19
-2263,1512901944817,19
-2264,1512901985943,20
-2265,1512902092285,19
-2266,1512902230222,19
-2267,1512902270660,18
-2268,1512902315063,19
-2269,1512902350010,18
-2270,1512902421943,19
-2271,1512902468890,19
-2272,1512902510143,19
-2273,1512902558586,19
-2274,1512902600452,19
-2275,1512902663191,19
-2276,1512902695443,19
-2277,1512902798213,20
-2278,1512902840804,19
-2279,1512902859836,18
-2280,1512902916374,20
-2281,1512902973109,20
-2282,1512903066299,20
-2283,1512903147110,19
-2284,1512903189690,19
-2285,1512903263769,19
-2286,1512903350828,19
-2287,1512903384003,18
-2288,1512903444112,19
-2289,1512903507064,20
-2290,1512903639522,20
-2291,1512903718409,20
-2292,1512903758839,19
-2293,1512903874553,19
-2294,1512903925185,18
-2295,1512903968263,18
-2296,1512904084635,19
-2297,1512904188420,18
-2298,1512904392769,19
-2299,1512904506525,18
-2300,1512904610698,18
-2301,1512904648238,17
-2302,1512904673790,17
-2303,1512904834005,18
-2304,1512904925816,17
-2305,1512904985824,16
-2306,1512905034759,16
-2307,1512905075688,16
-2308,1512905269912,16
-2309,1512905408209,15
-2310,1512905494871,16
-2311,1512905562242,16
-2312,1512905590851,16
-2313,1512905667403,16
-2314,1512905724772,16
-2315,1512905765111,17
-2316,1512905824433,17
-2317,1512906079179,17
-2318,1512906216348,17
-2319,1512906291039,16
-2320,1512906424449,17
-2321,1512906489326,17
-2322,1512906529649,16
-2323,1512906594528,16
-2324,1512906711008,16
-2325,1512906786917,16
-2326,1512906912987,16
-2327,1512907151988,15
-2328,1512907240561,15
-2329,1512907312879,14
-2330,1512907376520,13
-2331,1512907450488,13
-2332,1512907520946,13
-2333,1512907565619,14
-2334,1512907612067,14
-2335,1512907658801,14
-2336,1512907701202,14
-2337,1512907746914,14
-2338,1512907794460,14
-2339,1512907854189,13
-2340,1512907895458,13
-2341,1512907927115,14
-2342,1512907969886,15
-2343,1512908016732,15
-2344,1512908053198,14
-2345,1512908072559,14
-2346,1512908181707,16
-2347,1512908255180,16
-2348,1512908300652,15
-2349,1512908376798,16
-2350,1512908458151,16
-2351,1512908499436,16
-2352,1512908539468,16
-2353,1512908634111,15
-2354,1512908692844,15
-2355,1512908751794,15
-2356,1512908782647,14
-2357,1512908813622,14
-2358,1512908833300,15
-2359,1512908886806,16
-2360,1512908945258,15
-2361,1512908974448,15
-2362,1512909080238,16
-2363,1512909142051,16
-2364,1512909334050,16
-2365,1512909440293,15
-2366,1512909534180,15
-2367,1512909656737,14
-2368,1512909755299,14
-2369,1512909816020,14
-2370,1512909927866,15
-2371,1512909969178,14
-2372,1512909983191,14
-2373,1512910115159,16
-2374,1512910189046,15
-2375,1512910226256,15
-2376,1512910241335,16
-2377,1512910309523,18
-2378,1512910342275,18
-2379,1512910430534,18
-2380,1512910519914,20
-2381,1512910570234,19
-2382,1512910790271,20
-2383,1512910871412,19
-2384,1512911010407,19
-2385,1512911168621,19
-2386,1512911271027,18
-2387,1512911360786,18
-2388,1512911436184,18
-2389,1512911486465,18
-2390,1512911531774,18
-2391,1512911591879,19
-2392,1512911750459,18
-2393,1512911843409,18
-2394,1512911871082,18
-2395,1512911900502,19
-2396,1512912008452,20
-2397,1512912086160,19
-2398,1512912125303,19
-2399,1512912176430,19
-2400,1512912233037,19
-2401,1512912428516,19
-2402,1512912519259,20
-2403,1512912742650,20
-2404,1512912923222,19
-2405,1512912970989,19
-2406,1512913072238,19
-2407,1512913236047,18
-2408,1512913315861,18
-2409,1512913373099,18
-2410,1512913431489,18
-2411,1512913493493,18
-2412,1512913585258,18
-2413,1512913631207,18
-2414,1512913685154,18
-2415,1512913746709,18
-2416,1512913778935,18
-2417,1512913824499,19
-2418,1512913911026,19
-2419,1512913962092,19
-2420,1512914003370,19
-2421,1512914165310,18
-2422,1512914243301,18
-2423,1512914301776,19
-2424,1512914510228,18
-2425,1512914633391,17
-2426,1512914683075,16
-2427,1512914722125,17
-2428,1512915006776,17
-2429,1512915158073,16
-2430,1512915175879,16
-2431,1512915189187,18
-2432,1512915244462,20
-2433,1512915282928,20
-2434,1512915310366,20
-2435,1512915502700,21
-2436,1512915608131,20
-2437,1512915724538,20
-2438,1512915935061,20
-2439,1512916133086,19
-2440,1512916282472,17
-2441,1512916370264,18
-2442,1512916413985,18
-2443,1512916446988,18
-2444,1512916463157,18
-2445,1512916584473,21
-2446,1512916744593,21
-2447,1512916910207,20
-2448,1512917016877,20
-2449,1512917135229,19
-2450,1512917224554,19
-2451,1512917300251,18
-2452,1512917527440,18
-2453,1512917644578,18
-2454,1512917780189,17
-2455,1512917869124,17
-2456,1512917975217,17
-2457,1512918072254,16
-2458,1512918113092,16
-2459,1512918170204,17
-2460,1512918193153,17
-2461,1512918234551,18
-2462,1512918261942,19
-2463,1512918294499,20
-2464,1512918436789,20
-2465,1512918518890,19
-2466,1512918547357,19
-2467,1512918589472,19
-2468,1512918626892,20
-2469,1512918670990,20
-2470,1512918748242,21
-2471,1512918818778,20
-2472,1512918920146,20
-2473,1512918966003,20
-2474,1512919002838,21
-2475,1512919072300,21
-2476,1512919106941,21
-2477,1512919132997,23
-2478,1512919183176,23
-2479,1512919251213,25
-2480,1512919295111,24
-2481,1512919384695,25
-2482,1512919476544,24
-2483,1512919549729,24
-2484,1512919730878,24
-2485,1512919852264,24
-2486,1512919987297,23
-2487,1512920064276,22
-2488,1512920119659,22
-2489,1512920199450,22
-2490,1512920270118,22
-2491,1512920315186,22
-2492,1512920529585,22
-2493,1512920765656,22
-2494,1512920934067,21
-2495,1512921053566,20
-2496,1512921109453,20
-2497,1512921128405,21
-2498,1512921261744,22
-2499,1512921326221,22
-2500,1512921439752,22
-2501,1512921657736,22
-2502,1512921770254,21
-2503,1512921817422,21
-2504,1512921889087,20
-2505,1512921949495,20
-2506,1512921980713,21
-2507,1512922039075,20
-2508,1512922144436,21
-2509,1512922209226,19
-2510,1512922580189,19
-2511,1512922790955,19
-2512,1512922855721,19
-2513,1512922896009,19
-2514,1512922915696,18
-2515,1512923037060,19
-2516,1512923105224,20
-2517,1512923125847,19
-2518,1512923165980,21
-2519,1512923240275,22
-2520,1512923330999,22
-2521,1512923424418,22
-2522,1512923530017,21
-2523,1512923653247,20
-2524,1512923841188,20
-2525,1512923950829,19
-2526,1512924065174,19
-2527,1512924290536,18
-2528,1512924416262,18
-2529,1512924493038,16
-2530,1512924536020,16
-2531,1512924573837,16
-2532,1512924594934,18
-2533,1512924634141,18
-2534,1512924714599,20
-2535,1512924829579,20
-2536,1512924969716,20
-2537,1512925059722,18
-2538,1512925103189,18
-2539,1512925145119,18
-2540,1512925266746,18
-2541,1512925338974,18
-2542,1512925415235,17
-2543,1512925474528,18
-2544,1512925572664,17
-2545,1512925662233,18
-2546,1512925699929,17
-2547,1512925765295,18
-2548,1512925821333,18
-2549,1512925887546,17
-2550,1512925947273,17
-2551,1512926001269,17
-2552,1512926044851,16
-2553,1512926062110,16
-2554,1512926142151,17
-2555,1512926185653,17
-2556,1512926270126,17
-2557,1512926408723,16
-2558,1512926569684,16
-2559,1512926724766,15
-2560,1512926798945,15
-2561,1512926839703,15
-2562,1512926945851,15
-2563,1512927010858,15
-2564,1512927038983,15
-2565,1512927140104,15
-2566,1512927215920,14
-2567,1512927249601,15
-2568,1512927305494,15
-2569,1512927341181,15
-2570,1512927430997,16
-2571,1512927478246,16
-2572,1512927530987,16
-2573,1512927643218,16
-2574,1512927695884,15
-2575,1512927729643,16
-2576,1512927833190,16
-2577,1512927903884,15
-2578,1512927980357,16
-2579,1512928028395,17
-2580,1512928063132,16
-2581,1512928113674,17
-2582,1512928151452,17
-2583,1512928178503,17
-2584,1512928250420,19
-2585,1512928301486,17
-2586,1512928399908,18
-2587,1512928460878,18
-2588,1512928486918,17
-2589,1512928506993,17
-2590,1512928583390,19
-2591,1512928628477,19
-2592,1512928703038,20
-2593,1512928766551,19
-2594,1512928869726,19
-2595,1512928930677,18
-2596,1512928955728,18
-2597,1512928972969,20
-2598,1512929124394,22
-2599,1512929254648,22
-2600,1512929344354,22
-2601,1512929394558,21
-2602,1512929574514,21
-2603,1512929680391,21
-2604,1512929797332,20
-2605,1512929916422,20
-2606,1512930034057,20
-2607,1512930245180,19
-2608,1512930339931,19
-2609,1512930535382,19
-2610,1512930717877,18
-2611,1512930829886,18
-2612,1512930904466,17
-2613,1512931086199,16
-2614,1512931177129,17
-2615,1512931270803,16
-2616,1512931387257,16
-2617,1512931461069,16
-2618,1512931505720,16
-2619,1512931564945,16
-2620,1512931684849,17
-2621,1512931744779,17
-2622,1512931762175,16
-2623,1512931789597,17
-2624,1512931895009,18
-2625,1512931984994,17
-2626,1512932018623,17
-2627,1512932062135,18
-2628,1512932141322,18
-2629,1512932242454,17
-2630,1512932329913,17
-2631,1512932375170,17
-2632,1512932403639,17
-2633,1512932464786,18
-2634,1512932524485,18
-2635,1512932572333,18
-2636,1512932644887,19
-2637,1512932679355,18
-2638,1512932862689,19
-2639,1512932975229,18
-2640,1512933103269,17
-2641,1512933174490,17
-2642,1512933189019,17
-2643,1512933216549,19
-2644,1512933320098,20
-2645,1512933380159,20
-2646,1512933519801,19
-2647,1512933589293,19
-2648,1512933622469,19
-2649,1512933667494,19
-2650,1512933804757,20
-2651,1512933904788,20
-2652,1512933934746,19
-2653,1512934055943,20
-2654,1512934223399,20
-2655,1512934295588,20
-2656,1512934416754,20
-2657,1512934494130,19
-2658,1512934535655,19
-2659,1512934685196,19
-2660,1512934790273,18
-2661,1512934897707,18
-2662,1512935028434,18
-2663,1512935122440,17
-2664,1512935195296,16
-2665,1512935283748,16
-2666,1512935343637,16
-2667,1512935449512,16
-2668,1512935510886,16
-2669,1512935630839,15
-2670,1512935753498,16
-2671,1512935799805,14
-2672,1512935826265,15
-2673,1512935863107,15
-2674,1512935937117,15
-2675,1512936006341,15
-2676,1512936034856,15
-2677,1512936073447,15
-2678,1512936148321,15
-2679,1512936260653,15
-2680,1512936395173,15
-2681,1512936476436,14
-2682,1512936502772,15
-2683,1512936529447,15
-2684,1512936589581,16
-2685,1512936649872,16
-2686,1512936671774,16
-2687,1512936725494,17
-2688,1512936892820,17
-2689,1512937010159,16
-2690,1512937048481,17
-2691,1512937120622,18
-2692,1512937180231,16
-2693,1512937235029,16
-2694,1512937270885,16
-2695,1512937309736,16
-2696,1512937386111,16
-2697,1512937430667,18
-2698,1512937450656,19
-2699,1512937490618,21
-2700,1512937535538,21
-2701,1512937599336,22
-2702,1512937663009,22
-2703,1512937721417,21
-2704,1512937941684,22
-2705,1512938139460,21
-2706,1512938225671,20
-2707,1512938284147,20
-2708,1512938319758,20
-2709,1512938509859,20
-2710,1512938645136,20
-2711,1512938697032,19
-2712,1512938751154,19
-2713,1512938842262,19
-2714,1512938976287,18
-2715,1512939040427,18
-2716,1512939064387,18
-2717,1512939139273,19
-2718,1512939216245,18
-2719,1512939288993,18
-2720,1512939339448,18
-2721,1512939386912,18
-2722,1512939472023,18
-2723,1512986278727,18
-2724,1512986330560,18
-2725,1512986353260,18
-2726,1512986546838,18
-2727,1512986720358,17
-2728,1512986744761,17
-2729,1512986834498,19
-2730,1512986999853,17
-2731,1512987020432,18
-2732,1512987072224,19
-2733,1512987143731,20
-2734,1512987267567,19
-2735,1512987379728,19
-2736,1512987404798,19
-2737,1512987466896,20
-2738,1512987582215,21
-2739,1512987838734,19
-2740,1512987854672,19
-2741,1512987860296,21
-2742,1512987945128,29
-2743,1512988247973,30
-2744,1512988502631,29
-2745,1512988874210,29
-2746,1513169019670,28
-2747,1513169037556,27
-2748,1513169222313,30
-2749,1513169341163,30
-2750,1513169355800,29
-2751,1513169380083,33
-2752,1513169391201,35
-2753,1513169406304,42
-2754,1513169561395,48
-2755,1513169662291,47
-2756,1513169714826,46
-2757,1513169728497,48
-2758,1513169838753,55
-2759,1513170021569,55
-2760,1513170130348,54
-2761,1513170159538,53
-2762,1513170194193,56
-2763,1513170320272,59
-2764,1513170436942,59
-2765,1513170491060,58
-2766,1513170555205,58
-2767,1513170699016,59
-2768,1513170706164,59
-2769,1513170841624,76
-2770,1513171149892,76
-2771,1513171517920,75
-2772,1513171951719,73
-2773,1513172051598,72
-2774,1513172162875,73
-2775,1513172348918,71
-2776,1513172605196,71
-2777,1513172701712,70
-2778,1513172727286,70
-2779,1513172804360,74
-2780,1513172958380,75
-2781,1513173086881,73
-2782,1513173124708,73
-2783,1513173189674,75
-2784,1513173203486,76
-2785,1513173229838,88
-2786,1513173276987,93
-2787,1513173677474,95
-2788,1513174142060,94
-2789,1513174155810,92
-2790,1513174356609,105
-2791,1513174844033,104
-2792,1513175021343,102
-2793,1513175612640,100
-2794,1513175765055,98
-2795,1513175857081,97
-2796,1513175907276,96
-2797,1513175926726,98
-2798,1513176022704,109
-2799,1513176357626,109
-2800,1513176626886,107
-2801,1513176741290,105
-2802,1513176931614,104
-2803,1513177501279,103
-2804,1513177514861,101
-2805,1513177885940,115
-2806,1513178266990,112
-2807,1513178346182,109
-2808,1513178708054,109
-2809,1513178715307,108
-2810,1513179135258,139
-2811,1513179226243,136
-2812,1513179411859,136
-2813,1513179434049,134
-2814,1513179554802,144
-2815,1513179785412,143
-2816,1513180140008,141
-2817,1513180308234,137
-2818,1513180608799,135
-2819,1513180666858,132
-2820,1513180877621,134
-2821,1513181061140,130
-2822,1513181370044,128
-2823,1513181423412,124
-2824,1513181949519,125
-2825,1513182356016,122
-2826,1513182484809,119
-2827,1513182591089,116
-2828,1513182608049,115
-2829,1513182994489,127
-2830,1513183030260,123
-2831,1513183077619,126
-2832,1513183175909,129
-2833,1513183385167,127
-2834,1513183417532,124
-2835,1513183424624,127
-2836,1513183444875,166
-2837,1513183546843,180
-2838,1513183712527,179
-2839,1513184066399,175
-2840,1513184175878,170
-2841,1513184529560,169
-2842,1513185044227,168
-2843,1513185359299,163
-2844,1513185450389,158
-2845,1513185509517,157
-2846,1513185627154,156
-2847,1513185631297,153
-2848,1513185706252,237
-2849,1513185776510,237
-2850,1513185853775,238
-2851,1513185913612,239
-2852,1513185958068,242
-2853,1513186071621,252
-2854,1513186705595,252
-2855,1513187152572,245
-2856,1513187733614,239
-2857,1513188715264,233
-2858,1513188850069,229
-2859,1513189884984,225
-2860,1513190464889,218
-2861,1513190514483,212
-2862,1513190724771,217
-2863,1513190840960,213
-2864,1513191730926,210
-2865,1513192327619,202
-2866,1513192464495,196
-2867,1513192641944,192
-2868,1513192778903,188
-2869,1513193061276,193
-2870,1513193240961,187
-2871,1513193383206,182
-2872,1513193402361,177
-2873,1513193483412,191
-2874,1513193835624,190
-2875,1513193842976,184
-2876,1513193931534,236
-2877,1513194140874,233
-2878,1513194338266,227
-2879,1513194456481,224
-2880,1513194685974,220
-2881,1513194950855,214
-2882,1513194979566,207
-2883,1513196199747,217
-2884,1513196768891,209
-2885,1513197293496,207
-2886,1513197324944,203
-2887,1513197504356,211
-2888,1513197526612,205
-2889,1513197645359,218
-2890,1513198294292,221
-2891,1513198538201,213
-2892,1513198767228,206
-2893,1513199004783,199
-2894,1513199707418,191
-2895,1513200296425,183
-2896,1513200524734,175
-2897,1513200595924,170
-2898,1513201002750,172
-2899,1513201259844,165
-2900,1513201797497,157
-2901,1513202553317,149
-2902,1513202714065,141
-2903,1513202813930,135
-2904,1513203572358,128
-2905,1513204590553,128
-2906,1513204607060,120
-2907,1513204669243,128
-2908,1513204838242,126
-2909,1513205198327,119
-2910,1513205209301,129
-2911,1513205467111,148
-2912,1513205541529,142
-2913,1513205671007,138
-2914,1513205744676,139
-2915,1513205824161,135
-2916,1513205828127,131
-2917,1513206077636,201
-2918,1513206598974,193
-2919,1513207191885,184
-2920,1513207786258,177
-2921,1513207890326,169
-2922,1513207958500,163
-2923,1513208293834,158
-2924,1513208766726,152
-2925,1513209633500,142
-2926,1513209733392,133
-2927,1513209832576,127
-2928,1513209860647,120
-2929,1513210305365,128
-2930,1513210530085,120
-2931,1513210788364,114
-2932,1513211160348,109
-2933,1513211189774,100
-2934,1513211340810,99
-2935,1513211389001,95
-2936,1513211409415,112
-2937,1513211519995,126
-2938,1513211527197,121
-2939,1513211576339,153
-2940,1513211744446,151
-2941,1513212135734,146
-2942,1513212363017,136
-2943,1513212553762,129
-2944,1513212746414,120
-2945,1513213010226,114
-2946,1513213232997,109
-2947,1513213310696,102
-2948,1513213462449,140
-2949,1513213757741,138
-2950,1513213957950,135
-2951,1513215104893,131
-2952,1513215165488,128
-2953,1513215489219,131
-2954,1513215648218,127
-2955,1513215793289,121
-2956,1513216418743,116
-2957,1513216497705,108
-2958,1513216738527,104
-2959,1513216822694,99
-2960,1513216839243,95
-2961,1513216921147,100
-2962,1513217117038,101
-2963,1513217522972,95
-2964,1513217958034,89
-2965,1513217994849,82
-2966,1513218061805,80
-2967,1513218148286,76
-2968,1513218247046,71
-2969,1513218316619,66
-2970,1513218433058,62
-2971,1513218638497,56
-2972,1513218843340,50
-2973,1513218928799,54
-2974,1513219001542,51
-2975,1513219079938,45
-2976,1513219144657,69
-2977,1513219220130,69
-2978,1513219367047,66
-2979,1513219387243,61
-2980,1513219412435,64
-2981,1513219447120,65
-2982,1513219508513,63
-2983,1513219567315,68
-2984,1513219743538,64
-2985,1513219797782,59
-2986,1513219853869,56
-2987,1513219999275,59
-2988,1513220013012,55
-2989,1513220082123,69
-2990,1513220184900,67
-2991,1513220378367,64
-2992,1513220407248,59
-2993,1513220522638,58
-2994,1513220682631,55
-2995,1513220705454,50
-2996,1513220865366,49
-2997,1513220924777,44
-2998,1513220947577,43
-2999,1513220967540,41
-3000,1513221092941,40
-3001,1513221252704,36
-3002,1513221269195,30
-3003,1513221276295,28
-3004,1513221393404,34
-3005,1513221400892,28
-3006,1513221434376,30
-3007,1513221468904,35
-3008,1513221656525,33
-3009,1513221724312,28
-3010,1513221877810,24
-3011,1513221998363,32
-3012,1513222022319,27
-3013,1513222094877,27
-3014,1513222166066,23
-3015,1513222191170,20
-3016,1513222223139,19
-3017,1513222268881,55
-3018,1513222291216,54
-3019,1513222317074,56
-3020,1513222381804,57
-3021,1513222407743,54
-3022,1513222457877,57
-3023,1513222505016,57
-3024,1513222534362,56
-3025,1513222622379,56
-3026,1513222721197,53
-3027,1513222740699,51
-3028,1513222930793,54
-3029,1513222956351,56
-3030,1513223003678,57
-3031,1513223236234,55
-3032,1513223265320,51
-3033,1513223304100,51
-3034,1513223364677,54
-3035,1513223426113,52
-3036,1513223650812,51
-3037,1513223937272,54
-3038,1513224193763,51
-3039,1513224230663,67
-3040,1513224378021,72
-3041,1513224424556,70
-3042,1513224448347,71
-3043,1513224475832,75
-3044,1513224544782,78
-3045,1513224688991,77
-3046,1513224782498,75
-3047,1513224811672,74
-3048,1513225098504,77
-3049,1513225105804,75
-3050,1513225241540,96
-3051,1513225359015,94
-3052,1513225372169,92
-3053,1513225652826,107
-3054,1513226018678,103
-3055,1513226181252,100
-3056,1513226223057,98
-3057,1513226324253,99
-3058,1513226466053,98
-3059,1513226610253,96
-3060,1513226802697,94
-3061,1513227079998,98
-3062,1513227171114,95
-3063,1513227208888,94
-3064,1513227237592,96
-3065,1513227352607,99
-3066,1513227496633,99
-3067,1513227665306,98
-3068,1513227825997,95
-3069,1513227830087,94
-3070,1513228182152,145
-3071,1513228340790,141
-3072,1513228507870,139
-3073,1513228982582,135
-3074,1513228986416,132
-3075,1513229194948,209
-3076,1513229770788,206
-3077,1513229800708,201
-3078,1513229877268,212
-3079,1513229999551,212
-3080,1513230322676,213
-3081,1513230638332,211
-3082,1513231124367,208
-3083,1513231214803,203
-3084,1513231614940,204
-3085,1513232095539,198
-3086,1513232403289,193
-3087,1513232654011,190
-3088,1513232906061,186
-3089,1513232947126,185
-3090,1513233230527,190
-3091,1513233434074,186
-3092,1513233659707,182
-3093,1513233853675,180
-3094,1513234051345,176
-3095,1513234645447,171
-3096,1513235193437,167
-3097,1513235307459,162
-3098,1513235571128,159
-3099,1513235827880,157
-3100,1513235899104,154
-3101,1513235988229,153
-3102,1513236159577,150
-3103,1513236276839,148
-3104,1513236402310,150
-3105,1513236611658,146
-3106,1513237002852,146
-3107,1513237349687,140
-3108,1513237544895,136
-3109,1513237652709,131
-3110,1513238552017,129
-3111,1513238699488,123
-3112,1513238900837,118
-3113,1513238968178,115
-3114,1513239280261,112
-3115,1513239343432,107
-3116,1513239435487,105
-3117,1513239574980,102
-3118,1513239868637,99
-3119,1513239872645,96
-3120,1513239876692,149
-3121,1513240292698,232
-3122,1513240561658,227
-3123,1513240578022,221
-3124,1513240944377,247
-3125,1513241467668,242
-3126,1513241484725,234
-3127,1513241550711,259
-3128,1513242010652,262
-3129,1513242118095,254
-3130,1513242361811,253
-3131,1513242536456,247
-3132,1513243123621,241
-3133,1513243382686,235
-3134,1513243949962,229
-3135,1513244758167,222
-3136,1513244952972,214
-3137,1513245299594,207
-3138,1513246152472,199
-3139,1513246252408,190
-3140,1513246533436,188
-3141,1513247259481,180
-3142,1513247589338,173
-3143,1513247630230,168
-3144,1513247763008,172
-3145,1513248335550,167
-3146,1513249272982,159
-3147,1513249366418,152
-3148,1513249683904,148
-3149,1513249835981,141
-3150,1513250295595,146
-3151,1513250785590,139
-3152,1513251234278,131
-3153,1513251373205,132
-3154,1513251686979,126
-3155,1513251866431,118
-3156,1513251955366,112
-3157,1513252056670,109
-3158,1513252606269,103
-3159,1513252613468,96
-3160,1513252771443,120
-3161,1513252902096,114
-3162,1513253124598,107
-3163,1513253191660,99
-3164,1513253264604,97
-3165,1513253363523,96
-3166,1513254221190,89
-3167,1513254238594,82
-3168,1513254372096,85
-3169,1513254523716,78
-3170,1513254584354,97
-3171,1513254682187,94
-3172,1513254890207,89
-3173,1513254956923,82
-3174,1513254993610,76
-3175,1513255083585,115
-3176,1513255267222,112
-3177,1513255540502,107
-3178,1513256531364,109
-3179,1513256797071,105
-3180,1513256823080,101
-3181,1513257134548,105
-3182,1513257189487,99
-3183,1513257302626,96
-3184,1513257429485,94
-3185,1513257849993,90
-3186,1513258014325,84
-3187,1513258104601,78
-3188,1513258210381,74
-3189,1513258267141,69
-3190,1513258292096,71
-3191,1513258440556,72
-3192,1513258476392,68
-3193,1513258534283,65
-3194,1513258538779,62
-3195,1513258746193,90
-3196,1513259009840,83
-3197,1513259364528,77
-3198,1513259574135,72
-3199,1513259606682,66
-3200,1513259633471,64
-3201,1513259647280,64
-3202,1513259705231,70
-3203,1513259892616,67
-3204,1513259946970,61
-3205,1513260002627,57
-3206,1513260275519,53
-3207,1513260286549,46
-3208,1513260314498,49
-3209,1513260468403,47
-3210,1513260531753,41
-3211,1513260651626,35
-3212,1513260788865,28
-3213,1513260798253,22
-3214,1513260985331,22
-3215,1513261018705,15
-3216,1513261075942,11
-3217,1513261080076,5
-3218,1513261087492,1
-3219,1513261091758,1
-3220,1513261100095,16
-3221,1513261141570,59
-3222,1513261272088,57
-3223,1513261411177,55
-3224,1513261469501,66
-3225,1513261537807,65
-3226,1513261557511,62
-3227,1513261696266,82
-3228,1513261706980,83
-3229,1513262010234,98
-3230,1513262409302,96
-3231,1513262543691,93
-3232,1513262841540,92
-3233,1513263075865,89
-3234,1513263106585,86
-3235,1513263210285,88
-3236,1513263272209,86
-3237,1513263354086,86
-3238,1513263677918,84
-3239,1513263837526,80
-3240,1513264127426,79
-3241,1513264270454,75
-3242,1513264753400,72
-3243,1513264860253,68
-3244,1513265025028,69
-3245,1513265199560,68
-3246,1513266411771,64
-3247,1513266643462,59
-3248,1513266736530,58
-3249,1513267584715,56
-3250,1513269043232,51
-3251,1513269449578,47
-3252,1513269543240,44
-3253,1513271242912,41
-3254,1513272164802,37
-3255,1513272942260,33
-3256,1513275606642,29
-3257,1513330831420,26
-3258,1513330929013,23
-3259,1513331090053,20
-3260,1513331132427,32
-3261,1513331155602,31
-3262,1513331161924,31
-3263,1513331236914,39
-3264,1513331323194,39
-3265,1513331375356,37
-3266,1513331464472,36
-3267,1513331545500,32
-3268,1513331560325,36
-3269,1513331600424,38
-3270,1513331638011,37
-3271,1513331716749,37
-3272,1513331732697,36
-3273,1513331747624,38
-3274,1513331782735,41
-3275,1513331802960,42
-3276,1513331837403,46
-3277,1513331926495,45
-3278,1513331933986,42
-3279,1513332017449,52
-3280,1513332167013,50
-3281,1513332191275,50
-3282,1513332234448,53
-3283,1513332249961,53
-3284,1513332340989,58
-3285,1513332350233,56
-3286,1513332387512,67
-3287,1513332556425,67
-3288,1513332653361,64
-3289,1513332820648,63
-3290,1513332894926,60
-3291,1513332953424,61
-3292,1513332991470,60
-3293,1513333049049,61
-3294,1513333061504,61
-3295,1513333077456,85
-3296,1513333135228,94
-3297,1513333328432,94
-3298,1513333534905,91
-3299,1513333593004,89
-3300,1513333667871,90
-3301,1513333823993,91
-3302,1513333999082,95
-3303,1513334066825,93
-3304,1513334306269,93
-3305,1513334425653,91
-3306,1513334488876,89
-3307,1513334737134,89
-3308,1513334991848,91
-3309,1513335607807,90
-3310,1513335777324,86
-3311,1513336050234,84
-3312,1513336099663,81
-3313,1513336165732,82
-3314,1513336226796,83
-3315,1513336337396,83
-3316,1513336384957,81
-3317,1513336391740,81
-3318,1513336640574,107
-3319,1513336672997,105
-3320,1513336838813,108
-3321,1513337530678,107
-3322,1513338100091,105
-3323,1513338242443,102
-3324,1513338289251,99
-3325,1513338882750,101
-3326,1513338963605,98
-3327,1513339194681,100
-3328,1513339328175,97
-3329,1513339340462,104
-3330,1513339565085,120
-3331,1513339962781,118
-3332,1513340091996,115
-3333,1513340292658,112
-3334,1513340531747,110
-3335,1513341063030,110
-3336,1513341253825,107
-3337,1513341342465,105
-3338,1513341350022,105
-3339,1513341685101,135
-3340,1513341700366,132
-3341,1513341772511,147
-3342,1513341929761,148
-3343,1513343049766,145
-3344,1513343107508,141
-3345,1513343363550,142
-3346,1513344039007,138
-3347,1513344450939,133
-3348,1513345343870,130
-3349,1513345416444,125
-3350,1513345474667,125
-3351,1513345484207,124
-3352,1513345649018,149
-3353,1513345867437,147
-3354,1513345999575,143
-3355,1513346259037,139
-3356,1513346697112,134
-3357,1513347597352,129
-3358,1513347762828,123
-3359,1513347792476,119
-3360,1513347898958,123
-3361,1513347928648,121
-3362,1513348137756,126
-3363,1513348142122,127
-3364,1513348574943,191
-3365,1513349398716,185
-3366,1513349468021,179
-3367,1513350061459,179
-3368,1513350287428,173
-3369,1513350430693,170
-3370,1513350470093,168
-3371,1513350564716,172
-3372,1513350690586,170
-3373,1513350700302,168
-3374,1513350730662,206
-3375,1513350901249,215
-3376,1513351781895,213
-3377,1513352057503,207
-3378,1513352306026,201
-3379,1513352479670,202
-3380,1513352542882,198
-3381,1513352644370,198
-3382,1513353171701,197
-3383,1513353475466,192
-3384,1513353689381,189
-3385,1513354078437,184
-3386,1513354175144,185
-3387,1513354774686,184
-3388,1513354956387,178
-3389,1513355299931,174
-3390,1513355360837,168
-3391,1513355953202,167
-3392,1513356486650,162
-3393,1513356696557,157
-3394,1513356745837,152
-3395,1513356967934,158
-3396,1513357058009,158
-3397,1513357136380,158
-3398,1513357398307,156
-3399,1513357626953,150
-3400,1513357866130,146
-3401,1513358100691,142
-3402,1513358129723,136
-3403,1513358256233,141
-3404,1513358368506,138
-3405,1513358456224,133
-3406,1513358467098,131
-3407,1513358650602,154
-3408,1513358702638,147
-3409,1513358986442,147
-3410,1513359318746,140
-3411,1513359398237,134
-3412,1513359470340,130
-3413,1513359491398,128
-3414,1513359522982,136
-3415,1513359675933,139
-3416,1513359694104,134
-3417,1513359718559,146
-3418,1513359848468,166
-3419,1513360015541,161
-3420,1513360114744,159
-3421,1513360195362,155
-3422,1513361068262,152
-3423,1513361258595,144
-3424,1513361407318,138
-3425,1513361588562,134
-3426,1513362086709,127
-3427,1513362479946,122
-3428,1513362722105,114
-3429,1513362766080,107
-3430,1513363099986,115
-3431,1513363227042,109
-3432,1513363635101,103
-3433,1513363710833,96
-3434,1513363891138,92
-3435,1513363924676,85
-3436,1513364189635,83
-3437,1513364683103,77
-3438,1513364948970,70
-3439,1513364990023,80
-3440,1513365036247,77
-3441,1513365792464,84
-3442,1513365802456,79
-3443,1513366141722,92
-3444,1513366217238,85
-3445,1513366252953,83
-3446,1513366314948,82
-3447,1513366533803,77
-3448,1513366792486,70
-3449,1513366943516,63
-3450,1513367000166,59
-3451,1513367064161,56
-3452,1513367086123,67
-3453,1513367195670,68
-3454,1513367346730,63
-3455,1513367374653,57
-3456,1513367421343,55
-3457,1513367837163,52
-3458,1513367875706,45
-3459,1513367978012,41
-3460,1513368141491,39
-3461,1513368148404,34
-3462,1513368230085,44
-3463,1513368277092,39
-3464,1513368419283,69
-3465,1513368588534,64
-3466,1513368642407,59
-3467,1513368709218,59
-3468,1513368789775,55
-3469,1513368876273,51
-3470,1513368883271,48
-3471,1513368887334,63
-3472,1513368940202,96
-3473,1513369283818,96
-3474,1513369290363,111
-3475,1513369407334,154
-3476,1513369607012,152
-3477,1513369845579,147
-3478,1513370323544,143
-3479,1513370480416,138
-3480,1513370570510,135
-3481,1513370614936,135
-3482,1513370758197,138
-3483,1513371479523,135
-3484,1513372388162,130
-3485,1513372514893,124
-3486,1513372521886,121
-3487,1513372606448,159
-3488,1513372727243,156
-3489,1513373317967,153
-3490,1513373857226,147
-3491,1513373863790,144
-3492,1513374012408,190
-3493,1513374076939,185
-3494,1513374248285,185
-3495,1513374721256,184
-3496,1513375336099,177
-3497,1513375440443,173
-3498,1513375466956,171
-3499,1513375474762,179
-3500,1513375588054,228
-3501,1513375950620,224
-3502,1513376074141,218
-3503,1513377008004,218
-3504,1513377065618,212
-3505,1513377418658,213
-3506,1513377473065,207
-3507,1513377967305,223
-3508,1513378261238,216
-3509,1513379001772,213
-3510,1513379284926,206
-3511,1513379624656,200
-3512,1513379845776,195
-3513,1513379970991,191
-3514,1513380535132,194
-3515,1513380624132,191
-3516,1513381809331,189
-3517,1513383169348,191
-3518,1513383702573,191
-3519,1513384300957,185
-3520,1513384378304,180
-3521,1513384577184,180
-3522,1513384892582,177
-3523,1513385204789,171
-3524,1513385521241,165
-3525,1513385588265,160
-3526,1513386037642,160
-3527,1513386138928,153
-3528,1513386383001,149
-3529,1513386472750,143
-3530,1513386816920,143
-3531,1513387289662,137
-3532,1513387385134,131
-3533,1513387556333,126
-3534,1513387712403,122
-3535,1513387844601,117
-3536,1513387856802,114
-3537,1513387974619,130
-3538,1513388601584,125
-3539,1513389011568,118
-3540,1513389049308,113
-3541,1513389188868,115
-3542,1513389281569,108
-3543,1513389339510,113
-3544,1513389754020,110
-3545,1513389908480,105
-3546,1513390147050,101
-3547,1513390163195,96
-3548,1513390322181,103
-3549,1513390571676,97
-3550,1513390691784,90
-3551,1513390756640,86
-3552,1513390831892,82
-3553,1513390902371,80
-3554,1513391046064,76
-3555,1513391117983,71
-3556,1513391121971,67
-3557,1513391179109,101
-3558,1513391211694,98
-3559,1513391737001,98
-3560,1513391834305,90
-3561,1513392198778,84
-3562,1513392490894,83
-3563,1513392792975,75
-3564,1513392851411,69
-3565,1513393174592,64
-3566,1513393247503,56
-3567,1513393309635,51
-3568,1513393368004,46
-3569,1513393392745,40
-3570,1513393396924,37
-3571,1513393627927,58
-3572,1513393938522,70
-3573,1513393951012,65
-3574,1513394109378,69
-3575,1513394239772,83
-3576,1513394317848,79
-3577,1513394341305,75
-3578,1513394423365,76
-3579,1513394598765,71
-3580,1513394609156,65
-3581,1513394880464,75
-3582,1513394933028,72
-3583,1513395422529,68
-3584,1513395495395,62
-3585,1513395510860,56
-3586,1513395517544,59
-3587,1513395524228,94
-3588,1513395542078,123
-3589,1513395759313,131
-3590,1513395898994,127
-3591,1513395942735,121
-3592,1513395975428,146
-3593,1513396110334,151
-3594,1513396168306,151
-3595,1513396498685,150
-3596,1513397209272,144
-3597,1513397310235,138
-3598,1513397678072,135
-3599,1513397952485,137
-3600,1513398015775,159
-3601,1513398163250,161
-3602,1513398799231,158
-3603,1513399408831,154
-3604,1513399481338,150
-3605,1513399516138,152
-3606,1513399613546,157
-3607,1513399823163,159
-3608,1513400216549,155
-3609,1513400231570,151
-3610,1513400244129,168
-3611,1513401034043,195
-3612,1513402013791,189
-3613,1513402643716,183
-3614,1513402730169,179
-3615,1513402953290,177
-3616,1513403437598,175
-3617,1513403747541,168
-3618,1513404049658,163
-3619,1513404062336,157
-3620,1513404439288,180
-3621,1513404497759,176
-3622,1513404549824,177
-3623,1513404621651,179
-3624,1513404628320,177
-3625,1513404663597,234
-3626,1513405151670,244
-3627,1513405279387,237
-3628,1513405699246,235
-3629,1513406069993,227
-3630,1513406085644,221
-3631,1513406145780,247
-3632,1513408175915,248
-3633,1513408548002,240
-3634,1513408630728,234
-3635,1513409015013,232
-3636,1513409079153,224
-3637,1513409719830,236
-3638,1513409839966,229
-3639,1513410202059,224
-3640,1513410241533,216
-3641,1513410245396,224
-3642,1513410496517,355
-3643,1513410564037,348
-3644,1513411491137,351
-3645,1513411628198,340
-3646,1513411958291,336
-3647,1513412688919,327
-3648,1513413345472,324
-3649,1513413568511,314
-3650,1513413907825,306
-3651,1513414035003,298
-3652,1513414404120,293
-3653,1513414762535,285
-3654,1513414844099,277
-3655,1513415509590,274
-3656,1513415578396,264
-3657,1513415748460,283
-3658,1513416236935,278
-3659,1513416535811,271
-3660,1513416651305,263
-3661,1513417273290,258
-3662,1513417823452,248
-3663,1513417996157,239
-3664,1513418186222,231
-3665,1513418369978,224
-3666,1513418567803,216
-3667,1513418658056,209
-3668,1513418665002,203
-3669,1513418845227,263
-3670,1513418860392,256
-3671,1513419324896,296
-3672,1513420416020,285
-3673,1513421683467,272
-3674,1513422110242,267
-3675,1513422384574,257
-3676,1513423600055,247
-3677,1513424127804,237
-3678,1513424604639,229
-3679,1513426112141,219
-3680,1513426268719,207
-3681,1513427047646,205
-3682,1513427837653,195
-3683,1513428121379,185
-3684,1513428353544,174
-3685,1513428656183,165
-3686,1513428930729,159
-3687,1513429048902,159
-3688,1513429061325,167
-3689,1513429281662,197
-3690,1513429498076,188
-3691,1513429787751,180
-3692,1513429876809,173
-3693,1513430007301,172
-3694,1513430174869,165
-3695,1513430558083,159
-3696,1513430602835,149
-3697,1513430761433,147
-3698,1513430851591,139
-3699,1513430866691,131
-3700,1513430985864,142
-3701,1513431385607,136
-3702,1513431400696,127
-3703,1513432268543,135
-3704,1513432839892,124
-3705,1513432946701,115
-3706,1513433103525,111
-3707,1513433203923,103
-3708,1513433270503,95
-3709,1513433434469,86
-3710,1513433441064,88
-3711,1513433496193,126
-3712,1513433528082,120
-3713,1513433531850,118
-3714,1513433810241,182
-3715,1513433879715,174
-3716,1513434737533,168
-3717,1513434924762,155
-3718,1513435481504,146
-3719,1513435485576,134
-3720,1513436078305,215
-3721,1513437156030,203
-3722,1513437174844,193
-3723,1513437189955,209
-3724,1513437477774,232
-3725,1513437980247,252
-3726,1513438240400,249
-3727,1513438300655,239
-3728,1513438352888,238
-3729,1513438703995,236
-3730,1513438918767,226
-3731,1513438939577,232
-3732,1513438954641,251
-3733,1513438999099,278
-3734,1513439264413,281
-3735,1513439719118,273
-3736,1513439731665,261
-3737,1513439942888,302
-3738,1513440316157,291
-3739,1513440671768,281
-3740,1513441338113,269
-3741,1513441681978,263
-3742,1513441896022,323
-3743,1513442163025,315
-3744,1513442441322,313
-3745,1513443616646,304
-3746,1513443842656,296
-3747,1513444047978,289
-3748,1513444364262,281
-3749,1513444717346,271
-3750,1513444813958,263
-3751,1513444840010,258
-3752,1513444942179,273
-3753,1513445579699,269
-3754,1513445606760,258
-3755,1513446118305,273
-3756,1513446787144,262
-3757,1513446797038,256
-3758,1513446924038,307
-3759,1513448150537,300
-3760,1513448701894,289
-3761,1513448760300,280
-3762,1513449234764,278
-3763,1513450497901,267
-3764,1513451884591,256
-3765,1513452040499,244
-3766,1513452893885,236
-3767,1513452962336,224
-3768,1513453628623,221
-3769,1513453978662,245
-3770,1513455042317,237
-3771,1513457924190,246
-3772,1513458786185,235
-3773,1513459856235,225
-3774,1513459945962,214
-3775,1513460268589,208
-3776,1513460331984,199
-3777,1513460441975,194
-3778,1513460547380,188
-3779,1513461054358,181
-3780,1513461259478,171
-3781,1513461591756,163
-3782,1513461712265,152
-3783,1513461896474,143
-3784,1513462118958,134
-3785,1513462157016,124
-3786,1513462287416,121
-3787,1513462509851,111
-3788,1513462797353,102
-3789,1513462849347,108
-3790,1513462893106,103
-3791,1513463142242,98
-3792,1513463309505,87
-3793,1513463780156,80
-3794,1513464055749,70
-3795,1513464128789,60
-3796,1513464401748,52
-3797,1513464496929,44
-3798,1513464569172,35
-3799,1513464578767,27
-3800,1513464591448,33
-3801,1513464629866,29
-3802,1513464699824,21
-3803,1513464726117,20
-3804,1513464736023,12
-3805,1513464786084,4
-3806,1513464801898,1
-3807,1513464805708,1
-3808,1513464812253,1
-3809,1513464816084,1
-3810,1513464822681,1
-3811,1513464827357,1
-3812,1513464835208,1
-3813,1513464839089,1
-3814,1513464842933,1
-3815,1513464846680,1
-3816,1513464850446,1
-3817,1513464854349,1
-3818,1513464858379,1
-3819,1513464862162,1
-3820,1513464866081,1
-3821,1513464869918,1
-3822,1513464873897,1
-3823,1513464878014,1
-3824,1513464888675,1
-3825,1513464892274,1
-3826,1513464896120,1
-3827,1513464900069,1
-3828,1513464904044,1
-3829,1513464907854,1
-3830,1513464911845,1
-3831,1513464915548,1
-3832,1513464919386,1
-3833,1513464923339,1
-3834,1513464927296,1
-3835,1513464931319,1
-3836,1513464942798,1
-3837,1513464947175,1
-3838,1513464950932,1
-3839,1513464954683,1
-3840,1513464958505,1
-3841,1513464962705,1
-3842,1513464966667,1
-3843,1513464970549,1
-3844,1513464974779,1
-3845,1513464983473,1
-3846,1513464991291,1
-3847,1513464995626,1
-3848,1513464999375,1
-3849,1513465006472,1
-3850,1513465010462,1
-3851,1513465014246,1
-3852,1513465018079,1
-3853,1513465021920,1
-3854,1513465026302,1
-3855,1513465034055,1
-3856,1513465041578,1
-3857,1513465045464,1
-3858,1513465049413,1
-3859,1513465053456,1
-3860,1513465057245,1
-3861,1513465061011,1
-3862,1513465065808,1
-3863,1513465070081,1
-3864,1513465074172,1
-3865,1513465077849,1
-3866,1513465081633,1
-3867,1513465085539,1
-3868,1513465089458,1
-3869,1513465099578,1
-3870,1513465103529,1
-3871,1513465107263,1
-3872,1513465111091,1
-3873,1513465117625,1
-3874,1513465121445,1
-3875,1513465125417,1
-3876,1513465129318,1
-3877,1513465133347,1
-3878,1513465137654,1
-3879,1513465141525,1
-3880,1513465145557,1
-3881,1513465154036,1
-3882,1513465160766,1
-3883,1513465164673,1
-3884,1513465168690,1
-3885,1513465173256,1
-3886,1513465183725,2
-3887,1513465205671,2
-3888,1513465212249,1
-3889,1513465219347,1
-3890,1513465227001,3
-3891,1513465235223,6
-3892,1513465241922,6
-3893,1513465289160,8
-3894,1513465315499,8
-3895,1513465319399,8
-3896,1513465332660,12
-3897,1513465336538,14
-3898,1513465363261,22
-3899,1513465372675,23
-3900,1513465405313,31
-3901,1513465462118,35
-3902,1513465477974,36
-3903,1513465537320,41
-3904,1513465545728,42
-3905,1513465569716,54
-3906,1513465835729,58
-3907,1513466349602,57
-3908,1513466507013,56
-3909,1513466623009,55
-3910,1513466649854,55
-3911,1513466671747,59
-3912,1513466899957,64
-3913,1513467102555,63
-3914,1513467537105,62
-3915,1513467577920,62
-3916,1513467634770,63
-3917,1513467659025,65
-3918,1513467806618,69
-3919,1513467813607,69
-3920,1513467846233,91
-3921,1513467892528,96
-3922,1513467981371,99
-3923,1513468106063,100
-3924,1513468309558,99
-3925,1513468540486,98
-3926,1513468555603,98
-3927,1513468836316,110
-3928,1513468848869,109
-3929,1513469083296,127
-3930,1513469442582,126
-3931,1513469592109,124
-3932,1513469782513,123
-3933,1513469848082,122
-3934,1513470354152,124
-3935,1513470405524,122
-3936,1513470701278,125
-3937,1513470705135,122
-3938,1513470924348,196
-3939,1513470950871,194
-3940,1513471167110,207
-3941,1513471674134,205
-3942,1513471937985,202
-3943,1513472112346,199
-3944,1513472319017,197
-3945,1513473206830,196
-3946,1513473905743,191
-3947,1513474363693,187
-3948,1513474419300,184
-3949,1513474457703,187
-3950,1513474607603,194
-3951,1513474690343,193
-3952,1513474891594,194
-3953,1513475187411,191
-3954,1513475263159,188
-3955,1513475522704,189
-3956,1513475827653,185
-3957,1513475848340,182
-3958,1513476174003,198
-3959,1513477242186,194
-3960,1513477523606,189
-3961,1513477667036,185
-3962,1513477858833,183
-3963,1513477885225,180
-3964,1513477960439,191
-3965,1513477981306,191
-3966,1513478317859,208
-3967,1513478423102,203
-3968,1513478656264,202
-3969,1513479243739,198
-3970,1513479401200,192
-3971,1513479465444,189
-3972,1513479975093,190
-3973,1513480436976,184
-3974,1513480516035,178
-3975,1513480637672,178
-3976,1513480821637,175
-3977,1513480999697,171
-3978,1513481762149,166
-3979,1513481789510,161
-3980,1513482287076,168
-3981,1513483274511,162
-3982,1513484853875,156
-3983,1513484909325,149
-3984,1513485271335,149
-3985,1513485278548,143
-3986,1513485288127,184
-3987,1513485775343,223
-3988,1513485915909,216
-3989,1513486029167,211
-3990,1513486768868,207
-3991,1513487141229,199
-3992,1513487390791,193
-3993,1513487670246,187
-3994,1513488091605,181
-3995,1513488175459,174
-3996,1513488444653,172
-3997,1513488780117,166
-3998,1513489256141,163
-3999,1513490215447,156
-4000,1513491378086,151
-4001,1513491402145,144
-4002,1513491715027,152
-4003,1513491750054,147
-4004,1513492246468,149
-4005,1513492353824,148
-4006,1513492363093,145
-4007,1513492528561,174
-4008,1513492698530,168
-4009,1513493083653,162
-4010,1513493277326,155
-4011,1513493320474,148
-4012,1513493324335,153
-4013,1513493541870,239
-4014,1513494248693,231
-4015,1513494485425,221
-4016,1513494969878,215
-4017,1513495042080,207
-4018,1513495189956,207
-4019,1513495320996,201
-4020,1513495396653,206
-4021,1513495550963,206
-4022,1513495811979,201
-4023,1513496271566,195
-4024,1513496315478,186
-4025,1513496726955,187
-4026,1513496768168,178
-4027,1513496827090,186
-4028,1513496862533,184
-4029,1513497199194,197
-4030,1513497466586,190
-4031,1513497630476,182
-4032,1513497870406,174
-4033,1513497880077,167
-4034,1513499325707,201
-4035,1513499593927,191
-4036,1513499615392,184
-4037,1513499622099,195
-4038,1513499731890,292
-4039,1513499980632,289
-4040,1513500425234,290
-4041,1513501265285,283
-4042,1513501568057,273
-4043,1513501615982,265
-4044,1513501652925,269
-4045,1513503674421,277
-4046,1513504215439,266
-4047,1513505010739,256
-4048,1513505715614,247
-4049,1513506102546,241
-4050,1513506761764,237
-4051,1513507418211,229
-4052,1513507607934,222
-4053,1513508667541,215
-4054,1513508978299,205
-4055,1513509725974,199
-4056,1513511080480,190
-4057,1513511240636,181
-4058,1513511592989,184
-4059,1513512232994,176
-4060,1513513074939,165
-4061,1513513465836,156
-4062,1513513543774,149
-4063,1513513610111,144
-4064,1513513698121,147
-4065,1513514232031,145
-4066,1513515753089,146
-4067,1513515768282,138
-4068,1513515800630,152
-4069,1513515958758,154
-4070,1513516097556,147
-4071,1513516135997,140
-4072,1513516516025,143
-4073,1513516677221,134
-4074,1513516759681,126
-4075,1513516911619,122
-4076,1513516987154,116
-4077,1513517100177,110
-4078,1513517232216,104
-4079,1513517238994,96
-4080,1513517271384,127
-4081,1513517309056,126
-4082,1513517806770,124
-4083,1513517822415,113
-4084,1513518891021,123
-4085,1513519099138,113
-4086,1513519233020,128
-4087,1513519379221,144
-4088,1513519520949,137
-4089,1513519657098,132
-4090,1513519797670,127
-4091,1513519838719,120
-4092,1513519901736,118
-4093,1513519984889,114
-4094,1513520063722,108
-4095,1513520173215,102
-4096,1513520191389,97
-4097,1513520667032,100
-4098,1513520790632,92
-4099,1513521276893,85
-4100,1513521463856,75
-4101,1513521536254,66
-4102,1513521549152,66
-4103,1513521564303,70
-4104,1513521585378,75
-4105,1513521603988,74
-4106,1513521636067,76
-4107,1513521743662,91
-4108,1513521946244,84
-4109,1513522211975,77
-4110,1513522244136,68
-4111,1513522253541,65
-4112,1513522260678,76
-4113,1513522484266,141
-4114,1513522556939,136
-4115,1513523053721,131
-4116,1513523159046,125
-4117,1513523171795,119
-4118,1513523878147,136
-4119,1513524094224,129
-4120,1513524114953,123
-4121,1513524208276,132
-4122,1513524420393,128
-4123,1513524699232,122
-4124,1513524762954,114
-4125,1513524951816,114
-4126,1513525064646,108
-4127,1513525294884,106
-4128,1513525346720,102
-4129,1513525361857,105
-4130,1513525391995,114
-4131,1513525509335,115
-4132,1513525550880,110
-4133,1513525645054,108
-4134,1513525794302,123
-4135,1513525960827,117
-4136,1513526012319,111
-4137,1513526119804,118
-4138,1513526165887,149
-4139,1513526983793,153
-4140,1513527013852,147
-4141,1513527237079,153
-4142,1513527358234,147
-4143,1513527466467,144
-4144,1513527553040,147
-4145,1513527582761,152
-4146,1513527690893,157
-4147,1513527939526,154
-4148,1513528025589,150
-4149,1513528269404,147
-4150,1513528553612,142
-4151,1513528660020,136
-4152,1513528956659,132
-4153,1513529011290,127
-4154,1513529159272,125
-4155,1513529419222,121
-4156,1513529640756,115
-4157,1513529899209,109
-4158,1513530085409,104
-4159,1513530387590,99
-4160,1513530796682,92
-4161,1513531369310,85
-4162,1513531430412,79
-4163,1513531466782,77
-4164,1513531555762,77
-4165,1513531645900,74
-4166,1513531649684,70
-4167,1513531802827,107
-4168,1513531856683,112
-4169,1513532106151,115
-4170,1513532479197,109
-4171,1513532488888,103
-4172,1513532509644,126
-4173,1513532705069,133
-4174,1513532739761,128
-4175,1513532877634,131
-4176,1513533093309,125
-4177,1513533131203,121
-4178,1513533189417,122
-4179,1513533775058,119
-4180,1513533833802,130
-4181,1513533915502,132
-4182,1513534045908,132
-4183,1513534236598,128
-4184,1513534304437,131
-4185,1513534621383,128
-4186,1513534654326,122
-4187,1513535082047,124
-4188,1513535234491,119
-4189,1513535338566,114
-4190,1513535379216,111
-4191,1513535691148,111
-4192,1513536120627,108
-4193,1513536369916,104
-4194,1513536394276,99
-4195,1513536475441,103
-4196,1513536569181,99
-4197,1513536586850,101
-4198,1513536591047,107
-4199,1513536839764,162
-4200,1513537073737,156
-4201,1513537724082,149
-4202,1513537877262,143
-4203,1513538299282,142
-4204,1513538334186,141
-4205,1513538855367,147
-4206,1513539074592,144
-4207,1513539125026,141
-4208,1513539438518,140
-4209,1513539810906,134
-4210,1513540123798,128
-4211,1513540141712,123
-4212,1513540377117,140
-4213,1513540440570,146
-4214,1513540697557,146
-4215,1513540983584,142
-4216,1513541734669,135
-4217,1513541858249,130
-4218,1513541973184,136
-4219,1513542010868,132
-4220,1513542028791,133
-4221,1513542110144,151
-4222,1513542176808,150
-4223,1513542354051,148
-4224,1513542380752,144
-4225,1513542433418,151
-4226,1513542465452,151
-4227,1513542908833,157
-4228,1513542978827,150
-4229,1513543417058,149
-4230,1513543449033,151
-4231,1513543671993,159
-4232,1513544247077,155
-4233,1513544415688,151
-4234,1513544644661,147
-4235,1513544672029,141
-4236,1513544779532,147
-4237,1513544836635,145
-4238,1513544843458,145
-4239,1513545152586,193
-4240,1513545303138,186
-4241,1513545412493,186
-4242,1513545613661,183
-4243,1513545779109,178
-4244,1513545942755,174
-4245,1513546146602,170
-4246,1513546826275,170
-4247,1513547178603,165
-4248,1513547346792,159
-4249,1513547507685,154
-4250,1513547512044,149
-4251,1513547516519,224
-4252,1513548231531,336
-4253,1513548985057,327
-4254,1513550084018,319
-4255,1513550812850,310
-4256,1513551057676,301
-4257,1513551495832,294
-4258,1513551534260,285
-4259,1513551710397,293
-4260,1513552081492,285
-4261,1513553441660,276
-4262,1513553579082,265
-4263,1513553594748,260
-4264,1513554237749,292
-4265,1513554392613,281
-4266,1513554910560,275
-4267,1513555166384,287
-4268,1513555454469,279
-4269,1513555584220,273
-4270,1513556744353,267
-4271,1513556774138,257
-4272,1513556813536,280
-4273,1513556927551,293
-4274,1513557381809,289
-4275,1513557775169,284
-4276,1513557813001,275
-4277,1513558548479,282
-4278,1513558585888,275
-4279,1513558797101,284
-4280,1513558852599,276
-4281,1513559333693,279
-4282,1513559670653,271
-4283,1513560011314,263
-4284,1513560090856,253
-4285,1513560242418,252
-4286,1513560249537,244
-4287,1513560598485,320
-4288,1513560937390,310
-4289,1513561209800,300
-4290,1513561305620,291
-4291,1513561796612,289
-4292,1513562306607,278
-4293,1513562608259,266
-4294,1513563099492,256
-4295,1513565003897,249
-4296,1513565159061,239
-4297,1513565415799,230
-4298,1513565765647,227
-4299,1513566201975,247
-4300,1513566251114,238
-4301,1513566338171,239
-4302,1513567108220,234
-4303,1513567979177,223
-4304,1513570039151,213
-4305,1513570100278,206
-4306,1513570320389,203
-4307,1513570966341,194
-4308,1513571621713,186
-4309,1513571677612,175
-4310,1513572348721,172
-4311,1513573070211,161
-4312,1513573497655,158
-4313,1513573615645,148
-4314,1513574248793,142
-4315,1513574382793,132
-4316,1513574484372,124
-4317,1513574696663,115
-4318,1513574731174,105
-4319,1513574761166,103
-4320,1513574819100,104
-4321,1513574990472,105
-4322,1513575083636,97
-4323,1513575110703,92
-4324,1513575142986,89
-4325,1513575155225,91
-4326,1513575287317,101
-4327,1513575412199,97
-4328,1513575469118,88
-4329,1513575700995,83
-4330,1513575871581,73
-4331,1513576297183,69
-4332,1513576309717,58
-4333,1513576465139,58
-4334,1513576582405,49
-4335,1513576646631,39
-4336,1513576682265,36
-4337,1513576868247,28
-4338,1513576895384,21
-4339,1513576929123,38
-4340,1513577010376,31
-4341,1513577036862,24
-4342,1513577075095,18
-4343,1513577090632,10
-4344,1513577109621,2
-4345,1513577122155,1
-4346,1513577126261,1
-4347,1513577130053,1
-4348,1513577137390,1
-4349,1513577141212,1
-4350,1513577145289,1
-4351,1513577149193,1
-4352,1513577152927,35
-4353,1513577159532,51
-4354,1513577296442,62
-4355,1513577380406,56
-4356,1513577395402,50
-4357,1513577539437,52
-4358,1513577571672,47
-4359,1513577635153,52
-4360,1513577945433,48
-4361,1513577980564,42
-4362,1513578046383,37
-4363,1513578056343,33
-4364,1513578060133,54
-4365,1513578123861,82
-4366,1513578160254,79
-4367,1513578265341,78
-4368,1513578302761,74
-4369,1513578333841,73
-4370,1513578494845,72
-4371,1513578501893,66
-4372,1513578818355,92
-4373,1513578859487,94
-4374,1513578998358,95
-4375,1513579113656,90
-4376,1513579157591,85
-4377,1513579310597,92
-4378,1513579366468,87
-4379,1513579405013,92
-4380,1513579746771,92
-4381,1513579765245,92
-4382,1513579830841,98
-4383,1513579969142,95
-4384,1513580113044,91
-4385,1513580269989,90
-4386,1513580361811,86
-4387,1513580638483,124
-4388,1513580792360,120
-4389,1513580843484,117
-4390,1513580903864,119
-4391,1513581007226,122
-4392,1513581146475,120
-4393,1513581557376,116
-4394,1513581595296,113
-4395,1513581725223,115
-4396,1513581782246,111
-4397,1513581818084,112
-4398,1513582221221,115
-4399,1513582276360,111
-4400,1513582401718,110
-4401,1513582405924,113
-4402,1513582460944,174
-4403,1513582798738,176
-4404,1513583172413,170
-4405,1513583182148,165
-4406,1513583427149,203
-4407,1513583690312,199
-4408,1513584828099,194
-4409,1513585129078,187
-4410,1513586006857,185
-4411,1513586503970,178
-4412,1513586544616,173
-4413,1513586594702,176
-4414,1513586719492,179
-4415,1513587418115,175
-4416,1513588458489,170
-4417,1513588633149,164
-4418,1513588707569,160
-4419,1513589039213,161
-4420,1513589305695,159
-4421,1513589520883,156
-4422,1513589959312,151
-4423,1513590441892,145
-4424,1513590957544,143
-4425,1513590973761,140
-4426,1513591276427,163
-4427,1513591555675,158
-4428,1513591783085,154
-4429,1513592028833,151
-4430,1513592247071,145
-4431,1513592287266,140
-4432,1513592446766,141
-4433,1513592585600,142
-4434,1513592590058,138
-4435,1513593220280,206
-4436,1513593387148,199
-4437,1513593835206,195
-4438,1513593926188,189
-4439,1513594375954,187
-4440,1513594402440,180
-4441,1513595157503,189
-4442,1513595306560,183
-4443,1513595433407,178
-4444,1513595453826,173
-4445,1513595644420,185
-4446,1513595994250,179
-4447,1513596082750,171
-4448,1513596154907,168
-4449,1513596233941,165
-4450,1513596678368,161
-4451,1513596969683,154
-4452,1513597770660,146
-4453,1513598119340,149
-4454,1513598491787,151
-4455,1513598751146,144
-4456,1513598962557,138
-4457,1513599081613,135
-4458,1513599209880,130
-4459,1513599296481,126
-4460,1513599429535,122
-4461,1513599722582,116
-4462,1513600102696,110
-4463,1513600121062,103
-4464,1513600370055,112
-4465,1513600513258,123
-4466,1513600743716,118
-4467,1513600786411,114
-4468,1513600947346,114
-4469,1513601058097,110
-4470,1513601087876,107
-4471,1513601184629,109
-4472,1513601635725,115
-4473,1513601639974,109
-4474,1513602239468,165
-4475,1513602402521,158
-4476,1513602580317,153
-4477,1513603229715,149
-4478,1513603379774,142
-4479,1513603655568,137
-4480,1513603710138,133
-4481,1513603943958,132
-4482,1513604908467,131
-4483,1513604957972,125
-4484,1513605025430,123
-4485,1513605033091,121
-4486,1513605936815,151
-4487,1513606123718,143
-4488,1513606456182,137
-4489,1513606889718,130
-4490,1513606896658,125
-4491,1513607046998,162
-4492,1513607256115,157
-4493,1513607259952,150
-4494,1513607479566,234
-4495,1513607720380,230
-4496,1513608389209,223
-4497,1513608687169,216
-4498,1513608697479,211
-4499,1513608781931,249
-4500,1513611020184,248
-4501,1513613280540,238
-4502,1513613317520,260
-4503,1513613425187,271
-4504,1513613829733,267
-4505,1513614241187,258
-4506,1513614467796,271
-4507,1513616437274,264
-4508,1513617414741,256
-4509,1513617571018,246
-4510,1513617609094,241
-4511,1513617900810,247
-4512,1513618634765,239
-4513,1513618951122,235
-4514,1513619222155,231
-4515,1513619583581,225
-4516,1513620249561,217
-4517,1513620788480,208
-4518,1513621499281,200
-4519,1513621673381,193
-4520,1513622478645,187
-4521,1513622506244,179
-4522,1513622627193,184
-4523,1513622665129,179
-4524,1513622682416,180
-4525,1513623135714,195
-4526,1513623224138,197
-4527,1513623492511,192
-4528,1513623835957,184
-4529,1513623941172,175
-4530,1513623948509,170
-4531,1513623980721,216
-4532,1513624259555,225
-4533,1513624279094,217
-4534,1513624419197,234
-4535,1513625203865,264
-4536,1513625735831,254
-4537,1513626736946,247
-4538,1513627390564,237
-4539,1513627444794,230
-4540,1513628026176,229
-4541,1513628272808,228
-4542,1513628315851,221
-4543,1513628948572,224
-4544,1513629377724,215
-4545,1513629701761,217
-4546,1513630238089,210
-4547,1513630738488,201
-4548,1513630955024,194
-4549,1513631062416,188
-4550,1513631349671,185
-4551,1513631557000,177
-4552,1513631644821,168
-4553,1513631746467,164
-4554,1513631790874,158
-4555,1513631827064,157
-4556,1513631843296,157
-4557,1513632154430,171
-4558,1513632890926,163
-4559,1513633054721,154
-4560,1513633131117,147
-4561,1513633523262,142
-4562,1513633641887,132
-4563,1513634119334,124
-4564,1513634174666,120
-4565,1513634346083,116
-4566,1513634592524,108
-4567,1513634742028,99
-4568,1513634776960,93
-4569,1513634944623,90
-4570,1513635190572,82
-4571,1513635234601,76
-4572,1513635288890,70
-4573,1513635326875,64
-4574,1513635457181,89
-4575,1513635789413,81
-4576,1513635826619,73
-4577,1513635882022,68
-4578,1513636132371,62
-4579,1513636174649,54
-4580,1513636178726,47
-4581,1513636238463,69
-4582,1513636370755,62
-4583,1513636526897,53
-4584,1513636571091,47
-4585,1513636676599,41
-4586,1513636857248,52
-4587,1513636868904,43
-4588,1513636961315,44
-4589,1513637191330,35
-4590,1513637195542,26
-4591,1513637237997,53
-4592,1513637247998,49
-4593,1513637282253,52
-4594,1513637355337,95
-4595,1513637372981,91
-4596,1513637903388,96
-4597,1513638486542,89
-4598,1513638519056,82
-4599,1513638646053,106
-4600,1513638659444,104
-4601,1513638731425,115
-4602,1513638910413,111
-4603,1513638957824,114
-4604,1513639008440,115
-4605,1513639026880,114
-4606,1513639120695,121
-4607,1513639168402,118
-4608,1513639462683,116
-4609,1513639498772,110
-4610,1513639878495,112
-4611,1513640151494,112
-4612,1513640322034,107
-4613,1513640329286,100
-4614,1513640337389,126
-4615,1513640717575,156
-4616,1513640750626,150
-4617,1513641082499,152
-4618,1513641087227,145
-4619,1513641696123,210
-4620,1513641703034,203
-4621,1513642165109,263
-4622,1513642728677,262
-4623,1513643090615,254
-4624,1513643484205,251
-4625,1513643810117,255
-4626,1513644546330,246
-4627,1513644679520,240
-4628,1513644720170,235
-4629,1513645020704,239
-4630,1513645292949,232
-4631,1513645684403,253
-4632,1513645787683,253
-4633,1513646097418,251
-4634,1513646397892,257
-4635,1513646517216,251
-4636,1513648945124,248
-4637,1513649324252,240
-4638,1513650240109,233
-4639,1513651198332,225
-4640,1513651393456,221
-4641,1513651516066,215
-4642,1513651573321,212
-4643,1513651762752,218
-4644,1513651873514,212
-4645,1513652327367,209
-4646,1513653462546,201
-4647,1513654656469,194
-4648,1513654660579,185
-4649,1513654838346,285
-4650,1513655808168,281
-4651,1513657434610,271
-4652,1513659315699,263
-4653,1513659651673,255
-4654,1513659722837,248
-4655,1513659755918,250
-4656,1513659764669,264
-4657,1513660251659,337
-4658,1513660576580,329
-4659,1513660911132,320
-4660,1513661915457,312
-4661,1513662693345,304
-4662,1513663538626,294
-4663,1513664381462,284
-4664,1513665309701,274
-4665,1513666351762,267
-4666,1513667903916,256
-4667,1513669024212,247
-4668,1513669538828,237
-4669,1513672993952,230
-4670,1513676368579,219
-4671,1513677089129,209
-4672,1513677193627,200
-4673,1513677862307,196
-4674,1513677964948,187
-4675,1513678246075,181
-4676,1513680357915,173
-4677,1513680560416,164
-4678,1513681176971,157
-4679,1513681443798,147
-4680,1513681451014,138
-4681,1513681928624,188
-4682,1513682458669,179
-4683,1513682480998,170
-4684,1513682568067,177
-4685,1513682623064,171
-4686,1513682708909,168
-4687,1513682833806,161
-4688,1513683533923,157
-4689,1513683595293,147
-4690,1513683792308,142
-4691,1513683918041,139
-4692,1513684264303,131
-4693,1513684285255,128
-4694,1513684630510,133
-4695,1513684735861,124
-4696,1513684914674,122
-4697,1513685102211,112
-4698,1513685265072,103
-4699,1513685400475,96
-4700,1513685498513,87
-4701,1513685854637,88
-4702,1513686133768,80
-4703,1513686149927,70
-4704,1513686208873,72
-4705,1513686417792,67
-4706,1513686519839,64
-4707,1513686735658,58
-4708,1513686796385,50
-4709,1513686809974,42
-4710,1513686838696,42
-4711,1513687034147,36
-4712,1513687069096,26
-4713,1513687134677,18
-4714,1513687139463,25
-4715,1513687207546,47
-4716,1513687284150,39
-4717,1513687378716,36
-4718,1513687490202,28
-4719,1513687626323,57
-4720,1513687683258,50
-4721,1513687717521,80
-4722,1513687783756,79
-4723,1513688300913,74
-4724,1513688787983,67
-4725,1513688812514,61
-4726,1513689017608,61
-4727,1513689226010,55
-4728,1513689239401,49
-4729,1513689311008,58
-4730,1513689422352,53
-4731,1513689426509,48
-4732,1513689460993,69
-4733,1513689728503,69
-4734,1513689780419,62
-4735,1513690024093,58
-4736,1513690144279,54
-4737,1513690259657,47
-4738,1513690279945,41
-4739,1513690372641,39
-4740,1513690471363,33
-4741,1513690566740,27
-4742,1513690679584,22
-4743,1513690792135,19
-4744,1513690812198,13
-4745,1513690822260,10
-4746,1513690829810,5
-4747,1513690858828,1
-4748,1513690862908,1
-4749,1513690867048,40
-4750,1513690870966,60
-4751,1513690972092,90
-4752,1513691015690,85
-4753,1513691022768,84
-4754,1513691036035,107
-4755,1513691058729,122
-4756,1513691065951,137
-4757,1513691446170,213
-4758,1513691557250,208
-4759,1513691761293,207
-4760,1513691861554,203
-4761,1513692346059,201
-4762,1513692393621,196
-4763,1513692479282,199
-4764,1513692840782,198
-4765,1513693258910,192
-4766,1513693357534,186
-4767,1513694089096,184
-4768,1513694471503,177
-4769,1513694869972,172
-4770,1513695267855,165
-4771,1513695354950,159
-4772,1513695400377,156
-4773,1513695454999,159
-4774,1513696039181,159
-4775,1513696673083,154
-4776,1513696792829,149
-4777,1513696924268,144
-4778,1513697191809,140
-4779,1513697541434,134
-4780,1513697662758,128
-4781,1513697887557,147
-4782,1513698009181,142
-4783,1513698198510,138
-4784,1513698360352,142
-4785,1513698490974,140
-4786,1513698658553,140
-4787,1513698662659,138
-4788,1513698946692,213
-4789,1513698950652,207
-4790,1513699058493,328
-4791,1513699445934,327
-4792,1513699732264,321
-4793,1513699936690,315
-4794,1513700300752,316
-4795,1513700605881,309
-4796,1513700653422,303
-4797,1513700874350,309
-4798,1513701122154,304
-4799,1513701556880,298
-4800,1513701791452,291
-4801,1513702138919,285
-4802,1513703446865,278
-4803,1513703564925,269
-4804,1513704139731,270
-4805,1513704869373,263
-4806,1513705813976,254
-4807,1513706066029,246
-4808,1513706195308,239
-4809,1513706567207,234
-4810,1513706589724,230
-4811,1513706889315,247
-4812,1513707139314,240
-4813,1513707458695,232
-4814,1513707573955,225
-4815,1513707706537,226
-4816,1513707875299,221
-4817,1513708302408,214
-4818,1513708402846,207
-4819,1513708701115,201
-4820,1513708932364,194
-4821,1513709734200,186
-4822,1513709996301,179
-4823,1513710196824,173
-4824,1513710622030,164
-4825,1513710829471,156
-4826,1513711262955,151
-4827,1513711279936,143
-4828,1513711396818,153
-4829,1513711730920,151
-4830,1513711889798,142
-4831,1513711900035,135
-4832,1513712046491,171
-4833,1513712191801,166
-4834,1513712575603,159
-4835,1513712619258,151
-4836,1513713046816,149
-4837,1513713147957,141
-4838,1513713206475,134
-4839,1513713345195,131
-4840,1513713492162,124
-4841,1513713992282,116
-4842,1513714432353,107
-4843,1513714707223,97
-4844,1513714844147,88
-4845,1513715103562,80
-4846,1513715456580,71
-4847,1513715526124,63
-4848,1513715567022,54
-4849,1513715595671,47
-4850,1513715691827,53
-4851,1513715794492,63
-4852,1513715894655,56
-4853,1513715975988,50
-4854,1513716088692,56
-4855,1513716228488,58
-4856,1513716298544,58
-4857,1513716329077,74
-4858,1513716368082,73
-4859,1513716382509,71
-4860,1513716401789,76
-4861,1513716464083,80
-4862,1513716516632,76
-4863,1513716775260,76
-4864,1513717027185,71
-4865,1513717082497,64
-4866,1513717187896,60
-4867,1513717270863,55
-4868,1513717407503,48
-4869,1513717451004,42
-4870,1513717506001,37
-4871,1513717513792,31
-4872,1513717528402,35
-4873,1513717597710,37
-4874,1513717669266,33
-4875,1513717731575,26
-4876,1513717751873,19
-4877,1513717765128,16
-4878,1513717775959,12
-4879,1513717801910,6
-4880,1513717831273,1
-4881,1513717836331,1
-4882,1513717844511,1
-4883,1513717848573,1
-4884,1513717852727,1
-4885,1513717857185,1
-4886,1513717861303,1
-4887,1513717865396,1
-4888,1513717869707,1
-4889,1513717873745,1
-4890,1513717877867,42
-4891,1513717943249,65
-4892,1513718016554,63
-4893,1513718174180,62
-4894,1513718209444,59
-4895,1513718225210,60
-4896,1513718279918,64
-4897,1513718338975,70
-4898,1513718452984,70
-4899,1513718526914,68
-4900,1513718613320,66
-4901,1513718689140,65
-4902,1513718841259,62
-4903,1513719019560,59
-4904,1513719104893,57
-4905,1513719357271,55
-4906,1513719376905,51
-4907,1513719472086,53
-4908,1513719476739,50
-4909,1513719613562,73
-4910,1513719690195,70
-4911,1513719717239,79
-4912,1513719861137,81
-4913,1513719993869,80
-4914,1513720097144,78
-4915,1513720131817,77
-4916,1513720165053,79
-4917,1513720257630,81
-4918,1513720382093,80
-4919,1513720701929,79
-4920,1513720958285,76
-4921,1513721098517,72
-4922,1513721145075,68
-4923,1513721277985,67
-4924,1513721368178,65
-4925,1513721372643,62
-4926,1513721495294,91
-4927,1513721569417,89
-4928,1513721974425,96
-4929,1513722122224,93
-4930,1513722188701,90
-4931,1513722399533,89
-4932,1513722687421,102
-4933,1513722844976,100
-4934,1513722968697,97
-4935,1513722985115,95
-4936,1513723060758,108
-4937,1513723141014,107
-4938,1513723333449,108
-4939,1513723813684,107
-4940,1513723831612,105
-4941,1513724033802,115
-4942,1513724325840,111
-4943,1513724329888,108
-4944,1513724342745,168
-4945,1513724734639,193
-4946,1513724922184,189
-4947,1513725351804,185
-4948,1513725850027,181
-4949,1513725902749,177
-4950,1513725969960,181
-4951,1513726088740,182
-4952,1513726559663,180
-4953,1513726787074,175
-4954,1513726857962,171
-4955,1513727033064,171
-4956,1513727061660,167
-4957,1513727457578,176
-4958,1513727517225,173
-4959,1513727761934,175
-4960,1513727835387,176
-4961,1513728073082,181
-4962,1513728429240,177
-4963,1513728645048,174
-4964,1513728821639,170
-4965,1513729297890,166
-4966,1513729317123,161
-4967,1513729572925,176
-4968,1513729592825,172
-4969,1513729996971,186
-4970,1513730061345,181
-4971,1513730373310,182
-4972,1513731002885,181
-4973,1513731177166,178
-4974,1513731304383,174
-4975,1513731350428,171
-4976,1513731399815,174
-4977,1513731805482,176
-4978,1513731889872,171
-4979,1513732527357,170
-4980,1513732699025,164
-4981,1513732909092,160
-4982,1513733004162,154
-4983,1513733133468,151
-4984,1513733330724,147
-4985,1513733600967,142
-4986,1513733880228,135
-4987,1513734074355,130
-4988,1513734088119,124
-4989,1513734279146,139
-4990,1513734354249,133
-4991,1513734729876,143
-4992,1513735139481,137
-4993,1513735374033,132
-4994,1513735411845,126
-4995,1513735572520,129
-4996,1513735935628,128
-4997,1513736036835,123
-4998,1513736273940,120
-4999,1513736457743,114
-5000,1513736545281,111
-5001,1513736658808,107
-5002,1513736726193,103
-5003,1513736869967,100
-5004,1513736909036,94
-5005,1513737029962,94
-5006,1513737136261,88
-5007,1513737255101,86
-5008,1513737376040,81
-5009,1513737490019,89
-5010,1513737724609,84
-5011,1513737777037,80
-5012,1513738369956,80
-5013,1513738424176,74
-5014,1513738459455,71
-5015,1513738698217,69
-5016,1513738838710,66
-5017,1513738879887,63
-5018,1513738944623,60
-5019,1513739055405,56
-5020,1513739214822,52
-5021,1513739478827,46
-5022,1513739489364,40
-5023,1513739563386,44
-5024,1513739604012,39
-5025,1513739683477,35
-5026,1513739738781,47
-5027,1513740044286,42
-5028,1513740124299,39
-5029,1513740150438,33
-5030,1513740169484,31
-5031,1513740299372,29
-5032,1513740357286,24
-5033,1513740504572,19
-5034,1513740512320,14
-5035,1513740516494,13
-5036,1513740575989,20
-5037,1513740586051,17
-5038,1513740593417,16
-5039,1513740603379,15
-5040,1513740613270,13
-5041,1513740617522,17
-5042,1513740661982,21
-5043,1513740669144,16
-5044,1513740713530,48
-5045,1513740968730,61
-5046,1513741075268,57
-5047,1513741168130,55
-5048,1513741291460,51
-5049,1513741599936,47
-5050,1513741719425,46
-5051,1513741755351,46
-5052,1513741954878,46
-5053,1513741983141,42
-5054,1513742151027,42
-5055,1513742179265,40
-5056,1513742287556,40
-5057,1513742378680,43
-5058,1513742456303,40
-5059,1513742535933,41
-5060,1513742543144,38
-5061,1513742601276,49
-5062,1513742852247,47
-5063,1513742973872,44
-5064,1513742989334,40
-5065,1513743163791,43
-5066,1513743363905,40
-5067,1513743398574,46
-5068,1513743429880,45
-5069,1513743454549,55
-5070,1513743459240,57
-5071,1513743609458,85
-5072,1513743656131,83
-5073,1513743696844,83
-5074,1513743780190,85
-5075,1513743845753,84
-5076,1513743971530,87
-5077,1513744001869,88
-5078,1513744140642,92
-5079,1513744413093,91
-5080,1513744445106,88
-5081,1513744514423,90
-5082,1513744703580,90
-5083,1513744860008,89
-5084,1513745212544,87
-5085,1513745473303,84
-5086,1513745515747,81
-5087,1513745538212,82
-5088,1513745856574,87
-5089,1513745930821,94
-5090,1513746186290,93
-5091,1513746689980,92
-5092,1513746819826,88
-5093,1513746919180,86
-5094,1513746926919,84
-5095,1513747049414,110
-5096,1513747318084,109
-5097,1513747755515,106
-5098,1513748086688,103
-5099,1513748096885,100
-5100,1513748323946,120
-5101,1513748451623,117
-5102,1513748534190,116
-5103,1513748639527,116
-5104,1513748708172,115
-5105,1513748821386,117
-5106,1513749005847,116
-5107,1513749030895,114
-5108,1513749164521,120
-5109,1513749189724,118
-5110,1513749491799,126
-5111,1513749715624,122
-5112,1513750042242,120
-5113,1513750058824,115
-5114,1513750172441,128
-5115,1513750262965,129
-5116,1513750501842,127
-5117,1513750748035,124
-5118,1513750927584,122
-5119,1513750947015,119
-5120,1513751423512,129
-5121,1513751484181,124
-5122,1513751527590,124
-5123,1513751577757,130
-5124,1513751731047,132
-5125,1513752342241,129
-5126,1513752775033,125
-5127,1513752912632,121
-5128,1513753230787,117
-5129,1513753408655,113
-5130,1513753452423,111
-5131,1513753769460,113
-5132,1513754450237,109
-5133,1513754730189,104
-5134,1513755266954,100
-5135,1513755424545,97
-5136,1513755734163,96
-5137,1513756109092,92
-5138,1513756370268,88
-5139,1513756382928,87
-5140,1513756433641,101
-5141,1513756594006,101
-5142,1513756929523,102
-5143,1513757016382,98
-5144,1513757410626,98
-5145,1513757692582,94
-5146,1513757721245,90
-5147,1513757743983,93
-5148,1513757936736,98
-5149,1513758014591,94
-5150,1513758209520,92
-5151,1513758510660,87
-5152,1513758659344,84
-5153,1513758803373,81
-5154,1513758847669,78
-5155,1513758931209,77
-5156,1513759027582,76
-5157,1513759036125,72
-5158,1513759075144,87
-5159,1513759234889,87
-5160,1513759446963,83
-5161,1513759589974,85
-5162,1513759815630,82
-5163,1513760124705,76
-5164,1513760234911,72
-5165,1513760368573,71
-5166,1513760419002,67
-5167,1513760453727,64
-5168,1513760526953,64
-5169,1513760721293,63
-5170,1513760765867,60
-5171,1513760819334,73
-5172,1513760861533,71
-5173,1513761002629,72
-5174,1513761236973,70
-5175,1513761406890,68
-5176,1513761634555,65
-5177,1513761645067,61
-5178,1513761689204,73
-5179,1513761802073,72
-5180,1513761910621,69
-5181,1513762247747,69
-5182,1513762269282,66
-5183,1513762435483,69
-5184,1513762462265,64
-5185,1513762478821,66
-5186,1513762620362,70
-5187,1513762844327,68
-5188,1513762925054,67
-5189,1513763009637,65
-5190,1513763052870,63
-5191,1513763087630,62
-5192,1513763137378,60
-5193,1513763256364,59
-5194,1513763285323,56
-5195,1513763289765,68
-5196,1513763348157,100
-5197,1513763484864,100
-5198,1513763550222,96
-5199,1513763741974,94
-5200,1513763749337,102
-5201,1513763753889,131
-5202,1513764208678,194
-5203,1513764415033,190
-5204,1513764637166,187
-5205,1513764698572,184
-5206,1513765354866,185
-5207,1513765424652,180
-5208,1513765828852,185
-5209,1513765872193,180
-5210,1513766395446,189
-5211,1513766636531,184
-5212,1513766841351,180
-5213,1513766878540,175
-5214,1513767029327,188
-5215,1513767059087,186
-5216,1513767501281,196
-5217,1513767923107,191
-5218,1513768038929,186
-5219,1513768391467,183
-5220,1513768626246,185
-5221,1513768752018,181
-5222,1513768816200,180
-5223,1513769430743,183
-5224,1513769715636,180
-5225,1513770352980,176
-5226,1513770644259,171
-5227,1513770651473,165
-5228,1513770710872,214
-5229,1513771193483,216
-5230,1513771253228,210
-5231,1513771387215,214
-5232,1513771410657,211
-5233,1513771832610,225
-5234,1513772997012,218
-5235,1513773047028,212
-5236,1513773408290,215
-5237,1513773856680,208
-5238,1513774618825,201
-5239,1513774644971,194
-5240,1513774968300,212
-5241,1513775421455,208
-5242,1513775557128,202
-5243,1513775653622,198
-5244,1513775971564,196
-5245,1513776163781,190
-5246,1513776745722,184
-5247,1513777146785,180
-5248,1513777228104,178
-5249,1513777740344,176
-5250,1513777769146,171
-5251,1513778246755,178
-5252,1513778827183,170
-5253,1513779101647,163
-5254,1513779198437,157
-5255,1513779286055,156
-5256,1513779335416,152
-5257,1513779597489,153
-5258,1513779793856,156
-5259,1513780518581,152
-5260,1513780865826,146
-5261,1513780969687,140
-5262,1513781108498,135
-5263,1513781627272,130
-5264,1513782016751,123
-5265,1513782501777,116
-5266,1513782634127,110
-5267,1513782668647,106
-5268,1513782826441,107
-5269,1513782967882,101
-5270,1513783154183,96
-5271,1513783235822,90
-5272,1513783474297,87
-5273,1513783497424,82
-5274,1513783676419,83
-5275,1513783942935,76
-5276,1513784169295,69
-5277,1513784604004,63
-5278,1513784655570,62
-5279,1513784714534,58
-5280,1513784859310,55
-5281,1513785164986,48
-5282,1513785189108,41
-5283,1513785256533,40
-5284,1513785264247,35
-5285,1513785426597,41
-5286,1513785597538,39
-5287,1513785624043,32
-5288,1513785672817,27
-5289,1513785714378,22
-5290,1513785752437,17
-5291,1513785821372,12
-5292,1513785864737,7
-5293,1513785875756,1
-5294,1513785900073,1
-5295,1513785912224,1
-5296,1513785920400,1
-5297,1513785929166,1
-5298,1513785937485,1
-5299,1513785946187,1
-5300,1513785960821,1
-5301,1513785968939,1
-5302,1513785977719,20
-5303,1513786074475,20
-5304,1513786088036,16
-5305,1513786129421,15
-5306,1513786140466,14
-5307,1513786154797,12
-5308,1513786184127,12
-5309,1513786210919,9
-5310,1513786219511,9
-5311,1513786240097,7
-5312,1513786254417,4
-5313,1513786266504,1
-5314,1513786274018,2
-5315,1513786285537,1
-5316,1513786297031,1
-5317,1513786304962,1
-5318,1513786322824,1
-5319,1513786327972,1
-5320,1513786336402,1
-5321,1513786344909,1
-5322,1513786353371,1
-5323,1513786362202,1
-5324,1513786370433,1
-5325,1513786378452,1
-5326,1513786387159,1
-5327,1513786395420,1
-5328,1513786403652,1
-5329,1513786411794,1
-5330,1513786423228,1
-5331,1513786437125,1
-5332,1513786442479,1
-5333,1513786451410,1
-5334,1513786459696,1
-5335,1513786467621,1
-5336,1513786475680,1
-5337,1513786484353,1
-5338,1513786493184,1
-5339,1513786501249,1
-5340,1513786509611,1
-5341,1513786517900,1
-5342,1513786526428,1
-5343,1513786534633,1
-5344,1513786543338,1
-5345,1513786552078,1
-5346,1513786569491,1
-5347,1513786577476,1
-5348,1513786586136,1
-5349,1513786594831,1
-5350,1513786602905,1
-5351,1513786611112,1
-5352,1513786619054,1
-5353,1513786627821,1
-5354,1513786635632,1
-5355,1513786643928,1
-5356,1513786652391,1
-5357,1513786660830,1
-5358,1513786669267,1
-5359,1513786676996,1
-5360,1513786688039,1
-5361,1513786696438,1
-5362,1513786704538,1
-5363,1513786713042,1
-5364,1513786724380,1
-5365,1513786735423,1
-5366,1513786743785,1
-5367,1513786755913,1
-5368,1513786763811,1
-5369,1513786772099,1
-5370,1513786780479,1
-5371,1513786788764,1
-5372,1513786796976,1
-5373,1513786805092,1
-5374,1513786816717,1
-5375,1513786824813,1
-5376,1513786833206,1
-5377,1513786841373,1
-5378,1513786855602,1
-5379,1513786867311,1
-5380,1513786875814,1
-5381,1513786886432,1
-5382,1513786894547,1
-5383,1513786903173,1
-5384,1513786911764,1
-5385,1513786920426,1
-5386,1513786928587,1
-5387,1513786936955,1
-5388,1513786945363,1
-5389,1513786953225,1
-5390,1513786961610,2
-5391,1513786969924,2
-5392,1513786993369,2
-5393,1513787011158,2
-5394,1513787028310,2
-5395,1513787039625,1
-5396,1513787048057,1
-5397,1513787057456,1
-5398,1513787071477,1
-5399,1513787079497,1
-5400,1513787091570,1
-5401,1513787102907,1
-5402,1513787110996,1
-5403,1513787122358,1
-5404,1513787136971,1
-5405,1513787147955,2
-5406,1513787160172,2
-5407,1513787171664,4
-5408,1513787180042,5
-5409,1513787204252,7
-5410,1513787227773,7
-5411,1513787256878,9
-5412,1513787286455,10
-5413,1513787306881,10
-5414,1513787315635,11
-5415,1513787336880,13
-5416,1513787366084,14
-5417,1513787386219,16
-5418,1513787428389,16
-5419,1513787448949,17
-5420,1513787469419,19
-5421,1513787501940,20
-5422,1513787523284,21
-5423,1513787605559,24
-5424,1513787671704,24
-5425,1513787742136,23
-5426,1513787774612,24
-5427,1513787917960,25
-5428,1513787931926,25
-5429,1513787949003,28
-5430,1513787981497,32
-5431,1513788010971,34
-5432,1513788130052,35
-5433,1513788230794,36
-5434,1513788286958,35
-5435,1513788317900,36
-5436,1513788383497,38
-5437,1513788455769,39
-5438,1513788506011,39
-5439,1513788560580,40
-5440,1513788671720,41
-5441,1513788732704,41
-5442,1513788843914,41
-5443,1513788982655,42
-5444,1513789164320,41
-5445,1513789293538,41
-5446,1513789333075,40
-5447,1513789415509,42
-5448,1513789445359,42
-5449,1513789480757,44
-5450,1513789511321,47
-5451,1513789614317,49
-5452,1513789767772,49
-5453,1513789784143,48
-5454,1513789824869,55
-5455,1513789911542,56
-5456,1513790091200,56
-5457,1513790255459,55
-5458,1513790360117,55
-5459,1513790586965,55
-5460,1513790757827,54
-5461,1513790866015,53
-5462,1513791055932,54
-5463,1513791371787,53
-5464,1513791416959,51
-5465,1513791536188,53
-5466,1513791750419,53
-5467,1513791839531,51
-5468,1513791937480,52
-5469,1513792166470,51
-5470,1513792331605,50
-5471,1513792541352,49
-5472,1513792598826,49
-5473,1513792685144,49
-5474,1513792760706,49
-5475,1513792903606,49
-5476,1513793032499,48
-5477,1513793204937,47
-5478,1513793373042,47
-5479,1513793505751,46
-5480,1513793823044,44
-5481,1513794030718,43
-5482,1513794050881,42
-5483,1513794157942,45
-5484,1513794361704,44
-5485,1513794369218,44
-5486,1513794497512,56
-5487,1513794626504,54
-5488,1513794649831,54
-5489,1513794727650,58
-5490,1513794885405,58
-5491,1513794995796,57
-5492,1513795025748,56
-5493,1513795170546,58
-5494,1513795260513,57
-5495,1513795296554,57
-5496,1513795396085,57
-5497,1513795548065,57
-5498,1513795636670,56
-5499,1513795771089,55
-5500,1513795945982,53
-5501,1513796116369,52
-5502,1513796301688,51
-5503,1513796393314,48
-5504,1513796551580,48
-5505,1513796631319,46
-5506,1513796676155,45
-5507,1513796799416,45
-5508,1513796987440,44
-5509,1513797074043,43
-5510,1513797143958,42
-5511,1513797204137,41
-5512,1513797222782,40
-5513,1513797284215,43
-5514,1513797317662,43
-5515,1513797426941,45
-5516,1513797652330,45
-5517,1513797769272,43
-5518,1513797871449,42
-5519,1513797984207,41
-5520,1513798081179,40
-5521,1513798122638,39
-5522,1513798135860,40
-5523,1513798176066,46
-5524,1513798220080,46
-5525,1513798273619,47
-5526,1513798311303,47
-5527,1513798421859,48
-5528,1513798608166,47
-5529,1513798739611,46
-5530,1513798891787,47
-5531,1513799066271,46
-5532,1513799132395,45
-5533,1513799167207,45
-5534,1513799188235,46
-5535,1513799234204,49
-5536,1513799281869,51
-5537,1513799307050,51
-5538,1513799421370,54
-5539,1513799540117,54
-5540,1513799573119,53
-5541,1513799594572,54
-5542,1513799628213,59
-5543,1513799660217,60
-5544,1513799681808,62
-5545,1513799772802,67
-5546,1513799906236,66
-5547,1513800083534,64
-5548,1513800310521,63
-5549,1513800423134,62
-5550,1513800436874,63
-5551,1513800477214,72
-5552,1513800508660,74
-5553,1513800712162,77
-5554,1513800935461,78
-5555,1513801142135,78
-5556,1513801289267,76
-5557,1513801433589,75
-5558,1513801563988,73
-5559,1513801685948,73
-5560,1513801804455,72
-5561,1513802071296,70
-5562,1513802546141,68
-5563,1513802969688,66
-5564,1513803022315,64
-5565,1513803302209,65
-5566,1513803611050,63
-5567,1513803647647,60
-5568,1513803721287,62
-5569,1513803821670,62
-5570,1513803891431,60
-5571,1513803981572,59
-5572,1513804040650,58
-5573,1513804190796,58
-5574,1513804299739,57
-5575,1513804450929,56
-5576,1513804602963,54
-5577,1513804725358,52
-5578,1513804841450,50
-5579,1513804970002,48
-5580,1513805035007,46
-5581,1513805138113,45
-5582,1513805221862,43
-5583,1513805333315,43
-5584,1513805462467,42
-5585,1513805590131,40
-5586,1513805615699,45
-5587,1513805745631,46
-5588,1513805962447,45
-5589,1513806056271,45
-5590,1513806123035,44
-5591,1513806127741,43
-5592,1513806362307,63
-5593,1513806505519,63
-5594,1513806647607,61
-5595,1513806923951,60
-5596,1513807072391,59
-5597,1513807193369,57
-5598,1513807604914,56
-5599,1513808062062,54
-5600,1513808211211,52
-5601,1513808336780,50
-5602,1513808417380,48
-5603,1513808507573,47
-5604,1513808649654,46
-5605,1513808783737,44
-5606,1513808888398,42
-5607,1513808926926,41
-5608,1513809051388,41
-5609,1513809143866,39
-5610,1513809249011,38
-5611,1513809312810,37
-5612,1513809331150,35
-5613,1513809362171,40
-5614,1513809429826,41
-5615,1513809579289,40
-5616,1513809684024,38
-5617,1513809778129,37
-5618,1513809789293,35
-5619,1513809822403,40
-5620,1513809939455,40
-5621,1513810101015,38
-5622,1513810182528,36
-5623,1513810218915,38
-5624,1513810277923,38
-5625,1513810350705,38
-5626,1513810398983,37
-5627,1513810413512,38
-5628,1513810499827,41
-5629,1513810592054,40
-5630,1513810634599,39
-5631,1513810669556,38
-5632,1513810783566,37
-5633,1513810838065,37
-5634,1513810848259,36
-5635,1513810929479,44
-5636,1513811014303,43
-5637,1513811038012,43
-5638,1513811117474,47
-5639,1513811200685,46
-5640,1513811261995,45
-5641,1513811445887,45
-5642,1513811695073,45
-5643,1513811815446,45
-5644,1513811855105,45
-5645,1513811879354,48
-5646,1513811908773,51
-5647,1513811945445,53
-5648,1513811966543,54
-5649,1513812026955,57
-5650,1513812118343,57
-5651,1513812183127,62
-5652,1513812426940,63
-5653,1513812482293,63
-5654,1513812577256,64
-5655,1513812731024,63
-5656,1513812849110,62
-5657,1513812925717,60
-5658,1513813185877,60
-5659,1513813383936,58
-5660,1513813405934,57
-5661,1513813601472,62
-5662,1513813652838,60
-5663,1513813740248,59
-5664,1513813867572,59
-5665,1513813967828,58
-5666,1513814069154,57
-5667,1513814172895,55
-5668,1513814198215,55
-5669,1513814219132,59
-5670,1513814351557,63
-5671,1513814553651,62
-5672,1513814682774,61
-5673,1513814877664,60
-5674,1513815261643,58
-5675,1513815272192,56
-5676,1513815373842,67
-5677,1513815618108,66
-5678,1513815871931,64
-5679,1513815974134,61
-5680,1513816078970,60
-5681,1513816210315,59
-5682,1513816441786,57
-5683,1513816629876,55
-5684,1513816731079,53
-5685,1513816815375,52
-5686,1513816842962,50
-5687,1513816874719,53
-5688,1513816914483,55
-5689,1513816984157,55
-5690,1513817039499,55
-5691,1513817101910,54
-5692,1513817261800,64
-5693,1513817462705,63
-5694,1513817504294,61
-5695,1513817628566,61
-5696,1513817723877,60
-5697,1513817816403,59
-5698,1513817873108,58
-5699,1513817934428,57
-5700,1513817980296,57
-5701,1513818136111,57
-5702,1513818202257,56
-5703,1513818216596,55
-5704,1513818398119,62
-5705,1513818679517,59
-5706,1513818866099,57
-5707,1513819049726,55
-5708,1513819591099,54
-5709,1513819651732,51
-5710,1513819842330,50
-5711,1513820005911,48
-5712,1513820048441,46
-5713,1513820180330,47
-5714,1513820385380,47
-5715,1513820576191,45
-5716,1513820698792,42
-5717,1513820848112,41
-5718,1513820892454,39
-5719,1513820976630,42
-5720,1513821061215,41
-5721,1513821116379,40
-5722,1513821131476,38
-5723,1513821205794,42
-5724,1513821295283,41
-5725,1513821353264,40
-5726,1513821423821,40
-5727,1513821481672,39
-5728,1513821527658,40
-5729,1513821615552,40
-5730,1513821773054,38
-5731,1513821856787,37
-5732,1513821936246,36
-5733,1513822067855,34
-5734,1513822089020,33
-5735,1513822214938,38
-5736,1513822336680,36
-5737,1513822393114,35
-5738,1513822496662,35
-5739,1513822571307,34
-5740,1513822625978,33
-5741,1513822834154,33
-5742,1513823050261,31
-5743,1513823369038,28
-5744,1513823434304,26
-5745,1513823541652,26
-5746,1513823640278,25
-5747,1513823660762,26
-5748,1513823698641,27
-5749,1513823788229,30
-5750,1513823945938,29
-5751,1513823965646,28
-5752,1513823989704,29
-5753,1513823998309,31
-5754,1513824065859,38
-5755,1513824120835,37
-5756,1513824187778,37
-5757,1513824405875,35
-5758,1513824713748,34
-5759,1513824743740,32
-5760,1513824814832,32
-5761,1513824866727,33
-5762,1513824893458,33
-5763,1513825068133,34
-5764,1513825109820,33
-5765,1513825261078,33
-5766,1513825327835,31
-5767,1513825420281,30
-5768,1513825499467,29
-5769,1513825564696,30
-5770,1513825606567,32
-5771,1513825642291,32
-5772,1513825801760,32
-5773,1513825851091,30
-5774,1513825859124,30
-5775,1513825880638,37
-5776,1513825930764,44
-5777,1513825997222,45
-5778,1513826001947,44
-5779,1513826019804,64
-5780,1513826043986,71
-5781,1513826112681,76
-5782,1513826282233,76
-5783,1513826287102,74
-5784,1513826300205,108
-5785,1513826455060,124
-5786,1513826667456,123
-5787,1513826699993,123
-5788,1513826749006,130
-5789,1513826770682,133
-5790,1513827199758,145
-5791,1513827341761,143
-5792,1513827729945,143
-5793,1513828418238,139
-5794,1513828738200,137
-5795,1513828866287,135
-5796,1513828888717,135
-5797,1513829109489,145
-5798,1513829568739,143
-5799,1513829892223,141
-5800,1513829950125,138
-5801,1513830815841,141
-5802,1513831609955,138
-5803,1513832030932,134
-5804,1513832664603,136
-5805,1513832862688,133
-5806,1513832906000,131
-5807,1513833001167,134
-5808,1513833111209,133
-5809,1513833180618,132
-5810,1513833329994,133
-5811,1513833503741,131
-5812,1513833851921,129
-5813,1513834455807,126
-5814,1513834804343,123
-5815,1513835195392,120
-5816,1513835941745,116
-5817,1513836409011,113
-5818,1513836526504,108
-5819,1513836651782,108
-5820,1513836893887,106
-5821,1513837270517,103
-5822,1513838441498,100
-5823,1513839798234,99
-5824,1513840897309,95
-5825,1513841838608,92
-5826,1513841980773,89
-5827,1513842111355,87
-5828,1513842227202,84
-5829,1513842328679,83
-5830,1513842441661,81
-5831,1513842679316,79
-5832,1513842847786,76
-5833,1513842880108,73
-5834,1513843024948,74
-5835,1513843265623,74
-5836,1513843432989,70
-5837,1513843501005,67
-5838,1513843666267,66
-5839,1513843960776,62
-5840,1513844004570,60
-5841,1513844137236,59
-5842,1513844541335,56
-5843,1513844874840,52
-5844,1513844944620,48
-5845,1513845062389,46
-5846,1513845197622,42
-5847,1513845322245,39
-5848,1513845469970,37
-5849,1513845566414,34
-5850,1513845590922,31
-5851,1513845612737,30
-5852,1513845624471,30
-5853,1513845639256,34
-5854,1513845769164,39
-5855,1513845910957,35
-5856,1513845938025,33
-5857,1513846030540,32
-5858,1513846232691,28
-5859,1513846258270,24
-5860,1513846310346,24
-5861,1513846345092,20
-5862,1513846374983,18
-5863,1513846417509,18
-5864,1513846443721,14
-5865,1513846482844,12
-5866,1513846513956,9
-5867,1513846552949,6
-5868,1513846571105,2
-5869,1513846582862,1
-5870,1513846590994,1
-5871,1513846603385,1
-5872,1513846615370,1
-5873,1513846624514,1
-5874,1513846633285,1
-5875,1513846641025,1
-5876,1513846645633,1
-5877,1513846653722,1
-5878,1513846662469,1
-5879,1513846671655,1
-5880,1513846683250,1
-5881,1513846695169,1
-5882,1513846707983,1
-5883,1513846716836,1
-5884,1513846728632,1
-5885,1513846740325,1
-5886,1513846749120,1
-5887,1513846758205,1
-5888,1513846769584,1
-5889,1513846774139,2
-5890,1513846786921,8
-5891,1513846805483,7
-5892,1513846814930,8
-5893,1513846826721,8
-5894,1513846838622,8
-5895,1513846852716,8
-5896,1513846903062,9
-5897,1513846907258,14
-5898,1513846929878,21
-5899,1513846993831,21
-5900,1513847039066,20
-5901,1513847060469,23
-5902,1513847081108,24
-5903,1513847098636,24
-5904,1513847131441,26
-5905,1513847248681,26
-5906,1513847324805,25
-5907,1513847410344,28
-5908,1513847439512,28
-5909,1513847848009,30
-5910,1513848319391,30
-5911,1513848399147,30
-5912,1513848434585,29
-5913,1513848454157,31
-5914,1513848492608,33
-5915,1513848518235,34
-5916,1513848672297,35
-5917,1513848890036,34
-5918,1513848996644,33
-5919,1513849053689,32
-5920,1513849105383,33
-5921,1513849133097,33
-5922,1513849161450,34
-5923,1513849300151,36
-5924,1513849501381,34
-5925,1513849668759,33
-5926,1513849763987,31
-5927,1513849788674,30
-5928,1513849804445,33
-5929,1513849851571,37
-5930,1513849955670,37
-5931,1513850091400,36
-5932,1513850157513,36
-5933,1513850214541,36
-5934,1513850267548,37
-5935,1513850276040,37
-5936,1513850400872,47
-5937,1513850431563,46
-5938,1513850816413,49
-5939,1513851046334,47
-5940,1513851097075,46
-5941,1513851118131,47
-5942,1513851142342,51
-5943,1513851191168,55
-5944,1513851311191,55
-5945,1513851558735,55
-5946,1513851816005,53
-5947,1513852250670,52
-5948,1513852260970,51
-5949,1513852342395,61
-5950,1513852430246,60
-5951,1513852563412,60
-5952,1513852793339,60
-5953,1513852947084,62
-5954,1513853006797,64
-5955,1513853072589,64
-5956,1513853162347,64
-5957,1513853209611,66
-5958,1513853367207,67
-5959,1513853511200,65
-5960,1513853640274,66
-5961,1513853778365,65
-5962,1513853816715,65
-5963,1513854032446,67
-5964,1513854299525,65
-5965,1513854427277,65
-5966,1513854630083,64
-5967,1513854859429,62
-5968,1513854915621,61
-5969,1513855512853,62
-5970,1513855556674,60
-5971,1513855821893,61
-5972,1513855851220,58
-5973,1513855926780,61
-5974,1513856060430,61
-5975,1513856166492,59
-5976,1513856233029,58
-5977,1513856555882,58
-5978,1513856753236,56
-5979,1513856824859,54
-5980,1513856854296,53
-5981,1513857021785,55
-5982,1513857067244,53
-5983,1513857216208,53
-5984,1513857265043,52
-5985,1513857342422,52
-5986,1513857479452,50
-5987,1513857490419,49
-5988,1513857580733,57
-5989,1513857658635,55
-5990,1513857800299,54
-5991,1513857844643,53
-5992,1513857873401,54
-5993,1513858030273,56
-5994,1513858121106,55
-5995,1513858323049,54
-5996,1513858367300,52
-5997,1513858498150,52
-5998,1513858943620,55
-5999,1513859436897,53
-6000,1513859530197,50
-6001,1513859580821,49
-6002,1513859654454,51
-6003,1513859716136,50
-6004,1513859774511,50
-6005,1513859835095,51
-6006,1513859912672,51
-6007,1513859939444,49
-6008,1513860037887,52
-6009,1513860155074,51
-6010,1513860291470,49
-6011,1513860339275,47
-6012,1513860420664,46
-6013,1513860718807,46
-6014,1513860827050,45
-6015,1513860925397,44
-6016,1513861024812,44
-6017,1513861142560,42
-6018,1513861180616,41
-6019,1513861230994,40
-6020,1513861375503,41
-6021,1513861482544,39
-6022,1513861514097,38
-6023,1513861610927,40
-6024,1513861636251,38
-6025,1513861643705,39
-6026,1513861684237,49
-6027,1513861817687,49
-6028,1513861933539,48
-6029,1513862045220,48
-6030,1513862171087,48
-6031,1513862464747,46
-6032,1513862707097,43
-6033,1513862717413,42
-6034,1513862764606,49
-6035,1513862881737,49
-6036,1513863106045,52
-6037,1513863125474,50
-6038,1513863235653,55
-6039,1513863302584,53
-6040,1513863408826,52
-6041,1513863485183,50
-6042,1513863513296,53
-6043,1513863584975,57
-6044,1513863830513,56
-6045,1513863904146,54
-6046,1513864032698,53
-6047,1513864107996,52
-6048,1513864122591,50
-6049,1513864199640,62
-6050,1513864268469,62
-6051,1513864302357,62
-6052,1513864385954,64
-6053,1513864501079,63
-6054,1513864529599,62
-6055,1513864573277,65
-6056,1513864650595,66
-6057,1513864709336,66
-6058,1513864774355,67
-6059,1513864873102,68
-6060,1513865026779,66
-6061,1513865345056,65
-6062,1513865416696,63
-6063,1513865436173,64
-6064,1513865499754,68
-6065,1513865566595,69
-6066,1513865611443,69
-6067,1513865659588,69
-6068,1513865675835,69
-6069,1513865799483,78
-6070,1513865933154,75
-6071,1513866083024,76
-6072,1513866194318,73
-6073,1513866259515,74
-6074,1513866316684,74
-6075,1513866543349,74
-6076,1513866596997,72
-6077,1513866742527,73
-6078,1513866879031,71
-6079,1513866900088,69
-6080,1513866918395,74
-6081,1513866972998,82
-6082,1513867357316,83
-6083,1513867392873,81
-6084,1513867508336,83
-6085,1513867668973,83
-6086,1513867743944,81
-6087,1513867795475,80
-6088,1513867923674,85
-6089,1513867971360,84
-6090,1513868049951,86
-6091,1513868308818,85
-6092,1513868323318,83
-6093,1513868592320,96
-6094,1513868743628,93
-6095,1513869098850,91
-6096,1513869133009,89
-6097,1513869346269,93
-6098,1513869451279,90
-6099,1513869586924,89
-6100,1513870131068,86
-6101,1513870135412,83
-6102,1513870231830,127
-6103,1513870389941,126
-6104,1513870571873,124
-6105,1513870802565,122
-6106,1513870835304,120
-6107,1513871012779,125
-6108,1513871320786,123
-6109,1513871361598,121
-6110,1513871555281,124
-6111,1513871571456,120
-6112,1513871911057,136
-6113,1513871952092,132
-6114,1513872006355,135
-6115,1513872072855,136
-6116,1513872285130,136
-6117,1513872447282,133
-6118,1513872683845,131
-6119,1513872791603,127
-6120,1513873171047,126
-6121,1513873742575,122
-6122,1513873905863,118
-6123,1513874069753,116
-6124,1513874493823,113
-6125,1513874667793,110
-6126,1513874970266,112
-6127,1513875065121,110
-6128,1513875118290,108
-6129,1513875473492,109
-6130,1513875597958,105
-6131,1513875671934,102
-6132,1513875872973,101
-6133,1513876094087,96
-6134,1513876140986,98
-6135,1513876191976,99
-6136,1513876368773,99
-6137,1513876909552,95
-6138,1513877451744,94
-6139,1513877791837,89
-6140,1513878064607,86
-6141,1513878105652,82
-6142,1513878134207,84
-6143,1513878265115,88
-6144,1513878302564,85
-6145,1513878386481,84
-6146,1513878516602,84
-6147,1513878639935,80
-6148,1513878929617,78
-6149,1513879074254,77
-6150,1513879505356,75
-6151,1513879699289,71
-6152,1513879706350,69
-6153,1513879843496,89
-6154,1513880050270,85
-6155,1513880377357,84
-6156,1513880497800,81
-6157,1513880851680,79
-6158,1513880921640,75
-6159,1513880953042,73
-6160,1513881037412,76
-6161,1513881165656,73
-6162,1513881247046,69
-6163,1513881317224,67
-6164,1513881352372,68
-6165,1513881359708,68
-6166,1513881429128,87
-6167,1513881545691,86
-6168,1513881890966,84
-6169,1513881975517,85
-6170,1513881979882,83
-6171,1513882135683,123
-6172,1513882244138,120
-6173,1513882468356,117
-6174,1513882883064,114
-6175,1513882950095,110
-6176,1513883430135,109
-6177,1513883535599,105
-6178,1513883579010,102
-6179,1513883704944,103
-6180,1513883826983,102
-6181,1513883921779,103
-6182,1513884077895,101
-6183,1513884179195,97
-6184,1513884331873,97
-6185,1513884417540,93
-6186,1513884635958,91
-6187,1513884982919,87
-6188,1513885256172,84
-6189,1513885309475,80
-6190,1513885440249,80
-6191,1513885621927,77
-6192,1513885701337,73
-6193,1513885784441,76
-6194,1513886268336,74
-6195,1513886532235,69
-6196,1513886666351,64
-6197,1513886824284,63
-6198,1513887185097,59
-6199,1513887367079,55
-6200,1513887397310,51
-6201,1513887458217,50
-6202,1513887519037,70
-6203,1513887574169,69
-6204,1513887653171,69
-6205,1513887727095,66
-6206,1513888042496,65
-6207,1513888063588,65
-6208,1513888202248,68
-6209,1513888206606,65
-6210,1513888217064,100
-6211,1513888364755,119
-6212,1513888448031,124
-6213,1513888689821,123
-6214,1513888724169,122
-6215,1513888786419,129
-6216,1513889433693,131
-6217,1513889451344,127
-6218,1513889605494,140
-6219,1513889989168,138
-6220,1513890009785,133
-6221,1513890429268,144
-6222,1513890695707,140
-6223,1513890918921,136
-6224,1513890975534,133
-6225,1513891125908,133
-6226,1513891332068,130
-6227,1513891405931,126
-6228,1513891595425,126
-6229,1513891730374,123
-6230,1513892051931,120
-6231,1513892312943,116
-6232,1513892753058,113
-6233,1513892999442,109
-6234,1513893074049,105
-6235,1513893274044,105
-6236,1513893366491,103
-6237,1513893441551,100
-6238,1513893872477,98
-6239,1513893892965,94
-6240,1513893933904,99
-6241,1513894182701,98
-6242,1513894243291,97
-6243,1513894368274,98
-6244,1513894439298,95
-6245,1513894586528,96
-6246,1513894699356,92
-6247,1513894738600,89
-6248,1513894936361,90
-6249,1513895135965,85
-6250,1513895301390,81
-6251,1513895735316,76
-6252,1513895739919,71
-6253,1513895786345,115
-6254,1513895871259,115
-6255,1513896272847,112
-6256,1513896304591,108
-6257,1513896402660,110
-6258,1513896512194,106
-6259,1513896884636,104
-6260,1513897033652,101
-6261,1513897272523,97
-6262,1513897420310,93
-6263,1513897434219,89
-6264,1513897463930,100
-6265,1513897563531,103
-6266,1513897847834,111
-6267,1513897993013,107
-6268,1513898261072,104
-6269,1513898414209,99
-6270,1513898714053,95
-6271,1513898860958,114
-6272,1513898914953,111
-6273,1513899089816,112
-6274,1513899175933,108
-6275,1513899596183,106
-6276,1513899753299,103
-6277,1513899844980,99
-6278,1513899912586,98
-6279,1513900098097,99
-6280,1513900223350,95
-6281,1513900475295,93
-6282,1513900659817,90
-6283,1513900747577,87
-6284,1513900831888,84
-6285,1513901100517,82
-6286,1513901147367,79
-6287,1513901306150,78
-6288,1513901499924,74
-6289,1513901690190,69
-6290,1513901805961,67
-6291,1513901840656,64
-6292,1513901980335,63
-6293,1513902124330,60
-6294,1513902227993,57
-6295,1513902284099,52
-6296,1513902347335,49
-6297,1513902391101,46
-6298,1513902482858,44
-6299,1513902518081,40
-6300,1513902544002,37
-6301,1513902608088,37
-6302,1513902657388,34
-6303,1513902675013,31
-6304,1513902723855,31
-6305,1513902758356,29
-6306,1513902769406,27
-6307,1513902868791,26
-6308,1513902918011,26
-6309,1513902922383,22
-6310,1513902958573,47
-6311,1513903019000,57
-6312,1513903091747,55
-6313,1513903184241,54
-6314,1513903294858,50
-6315,1513903336586,52
-6316,1513903359770,52
-6317,1513903407295,53
-6318,1513903558820,60
-6319,1513903602993,58
-6320,1513903693301,57
-6321,1513903936685,61
-6322,1513904170285,58
-6323,1513904286322,55
-6324,1513904496593,52
-6325,1513904694509,52
-6326,1513904894555,49
-6327,1513905259430,46
-6328,1513905359332,45
-6329,1513905406603,42
-6330,1513905534329,41
-6331,1513905707964,38
-6332,1513905944517,35
-6333,1513906141720,32
-6334,1513906161650,28
-6335,1513906203514,29
-6336,1513906245774,27
-6337,1513906278746,27
-6338,1513906308657,25
-6339,1513906359532,24
-6340,1513906363578,27
-6341,1513906384086,42
-6342,1513906483785,43
-6343,1513906623645,41
-6344,1513906760452,40
-6345,1513906866571,38
-6346,1513906984229,35
-6347,1513907018852,32
-6348,1513907088521,33
-6349,1513907163284,31
-6350,1513907242032,28
-6351,1513907388121,25
-6352,1513907500848,23
-6353,1513907507983,38
-6354,1513907562353,50
-6355,1513907741809,51
-6356,1513907917589,49
-6357,1513907990436,50
-6358,1513908050883,49
-6359,1513908113198,49
-6360,1513908194091,48
-6361,1513908317620,46
-6362,1513908514057,44
-6363,1513908631872,43
-6364,1513908675656,48
-6365,1513908710198,50
-6366,1513908745839,53
-6367,1513908989211,54
-6368,1513909239582,51
-6369,1513909303367,50
-6370,1513909338996,49
-6371,1513909352692,50
-6372,1513909385706,56
-6373,1513909427722,60
-6374,1513909723311,61
-6375,1513910018025,59
-6376,1513910040485,57
-6377,1513910156333,61
-6378,1513910349940,60
-6379,1513910480469,59
-6380,1513910586660,57
-6381,1513910696336,56
-6382,1513910730947,55
-6383,1513910735185,56
-6384,1513910745700,86
-6385,1513910765618,103
-6386,1513910960054,112
-6387,1513911484427,111
-6388,1513911534970,107
-6389,1513911647981,109
-6390,1513911796244,107
-6391,1513911817457,105
-6392,1513911850863,116
-6393,1513911882678,120
-6394,1513911984159,125
-6395,1513912335671,124
-6396,1513912568881,121
-6397,1513912963971,119
-6398,1513913577204,117
-6399,1513913581605,114
-6400,1513913870430,172
-6401,1513914032554,170
-6402,1513914144230,167
-6403,1513914407114,167
-6404,1513914654534,165
-6405,1513915036675,163
-6406,1513915509087,159
-6407,1513915578723,157
-6408,1513915922147,158
-6409,1513916109250,153
-6410,1513916410523,157
-6411,1513916729864,155
-6412,1513916808813,151
-6413,1513917031356,151
-6414,1513917503205,149
-6415,1513917656636,145
-6416,1513917944402,143
-6417,1513917994211,142
-6418,1513918135472,145
-6419,1513918203703,143
-6420,1513918293971,144
-6421,1513918510488,143
-6422,1513919131405,140
-6423,1513919673244,135
-6424,1513920104978,132
-6425,1513920128817,127
-6426,1513920142977,135
-6427,1513920315844,153
-6428,1513920353188,150
-6429,1513920493734,154
-6430,1513921327947,151
-6431,1513921448193,147
-6432,1513921574410,143
-6433,1513921802418,140
-6434,1513921855993,136
-6435,1513922048298,138
-6436,1513922098618,134
-6437,1513922373614,135
-6438,1513922435217,131
-6439,1513922689009,131
-6440,1513922873857,126
-6441,1513923091670,130
-6442,1513923141172,128
-6443,1513923221344,129
-6444,1513923360276,127
-6445,1513923816004,123
-6446,1513924176902,119
-6447,1513924429553,113
-6448,1513924746665,110
-6449,1513924767869,105
-6450,1513925217647,111
-6451,1513925335944,106
-6452,1513925370090,102
-6453,1513925517066,103
-6454,1513925609355,105
-6455,1513925844242,101
-6456,1513926007262,98
-6457,1513926225612,93
-6458,1513926330658,89
-6459,1513926706483,86
-6460,1513926751548,81
-6461,1513926837115,80
-6462,1513926937395,76
-6463,1513927075953,72
-6464,1513927132178,67
-6465,1513927579648,65
-6466,1513927599119,61
-6467,1513927823171,64
-6468,1513927828040,59
-6469,1513928088379,81
-6470,1513928166120,77
-6471,1513928357689,74
-6472,1513928469195,72
-6473,1513928767325,69
-6474,1513928984083,65
-6475,1513929051532,60
-6476,1513929134650,56
-6477,1513929533960,54
-6478,1513929555377,48
-6479,1513929621877,48
-6480,1513929675377,44
-6481,1513929763663,39
-6482,1513929786485,35
-6483,1513929885952,34
-6484,1513929943474,45
-6485,1513929990546,50
-6486,1513930027998,53
-6487,1513930157313,52
-6488,1513930207545,48
-6489,1513930233159,47
-6490,1513930312964,46
-6491,1513930340873,44
-6492,1513930372099,47
-6493,1513930573383,50
-6494,1513930607834,49
-6495,1513930649288,49
-6496,1513930732538,47
-6497,1513930773190,43
-6498,1513930853854,41
-6499,1513931012640,37
-6500,1513931019886,64
-6501,1513931178383,81
-6502,1513931248308,78
-6503,1513931467265,78
-6504,1513931569019,76
-6505,1513931739826,73
-6506,1513932205557,70
-6507,1513932295246,66
-6508,1513932320859,66
-6509,1513932432467,68
-6510,1513932489238,66
-6511,1513932642650,65
-6512,1513932785351,62
-6513,1513933096619,60
-6514,1513933126260,57
-6515,1513933177100,57
-6516,1513933329693,56
-6517,1513933453876,53
-6518,1513933479857,52
-6519,1513933628548,54
-6520,1513933660015,53
-6521,1513933730402,54
-6522,1513933866081,52
-6523,1513933907066,49
-6524,1513933970021,47
-6525,1513934096729,44
-6526,1513934191510,47
-6527,1513934259368,56
-6528,1513934336113,54
-6529,1513934404745,56
-6530,1513934598797,55
-6531,1513934758020,53
-6532,1513934859890,50
-6533,1513934898005,49
-6534,1513934940818,49
-6535,1513934951782,51
-6536,1513934998539,59
-6537,1513935100044,61
-6538,1513935186321,59
-6539,1513935740867,60
-6540,1513935893549,56
-6541,1513936079707,53
-6542,1513936275272,52
-6543,1513936302155,51
-6544,1513936335888,54
-6545,1513936360008,55
-6546,1513936413780,57
-6547,1513936448675,56
-6548,1513936489792,56
-6549,1513936518320,55
-6550,1513936660470,62
-6551,1513936725805,59
-6552,1513936769580,58
-6553,1513936913080,61
-6554,1513937015181,59
-6555,1513937272968,58
-6556,1513937513235,55
-6557,1513937559785,52
-6558,1513937645487,52
-6559,1513937714492,50
-6560,1513938104957,49
-6561,1513938439516,47
-6562,1513938487446,45
-6563,1513938622838,44
-6564,1513938768988,41
-6565,1513938773351,40
-6566,1513938808918,58
-6567,1513938833092,62
-6568,1513939050065,64
-6569,1513939182075,75
-6570,1513939342797,74
-6571,1513939420001,72
-6572,1513939760844,71
-6573,1513939810868,68
-6574,1513939863612,67
-6575,1513940074739,67
-6576,1513940490692,65
-6577,1513940511488,62
-6578,1513940582620,67
-6579,1513940647370,68
-6580,1513940781994,67
-6581,1513940995015,65
-6582,1513941251984,63
-6583,1513941528167,61
-6584,1513941555599,58
-6585,1513941595190,61
-6586,1513941935030,61
-6587,1513942335613,60
-6588,1513942352861,57
-6589,1513942407200,63
-6590,1513942496407,63
-6591,1513942546024,62
-6592,1513942832026,63
-6593,1513942862112,62
-6594,1513943032783,63
-6595,1513943395420,62
-6596,1513943704466,60
-6597,1513943764935,57
-6598,1513944066384,57
-6599,1513944588284,54
-6600,1513944602035,51
-6601,1513944678423,67
-6602,1513944832357,66
-6603,1513944912021,65
-6604,1513945070378,64
-6605,1513945340491,62
-6606,1513945381167,59
-6607,1513945465768,59
-6608,1513945537362,58
-6609,1513945604163,60
-6610,1513945615223,59
-6611,1513945630063,70
-6612,1513945758747,78
-6613,1513946331349,76
-6614,1513946865926,73
-6615,1513946896796,72
-6616,1513947015704,75
-6617,1513947437052,73
-6618,1513947464861,70
-6619,1513947525347,75
-6620,1513947532877,74
-6621,1513947610110,96
-6622,1513947857845,95
-6623,1513948154998,92
-6624,1513948240431,91
-6625,1513948449888,90
-6626,1513949117529,88
-6627,1513950025865,85
-6628,1513951198562,81
-6629,1513951219136,78
-6630,1513951262682,84
-6631,1513951309372,85
-6632,1513951380500,86
-6633,1513951549060,84
-6634,1513951715979,82
-6635,1513951807936,81
-6636,1513951812826,84
-6637,1513951938208,123
-6638,1513952457610,122
-6639,1513952465073,118
-6640,1513952516352,151
-6641,1513952678683,154
-6642,1513952768076,150
-6643,1513953466935,149
-6644,1513954222635,147
-6645,1513954376631,144
-6646,1513954661562,143
-6647,1513955421122,140
-6648,1513955846315,138
-6649,1513956010342,135
-6650,1513956180549,134
-6651,1513956935594,132
-6652,1513957818146,128
-6653,1513958034111,124
-6654,1513958062290,121
-6655,1513958100027,127
-6656,1513958388840,130
-6657,1513958543808,126
-6658,1513958613527,124
-6659,1513958904755,123
-6660,1513959318333,119
-6661,1513959576091,115
-6662,1513960054372,111
-6663,1513960217621,107
-6664,1513960280837,104
-6665,1513960388751,102
-6666,1513960518033,111
-6667,1513960818984,109
-6668,1513961067278,109
-6669,1513961534666,105
-6670,1513962179211,101
-6671,1513962332568,97
-6672,1513962385780,94
-6673,1513962694646,94
-6674,1513963022758,91
-6675,1513963290307,88
-6676,1513963337727,84
-6677,1513963392867,83
-6678,1513963548696,86
-6679,1513963943441,83
-6680,1513964070910,80
-6681,1513964252740,78
-6682,1513964409305,73
-6683,1513964417317,70
-6684,1513964710279,86
-6685,1513965017122,85
-6686,1513965158318,81
-6687,1513965166105,78
-6688,1513965615621,97
-6689,1513965619834,96
-6690,1513965643975,147
-6691,1513966084891,156
-6692,1513966403558,152
-6693,1513966825431,147
-6694,1513967439865,144
-6695,1513967575065,139
-6696,1513967673979,135
-6697,1513967851618,132
-6698,1513967998423,128
-6699,1513968277898,125
-6700,1513968644937,119
-6701,1513969092451,118
-6702,1513969158950,113
-6703,1513969528115,111
-6704,1513969666485,107
-6705,1513969996140,102
-6706,1513970737894,97
-6707,1513971095156,94
-6708,1513971508931,88
-6709,1513971566940,84
-6710,1513971607105,82
-6711,1513971725351,87
-6712,1513971801731,89
-6713,1513971963208,86
-6714,1513972129707,82
-6715,1513972205905,77
-6716,1513972220486,76
-6717,1513972544518,83
-6718,1513973131412,77
-6719,1513973482900,75
-6720,1513973523234,71
-6721,1513973705154,81
-6722,1513973761793,78
-6723,1513973766229,76
-6724,1513973790152,111
-6725,1513973886944,118
-6726,1513973907319,114
-6727,1513973967205,122
-6728,1513974942363,120
-6729,1513975925270,114
-6730,1513976108926,111
-6731,1513976148980,109
-6732,1513976355814,111
-6733,1513976437624,106
-6734,1513976988915,104
-6735,1513977091937,98
-6736,1513977248217,95
-6737,1513977518352,111
-6738,1513977791509,107
-6739,1513978085228,102
-6740,1513978116890,117
-6741,1513978189524,124
-6742,1513978376641,123
-6743,1513979097642,122
-6744,1513979934687,117
-6745,1513980190019,111
-6746,1513980214447,108
-6747,1513980339199,114
-6748,1513980469736,111
-6749,1513980979961,108
-6750,1513981288998,103
-6751,1513981345607,99
-6752,1513981399078,99
-6753,1513981615354,97
-6754,1513981851615,93
-6755,1513982225246,94
-6756,1513982392115,92
-6757,1513982558417,89
-6758,1513982617366,86
-6759,1513982846415,86
-6760,1513982861770,82
-6761,1513983119560,89
-6762,1513983511586,85
-6763,1513983516096,81
-6764,1513983595414,119
-6765,1513983603418,118
-6766,1513983656598,149
-6767,1513983773162,150
-6768,1513984147813,146
-6769,1513984239835,141
-6770,1513984426929,137
-6771,1513984473858,133
-6772,1513984625500,133
-6773,1513984810163,130
-6774,1513985297769,126
-6775,1513985909514,119
-6776,1513986673744,113
-6777,1513986694680,109
-6778,1513987005313,116
-6779,1513987129437,111
-6780,1513987263922,106
-6781,1513987281934,102
-6782,1513987313296,109
-6783,1513987622002,110
-6784,1513987719245,115
-6785,1513987775764,111
-6786,1513988020311,109
-6787,1513988117432,103
-6788,1513988285786,110
-6789,1513988475178,105
-6790,1513988768435,128
-6791,1513988993603,130
-6792,1513989040397,127
-6793,1513989090743,127
-6794,1513990107245,129
-6795,1513991298934,122
-6796,1513991649350,118
-6797,1513991974500,115
-6798,1513992180144,111
-6799,1513992741136,107
-6800,1513993141535,102
-6801,1513993321766,98
-6802,1513993887302,93
-6803,1513994080739,90
-6804,1513994350857,85
-6805,1513994806879,81
-6806,1513994827395,76
-6807,1513994855204,78
-6808,1513994999979,80
-6809,1513995118963,75
-6810,1513995316741,72
-6811,1513995366396,69
-6812,1513995492182,68
-6813,1513995628639,65
-6814,1513995691557,60
-6815,1513995794937,57
-6816,1513995818207,54
-6817,1513995848946,59
-6818,1513996021405,59
-6819,1513996247413,54
-6820,1513996294143,49
-6821,1513996467855,48
-6822,1513996833709,42
-6823,1513996876363,38
-6824,1513996955889,57
-6825,1513997103708,58
-6826,1513997124631,55
-6827,1513997270199,63
-6828,1513997479830,62
-6829,1513997794225,58
-6830,1513998198351,53
-6831,1513998569576,50
-6832,1513998580601,48
-6833,1513998611908,54
-6834,1513998713339,56
-6835,1513999022079,52
-6836,1513999334738,49
-6837,1513999342450,44
-6838,1513999524881,53
-6839,1513999711682,49
-6840,1513999781200,45
-6841,1514000130779,46
-6842,1514000138315,44
-6843,1514000205212,54
-6844,1514000273288,51
-6845,1514000515281,47
-6846,1514000863059,43
-6847,1514000912425,43
-6848,1514001018423,42
-6849,1514001204941,38
-6850,1514001297443,34
-6851,1514001379380,31
-6852,1514001482085,29
-6853,1514001538860,26
-6854,1514001598707,23
-6855,1514001609848,19
-6856,1514001617566,19
-6857,1514001645714,21
-6858,1514001670018,18
-6859,1514001708107,16
-6860,1514001722350,12
-6861,1514001754549,17
-6862,1514001781631,13
-6863,1514001815146,10
-6864,1514001838766,28
-6865,1514001843190,28
-6866,1514001986649,57
-6867,1514002014190,57
-6868,1514002024865,60
-6869,1514002199363,70
-6870,1514002444128,69
-6871,1514002567926,67
-6872,1514002769271,67
-6873,1514003110511,66
-6874,1514003460467,63
-6875,1514003484406,59
-6876,1514003798051,62
-6877,1514003949664,58
-6878,1514004128354,62
-6879,1514004163039,59
-6880,1514004235167,61
-6881,1514004298316,60
-6882,1514004383901,65
-6883,1514004502335,67
-6884,1514004613583,66
-6885,1514004827726,65
-6886,1514004919915,65
-6887,1514004936907,64
-6888,1514005224805,70
-6889,1514005268147,68
-6890,1514005316710,69
-6891,1514005369220,69
-6892,1514005415784,70
-6893,1514005527237,72
-6894,1514005568085,74
-6895,1514005635422,74
-6896,1514005773463,74
-6897,1514005826608,72
-6898,1514005959945,71
-6899,1514006055259,70
-6900,1514006153915,69
-6901,1514006273183,67
-6902,1514006310147,65
-6903,1514006323964,65
-6904,1514006408744,74
-6905,1514006445991,72
-6906,1514006473006,73
-6907,1514006555148,80
-6908,1514006670325,82
-6909,1514006715072,80
-6910,1514006782277,81
-6911,1514007127505,81
-6912,1514007459533,79
-6913,1514007575442,76
-6914,1514007783288,74
-6915,1514007973168,72
-6916,1514008081357,70
-6917,1514008221786,70
-6918,1514008418023,70
-6919,1514008483174,67
-6920,1514008616765,67
-6921,1514008640537,65
-6922,1514008675054,68
-6923,1514008761062,69
-6924,1514008883375,68
-6925,1514009210425,66
-6926,1514009568710,63
-6927,1514009659795,62
-6928,1514009686954,62
-6929,1514009691489,63
-6930,1514010021437,93
-6931,1514010366383,89
-6932,1514010488725,86
-6933,1514010505988,88
-6934,1514010516535,98
-6935,1514010527130,116
-6936,1514011296285,138
-6937,1514012565678,134
-6938,1514013485457,135
-6939,1514014060470,131
-6940,1514014852526,127
-6941,1514015096658,124
-6942,1514015675615,119
-6943,1514015728316,122
-6944,1514015817711,124
-6945,1514015946733,124
-6946,1514016455905,122
-6947,1514016493719,117
-6948,1514016534972,121
-6949,1514016672377,123
-6950,1514016841725,120
-6951,1514016875758,118
-6952,1514016991642,121
-6953,1514017669014,119
-6954,1514017847408,115
-6955,1514018061937,111
-6956,1514018279535,110
-6957,1514018623711,108
-6958,1514018641375,105
-6959,1514018662921,115
-6960,1514018696920,123
-6961,1514019050739,127
-6962,1514019559621,123
-6963,1514020117783,119
-6964,1514020122661,114
-6965,1514020715705,166
-6966,1514020732897,169
-6967,1514020903273,187
-6968,1514021105005,185
-6969,1514021318654,188
-6970,1514021742000,184
-6971,1514021798673,179
-6972,1514021918540,181
-6973,1514022022051,179
-6974,1514022432876,177
-6975,1514022981762,172
-6976,1514023426668,169
-6977,1514024019895,164
-6978,1514024525779,158
-6979,1514025138893,153
-6980,1514025280248,149
-6981,1514025505862,147
-6982,1514025885997,143
-6983,1514026870738,138
-6984,1514027689861,133
-6985,1514027921809,127
-6986,1514028217603,123
-6987,1514028369558,118
-6988,1514029008150,118
-6989,1514029019156,114
-6990,1514029030860,134
-6991,1514029041872,156
-6992,1514029275633,185
-6993,1514029997328,182
-6994,1514030291854,176
-6995,1514030299329,172
-6996,1514030317053,222
-6997,1514030720477,244
-6998,1514031421131,238
-6999,1514031546135,231
-7000,1514031863881,229
-7001,1514032221192,222
-7002,1514032802297,216
-7003,1514033037335,211
-7004,1514033387865,210
-7005,1514033973393,204
-7006,1514034039626,199
-7007,1514034294492,202
-7008,1514034762887,196
-7009,1514035209165,190
-7010,1514035835035,185
-7011,1514036518614,179
-7012,1514036868636,172
-7013,1514037238924,164
-7014,1514037404183,158
-7015,1514038163988,153
-7016,1514039937089,146
-7017,1514041966749,139
-7018,1514042290232,131
-7019,1514042343432,124
-7020,1514042517813,123
-7021,1514042656279,117
-7022,1514042667326,114
-7023,1514043069257,134
-7024,1514044064545,126
-7025,1514045752254,119
-7026,1514046459280,112
-7027,1514046470603,104
-7028,1514047109234,118
-7029,1514047796753,113
-7030,1514048223118,121
-7031,1514049098600,114
-7032,1514049600202,107
-7033,1514049823733,100
-7034,1514050528305,99
-7035,1514050643566,104
-7036,1514050703414,111
-7037,1514050785000,109
-7038,1514051037114,105
-7039,1514051099811,98
-7040,1514051512792,96
-7041,1514052232385,88
-7042,1514052598787,82
-7043,1514052633737,76
-7044,1514052856840,76
-7045,1514053382671,71
-7046,1514053806119,65
-7047,1514053868909,59
-7048,1514054021374,58
-7049,1514054291459,54
-7050,1514054295913,49
-7051,1514054370590,69
-7052,1514054479794,68
-7053,1514054503637,63
-7054,1514054527548,63
-7055,1514054623115,63
-7056,1514054741867,57
-7057,1514054944324,51
-7058,1514055303506,44
-7059,1514055360429,44
-7060,1514055521192,46
-7061,1514055763599,44
-7062,1514055816968,38
-7063,1514056153231,32
-7064,1514056476337,26
-7065,1514056565535,47
-7066,1514056693434,43
-7067,1514056819913,50
-7068,1514056850648,46
-7069,1514056889285,45
-7070,1514057113121,43
-7071,1514057206004,38
-7072,1514057386652,37
-7073,1514057554910,34
-7074,1514057585353,30
-7075,1514057685770,28
-7076,1514057767078,23
-7077,1514057788611,18
-7078,1514057867769,15
-7079,1514057892162,10
-7080,1514057906346,6
-7081,1514057921519,2
-7082,1514057926255,1
-7083,1514057935192,1
-7084,1514057939643,1
-7085,1514057943732,1
-7086,1514057947966,1
-7087,1514057952373,1
-7088,1514057961015,1
-7089,1514057965291,1
-7090,1514057969775,1
-7091,1514057981480,1
-7092,1514057985735,1
-7093,1514057990078,1
-7094,1514057999055,1
-7095,1514058007628,1
-7096,1514058011883,9
-7097,1514058046100,27
-7098,1514058084333,26
-7099,1514058162983,24
-7100,1514058183417,25
-7101,1514058194317,26
-7102,1514058288005,29
-7103,1514058311619,27
-7104,1514058379214,27
-7105,1514058419629,26
-7106,1514058484199,25
-7107,1514058522427,27
-7108,1514058533247,26
-7109,1514058547634,30
-7110,1514058731282,32
-7111,1514058791566,30
-7112,1514058838192,28
-7113,1514058887253,27
-7114,1514058905859,25
-7115,1514058978171,26
-7116,1514059012988,24
-7117,1514059046786,22
-7118,1514059081053,21
-7119,1514059085719,20
-7120,1514059129850,29
-7121,1514059417271,29
-7122,1514059510805,27
-7123,1514059626987,37
-7124,1514059689660,35
-7125,1514059703756,34
-7126,1514059805778,37
-7127,1514059836357,35
-7128,1514059887487,45
-7129,1514059911286,45
-7130,1514059962621,47
-7131,1514060115642,47
-7132,1514060381354,45
-7133,1514060402170,42
-7134,1514060486539,46
-7135,1514060516014,44
-7136,1514060527157,45
-7137,1514060586100,54
-7138,1514060778904,56
-7139,1514060844962,53
-7140,1514060869011,54
-7141,1514060906683,57
-7142,1514061022189,58
-7143,1514061042942,56
-7144,1514061420123,62
-7145,1514061431241,59
-7146,1514061507540,70
-7147,1514061715424,68
-7148,1514061975224,67
-7149,1514061982889,64
-7150,1514062021613,82
-7151,1514062289029,96
-7152,1514062652125,95
-7153,1514062923877,94
-7154,1514063015365,94
-7155,1514063183142,97
-7156,1514063396534,96
-7157,1514063658236,94
-7158,1514063776505,93
-7159,1514064025596,91
-7160,1514064167945,90
-7161,1514064186126,89
-7162,1514064325541,98
-7163,1514064567058,96
-7164,1514064643253,94
-7165,1514064888465,94
-7166,1514065307694,93
-7167,1514065381113,90
-7168,1514065507911,89
-7169,1514065551368,90
-7170,1514065668086,93
-7171,1514065795716,91
-7172,1514065855243,91
-7173,1514066109986,91
-7174,1514066444047,88
-7175,1514066789925,87
-7176,1514067204511,85
-7177,1514067384677,82
-7178,1514067746398,81
-7179,1514068169677,78
-7180,1514068256233,75
-7181,1514068310467,74
-7182,1514068404673,74
-7183,1514068532296,73
-7184,1514068586247,71
-7185,1514068719027,71
-7186,1514068798916,69
-7187,1514068943460,67
-7188,1514069160546,66
-7189,1514069500949,63
-7190,1514069528836,59
-7191,1514069575830,62
-7192,1514069725758,61
-7193,1514069756685,58
-7194,1514069861872,59
-7195,1514069995212,57
-7196,1514070133664,54
-7197,1514070184537,54
-7198,1514070199273,54
-7199,1514070217063,60
-7200,1514070254695,64
-7201,1514070282724,66
-7202,1514070320778,70
-7203,1514070355630,71
-7204,1514070386722,74
-7205,1514070436453,75
-7206,1514070574723,76
-7207,1514070783248,73
-7208,1514071184338,71
-7209,1514071267578,70
-7210,1514071285339,71
-7211,1514071346058,77
-7212,1514071538350,76
-7213,1514071864009,73
-7214,1514071878346,70
-7215,1514071980732,79
-7216,1514071989137,77
-7217,1514072138259,95
-7218,1514072340584,94
-7219,1514072580699,90
-7220,1514072588395,92
-7221,1514072827163,117
-7222,1514072929337,113
-7223,1514073193002,111
-7224,1514073516386,108
-7225,1514073875027,104
-7226,1514073966262,103
-7227,1514074091054,101
-7228,1514074298047,99
-7229,1514074670548,97
-7230,1514075227012,94
-7231,1514075231635,92
-7232,1514075347385,135
-7233,1514075396270,132
-7234,1514075620835,135
-7235,1514075922665,132
-7236,1514076087384,129
-7237,1514076151578,131
-7238,1514076686011,131
-7239,1514076903266,127
-7240,1514076924070,124
-7241,1514076941402,135
-7242,1514077082167,151
-7243,1514077437452,147
-7244,1514077888884,146
-7245,1514078235593,141
-7246,1514078698343,143
-7247,1514078738689,139
-7248,1514078798246,142
-7249,1514078884201,143
-7250,1514079075741,152
-7251,1514079511568,151
-7252,1514079765638,146
-7253,1514080291213,142
-7254,1514080550895,138
-7255,1514080938285,135
-7256,1514081119473,131
-7257,1514081496967,128
-7258,1514081501658,124
-7259,1514081653333,183
-7260,1514082029217,179
-7261,1514082703225,175
-7262,1514083164725,176
-7263,1514083739158,171
-7264,1514084021247,166
-7265,1514084106680,162
-7266,1514084509284,161
-7267,1514085238496,156
-7268,1514085590122,152
-7269,1514085664918,148
-7270,1514085821805,149
-7271,1514086287697,145
-7272,1514086809689,141
-7273,1514087440310,137
-7274,1514087814952,132
-7275,1514087988892,127
-7276,1514088053204,124
-7277,1514088234148,121
-7278,1514088439611,118
-7279,1514088469722,113
-7280,1514088850463,116
-7281,1514089245334,111
-7282,1514089455425,108
-7283,1514089500336,104
-7284,1514089552177,103
-7285,1514090020682,103
-7286,1514090080344,98
-7287,1514090283832,96
-7288,1514090669253,92
-7289,1514091021716,87
-7290,1514091305009,81
-7291,1514091890737,77
-7292,1514092178477,73
-7293,1514092460391,68
-7294,1514092522651,65
-7295,1514092673359,61
-7296,1514092789211,57
-7297,1514092969780,52
-7298,1514093121282,48
-7299,1514093151799,47
-7300,1514093193267,48
-7301,1514093421991,47
-7302,1514093571881,45
-7303,1514093641285,42
-7304,1514093723649,40
-7305,1514093728180,38
-7306,1514093749158,54
-7307,1514093777760,54
-7308,1514093857176,54
-7309,1514093958931,49
-7310,1514094107323,45
-7311,1514094135873,45
-7312,1514094228511,44
-7313,1514094475305,39
-7314,1514094552045,35
-7315,1514094659592,36
-7316,1514094674075,32
-7317,1514094692917,42
-7318,1514094766961,43
-7319,1514094805252,39
-7320,1514094930725,36
-7321,1514094955143,46
-7322,1514094969422,46
-7323,1514094983849,50
-7324,1514095021530,52
-7325,1514095113449,51
-7326,1514095190243,48
-7327,1514095230367,44
-7328,1514095264856,42
-7329,1514095308900,40
-7330,1514095365841,38
-7331,1514095466943,33
-7332,1514095503959,54
-7333,1514095583686,53
-7334,1514095626947,54
-7335,1514095799840,52
-7336,1514095960908,49
-7337,1514096099070,45
-7338,1514096143058,44
-7339,1514096212567,41
-7340,1514096250198,39
-7341,1514096267516,44
-7342,1514096330451,55
-7343,1514096489811,55
-7344,1514096517178,51
-7345,1514096558738,52
-7346,1514096569817,50
-7347,1514096591771,57
-7348,1514096750107,63
-7349,1514096822952,62
-7350,1514097083272,61
-7351,1514097104218,59
-7352,1514097111949,61
-7353,1514097130364,76
-7354,1514097173321,82
-7355,1514097312374,82
-7356,1514097339960,78
-7357,1514097369835,81
-7358,1514097508070,83
-7359,1514097665366,112
-7360,1514097777306,110
-7361,1514097852577,109
-7362,1514098141864,109
-7363,1514098297950,106
-7364,1514098357521,103
-7365,1514098677685,104
-7366,1514098784843,103
-7367,1514099112054,101
-7368,1514099152029,98
-7369,1514099242796,99
-7370,1514099342787,100
-7371,1514099475733,99
-7372,1514099590091,97
-7373,1514099751484,95
-7374,1514099836173,93
-7375,1514100018410,91
-7376,1514100075075,88
-7377,1514100087792,90
-7378,1514100266586,104
-7379,1514100280707,101
-7380,1514100302862,118
-7381,1514100366022,126
-7382,1514100968348,126
-7383,1514101172275,122
-7384,1514101186814,122
-7385,1514101897247,140
-7386,1514102221112,135
-7387,1514102745389,133
-7388,1514102839835,129
-7389,1514103067927,127
-7390,1514103353976,123
-7391,1514103862927,119
-7392,1514104028151,115
-7393,1514104476433,111
-7394,1514104932295,107
-7395,1514104985745,104
-7396,1514105273929,104
-7397,1514105414863,100
-7398,1514105649149,96
-7399,1514106189744,93
-7400,1514106346108,90
-7401,1514106384049,87
-7402,1514106475427,88
-7403,1514106486824,85
-7404,1514106567315,99
-7405,1514106595023,97
-7406,1514107101674,110
-7407,1514107395736,108
-7408,1514107691000,106
-7409,1514108001091,102
-7410,1514108446136,98
-7411,1514108502276,94
-7412,1514108694270,95
-7413,1514108832202,91
-7414,1514108836551,87
-7415,1514109142186,131
-7416,1514109452030,127
-7417,1514109884081,124
-7418,1514110134389,122
-7419,1514110407003,117
-7420,1514110462086,114
-7421,1514110830807,114
-7422,1514110940078,111
-7423,1514111148078,112
-7424,1514111263283,111
-7425,1514111300127,109
-7426,1514111307519,111
-7427,1514111358598,143
-7428,1514111445460,144
-7429,1514111799821,143
-7430,1514112236197,139
-7431,1514112602878,135
-7432,1514112669293,130
-7433,1514112693086,130
-7434,1514112786156,137
-7435,1514113033934,136
-7436,1514113946706,132
-7437,1514114200538,125
-7438,1514114707306,120
-7439,1514114946683,115
-7440,1514115189615,111
-7441,1514115338874,106
-7442,1514115476980,104
-7443,1514115923788,102
-7444,1514116541975,96
-7445,1514116567037,92
-7446,1514116640902,97
-7447,1514116791542,99
-7448,1514116869114,98
-7449,1514117070005,95
-7450,1514117238559,90
-7451,1514117487347,86
-7452,1514117671355,84
-7453,1514117724527,89
-7454,1514117738756,92
-7455,1514117944714,104
-7456,1514118258844,100
-7457,1514118426261,98
-7458,1514118915090,97
-7459,1514118932555,92
-7460,1514119195106,101
-7461,1514119349734,97
-7462,1514119644494,94
-7463,1514119884550,89
-7464,1514120225162,85
-7465,1514120493549,82
-7466,1514120806755,77
-7467,1514121071334,73
-7468,1514121561227,68
-7469,1514121690092,66
-7470,1514121896818,62
-7471,1514122049756,59
-7472,1514122057529,55
-7473,1514122087738,67
-7474,1514122269005,68
-7475,1514122299855,64
-7476,1514122387222,64
-7477,1514122475553,62
-7478,1514122593784,66
-7479,1514122702418,62
-7480,1514122723289,66
-7481,1514122806345,75
-7482,1514122852642,74
-7483,1514122863565,73
-7484,1514122950066,85
-7485,1514123086269,92
-7486,1514123163147,88
-7487,1514123279654,86
-7488,1514123583946,83
-7489,1514123618775,80
-7490,1514123662839,80
-7491,1514123733134,80
-7492,1514123860547,78
-7493,1514124206628,74
-7494,1514124472928,69
-7495,1514124507786,65
-7496,1514124616145,66
-7497,1514124670772,63
-7498,1514124856678,60
-7499,1514124913462,56
-7500,1514125064176,54
-7501,1514125118199,50
-7502,1514125209752,49
-7503,1514125226956,45
-7504,1514125258588,56
-7505,1514125368952,56
-7506,1514125450991,56
-7507,1514125581187,53
-7508,1514125764008,49
-7509,1514125883906,45
-7510,1514125949356,41
-7511,1514125995011,38
-7512,1514126019069,36
-7513,1514126119770,36
-7514,1514126303557,32
-7515,1514126433960,52
-7516,1514126587520,48
-7517,1514126669811,45
-7518,1514126750048,43
-7519,1514126861694,40
-7520,1514127006939,36
-7521,1514127129320,35
-7522,1514127421348,32
-7523,1514127455955,29
-7524,1514127482503,27
-7525,1514127520241,26
-7526,1514127554176,27
-7527,1514127659321,44
-7528,1514127906721,43
-7529,1514127947333,43
-7530,1514128019204,42
-7531,1514128023645,40
-7532,1514128080581,58
-7533,1514128256592,59
-7534,1514128290065,63
-7535,1514128324009,65
-7536,1514128391380,66
-7537,1514128459548,64
-7538,1514128558632,64
-7539,1514128777051,62
-7540,1514128828089,60
-7541,1514128933638,58
-7542,1514129069820,57
-7543,1514129115134,55
-7544,1514129223623,54
-7545,1514129279691,52
-7546,1514129325441,54
-7547,1514129450483,55
-7548,1514129611853,52
-7549,1514129616486,51
-7550,1514129681771,74
-7551,1514129713417,73
-7552,1514129961226,75
-7553,1514129989516,71
-7554,1514130019855,75
-7555,1514130269550,85
-7556,1514130306324,82
-7557,1514130459374,84
-7558,1514130588308,81
-7559,1514130707268,79
-7560,1514130843266,83
-7561,1514130986044,80
-7562,1514131044641,79
-7563,1514131073632,78
-7564,1514131131357,80
-7565,1514131205449,80
-7566,1514131255746,79
-7567,1514131348394,79
-7568,1514131505945,76
-7569,1514131638179,73
-7570,1514131780430,71
-7571,1514131877322,68
-7572,1514131974900,65
-7573,1514132056605,72
-7574,1514132393679,72
-7575,1514132404774,69
-7576,1514132483088,83
-7577,1514132615855,82
-7578,1514132623530,80
-7579,1514132786179,101
-7580,1514132928898,98
-7581,1514132966659,99
-7582,1514133053509,102
-7583,1514133219962,102
-7584,1514133474544,108
-7585,1514133998161,106
-7586,1514134078013,102
-7587,1514134204747,103
-7588,1514134442389,101
-7589,1514134694904,98
-7590,1514134931226,97
-7591,1514135217842,96
-7592,1514135483647,94
-7593,1514135761235,91
-7594,1514135973549,88
-7595,1514136108372,85
-7596,1514136204881,85
-7597,1514136479465,83
-7598,1514136917182,82
-7599,1514137004506,78
-7600,1514137098488,78
-7601,1514137102800,75
-7602,1514137526670,114
-7603,1514137656712,111
-7604,1514137770554,111
-7605,1514138284895,111
-7606,1514138825487,108
-7607,1514139015338,104
-7608,1514139261038,102
-7609,1514139368566,98
-7610,1514139392654,96
-7611,1514139591213,102
-7612,1514139830404,99
-7613,1514140280154,97
-7614,1514140496029,93
-7615,1514140639205,89
-7616,1514140908521,87
-7617,1514140936169,83
-7618,1514141003166,86
-7619,1514141169248,86
-7620,1514141362157,82
-7621,1514141476979,78
-7622,1514141684797,76
-7623,1514141895168,72
-7624,1514141932093,69
-7625,1514142165841,70
-7626,1514142272120,66
-7627,1514142282947,64
-7628,1514142426754,74
-7629,1514142688556,70
-7630,1514142766494,67
-7631,1514142902755,65
-7632,1514143055702,72
-7633,1514143086122,69
-7634,1514143265133,71
-7635,1514143440069,69
-7636,1514143463918,68
-7637,1514143584667,71
-7638,1514144030807,69
-7639,1514144187519,65
-7640,1514144467718,61
-7641,1514144548658,59
-7642,1514144608881,56
-7643,1514144727435,54
-7644,1514144780465,52
-7645,1514144827031,50
-7646,1514144875235,50
-7647,1514145111392,49
-7648,1514145247949,45
-7649,1514145341442,42
-7650,1514145391332,51
-7651,1514145504935,51
-7652,1514145630708,51
-7653,1514145722974,47
-7654,1514145895294,48
-7655,1514146132593,47
-7656,1514146162584,44
-7657,1514146227405,45
-7658,1514146285461,44
-7659,1514146426229,43
-7660,1514146451896,40
-7661,1514146528833,41
-7662,1514146585883,38
-7663,1514146717857,37
-7664,1514146808876,37
-7665,1514146880453,36
-7666,1514146975120,35
-7667,1514147084366,33
-7668,1514147217516,31
-7669,1514147315174,28
-7670,1514147378761,26
-7671,1514147452422,23
-7672,1514147486022,21
-7673,1514147522800,19
-7674,1514147556423,18
-7675,1514147594284,16
-7676,1514147630923,21
-7677,1514147691289,20
-7678,1514147745594,18
-7679,1514147809998,28
-7680,1514147940883,26
-7681,1514148000704,25
-7682,1514148005472,25
-7683,1514148125676,36
-7684,1514148193126,35
-7685,1514148220546,33
-7686,1514148247515,33
-7687,1514148268845,34
-7688,1514148352613,35
-7689,1514148409875,33
-7690,1514148476698,32
-7691,1514148526429,30
-7692,1514148561104,29
-7693,1514148660381,28
-7694,1514148744726,26
-7695,1514148814595,23
-7696,1514148905227,22
-7697,1514148916573,20
-7698,1514148957855,21
-7699,1514148996258,20
-7700,1514149040948,18
-7701,1514149092959,16
-7702,1514149150893,36
-7703,1514149182580,34
-7704,1514149289265,36
-7705,1514149468809,35
-7706,1514149476564,33
-7707,1514149487397,40
-7708,1514149624629,47
-7709,1514149702578,46
-7710,1514149791956,44
-7711,1514149830452,48
-7712,1514149868558,48
-7713,1514149922738,49
-7714,1514149959762,47
-7715,1514150009046,48
-7716,1514150084916,48
-7717,1514150089448,49
-7718,1514150113485,75
-7719,1514150344827,81
-7720,1514150416519,79
-7721,1514150550673,78
-7722,1514150677430,77
-7723,1514150756099,76
-7724,1514150852428,76
-7725,1514151034022,76
-7726,1514151413843,74
-7727,1514151533563,72
-7728,1514151719146,77
-7729,1514151741588,76
-7730,1514151795952,81
-7731,1514151934581,83
-7732,1514152130823,81
-7733,1514152277747,80
-7734,1514152368312,81
-7735,1514152652662,80
-7736,1514152674655,77
-7737,1514152923247,86
-7738,1514153642779,85
-7739,1514153747872,82
-7740,1514153781424,81
-7741,1514153987963,83
-7742,1514154166647,82
-7743,1514154319367,81
-7744,1514154510171,79
-7745,1514154886350,78
-7746,1514154939035,76
-7747,1514155104401,78
-7748,1514155306524,76
-7749,1514155463597,74
-7750,1514155484504,73
-7751,1514155542361,79
-7752,1514155720070,79
-7753,1514155822619,77
-7754,1514155932390,76
-7755,1514156024206,75
-7756,1514156124075,74
-7757,1514156278238,74
-7758,1514156444455,72
-7759,1514156754238,71
-7760,1514156761794,68
-7761,1514156986836,88
-7762,1514157170621,86
-7763,1514157393002,85
-7764,1514157511774,82
-7765,1514157621949,80
-7766,1514157746138,80
-7767,1514157750742,78
-7768,1514157786191,114
-7769,1514157886281,119
-7770,1514157903898,117
-7771,1514158361412,129
-7772,1514158727202,125
-7773,1514159008391,122
-7774,1514159188729,119
-7775,1514159255296,117
-7776,1514159544873,117
-7777,1514159953200,113
-7778,1514159963890,110
-7779,1514160077151,130
-7780,1514160415424,128
-7781,1514160753960,124
-7782,1514161108853,121
-7783,1514161424376,123
-7784,1514161785310,119
-7785,1514161872052,116
-7786,1514161920274,116
-7787,1514161938175,118
-7788,1514162418333,131
-7789,1514162429401,127
-7790,1514162617017,150
-7791,1514162634989,147
-7792,1514163130701,162
-7793,1514163438669,157
-7794,1514163595945,153
-7795,1514163984384,150
-7796,1514165265229,146
-7797,1514165336285,140
-7798,1514165498790,141
-7799,1514165578679,138
-7800,1514166176469,137
-7801,1514166210682,132
-7802,1514166595592,136
-7803,1514167559445,132
-7804,1514167939484,127
-7805,1514168272069,122
-7806,1514168397415,117
-7807,1514168452708,119
-7808,1514168551064,123
-7809,1514168775134,121
-7810,1514169115806,116
-7811,1514169124057,112
-7812,1514169271244,141
-7813,1514169505788,137
-7814,1514169526533,134
-7815,1514169626369,145
-7816,1514169831440,143
-7817,1514169983434,140
-7818,1514170091331,148
-7819,1514170285675,150
-7820,1514171051396,145
-7821,1514171302520,141
-7822,1514171392654,137
-7823,1514171620038,136
-7824,1514171968633,132
-7825,1514172125234,128
-7826,1514172482541,124
-7827,1514172761167,119
-7828,1514172863472,115
-7829,1514173313193,112
-7830,1514173711585,111
-7831,1514173839155,107
-7832,1514173993670,104
-7833,1514174075572,100
-7834,1514174147671,98
-7835,1514174824839,96
-7836,1514174990863,91
-7837,1514175338922,91
-7838,1514175525865,86
-7839,1514175708159,81
-7840,1514175872504,78
-7841,1514176042489,75
-7842,1514176219677,71
-7843,1514176313021,67
-7844,1514176377132,63
-7845,1514176398783,60
-7846,1514176613315,62
-7847,1514176922449,58
-7848,1514177099813,54
-7849,1514177191185,49
-7850,1514177224798,45
-7851,1514177251198,46
-7852,1514177273271,47
-7853,1514177287639,46
-7854,1514177314800,48
-7855,1514177466281,48
-7856,1514177717781,44
-7857,1514177792038,39
-7858,1514177860167,35
-7859,1514177933206,31
-7860,1514177957111,26
-7861,1514178133496,34
-7862,1514178204333,29
-7863,1514178228663,25
-7864,1514178268652,22
-7865,1514178320738,19
-7866,1514178411332,15
-7867,1514178435173,10
-7868,1514178439764,26
-7869,1514178530376,39
-7870,1514178553434,36
-7871,1514178767316,43
-7872,1514178811074,39
-7873,1514178822522,37
-7874,1514178905100,40
-7875,1514178946880,37
-7876,1514178992311,36
-7877,1514179021089,34
-7878,1514179113366,32
-7879,1514179124367,40
-7880,1514179154551,45
-7881,1514179437827,44
-7882,1514179568204,40
-7883,1514179589710,37
-7884,1514179681364,36
-7885,1514179754306,33
-7886,1514179772960,31
-7887,1514179797924,33
-7888,1514179844949,40
-7889,1514179898014,37
-7890,1514179971103,49
-7891,1514180034239,47
-7892,1514180162160,55
-7893,1514180321098,52
-7894,1514180424862,49
-7895,1514180642937,48
-7896,1514180825576,45
-7897,1514180866254,42
-7898,1514181017315,42
-7899,1514181028403,40
-7900,1514181066640,47
-7901,1514181132786,47
-7902,1514181165389,49
-7903,1514181241683,49
-7904,1514181322619,47
-7905,1514181366174,44
-7906,1514181442646,43
-7907,1514181569491,42
-7908,1514181630222,42
-7909,1514181678215,40
-7910,1514181778003,39
-7911,1514181895731,37
-7912,1514182062594,51
-7913,1514182159182,49
-7914,1514182270131,48
-7915,1514182390670,53
-7916,1514182617245,53
-7917,1514182861802,52
-7918,1514183025341,50
-7919,1514183029882,49
-7920,1514183131184,73
-7921,1514183198389,71
-7922,1514183349036,71
-7923,1514183509636,71
-7924,1514183631953,69
-7925,1514183810444,67
-7926,1514183881076,66
-7927,1514183950998,66
-7928,1514184163802,64
-7929,1514184310130,63
-7930,1514184656252,61
-7931,1514184732630,58
-7932,1514185027874,58
-7933,1514185332930,55
-7934,1514185379212,54
-7935,1514185443354,56
-7936,1514185468968,55
-7937,1514185615089,56
-7938,1514185767430,55
-7939,1514185936864,52
-7940,1514186111572,51
-7941,1514186156354,48
-7942,1514186342272,48
-7943,1514186366343,46
-7944,1514186419440,47
-7945,1514186546279,47
-7946,1514186612813,48
-7947,1514186646256,46
-7948,1514186717154,47
-7949,1514186821248,46
-7950,1514186933370,44
-7951,1514187050842,43
-7952,1514187158855,42
-7953,1514187206455,43
-7954,1514187263570,45
-7955,1514187294190,46
-7956,1514187685357,47
-7957,1514187702663,44
-7958,1514187787322,48
-7959,1514187961771,47
-7960,1514188135366,45
-7961,1514188711644,43
-7962,1514189120093,41
-7963,1514189213051,37
-7964,1514189233678,37
-7965,1514189270509,38
-7966,1514189353799,38
-7967,1514189506267,36
-7968,1514189517055,34
-7969,1514189631625,45
-7970,1514189747735,43
-7971,1514189890025,43
-7972,1514190125703,40
-7973,1514190156305,39
-7974,1514190231973,43
-7975,1514190316404,42
-7976,1514190414146,41
-7977,1514190568566,40
-7978,1514190736797,39
-7979,1514190821525,37
-7980,1514190892511,39
-7981,1514190966164,39
-7982,1514191017974,38
-7983,1514191109281,37
-7984,1514191219106,38
-7985,1514191402984,36
-7986,1514191548719,34
-7987,1514191552987,34
-7988,1514191597573,52
-7989,1514191631078,52
-7990,1514191718617,55
-7991,1514192009984,54
-7992,1514192257238,51
-7993,1514192275273,50
-7994,1514192297043,54
-7995,1514192482041,57
-7996,1514192732110,55
-7997,1514193057528,53
-7998,1514193377711,51
-7999,1514193546594,49
-8000,1514193668014,51
-8001,1514193779179,50
-8002,1514193897944,49
-8003,1514193940839,48
-8004,1514194206438,48
-8005,1514194479619,47
-8006,1514194590584,46
-8007,1514194610805,45
-8008,1514194641241,48
-8009,1514194707260,49
-8010,1514194794488,49
-8011,1514194808632,48
-8012,1514194949670,53
-8013,1514195155060,52
-8014,1514195288479,49
-8015,1514195293049,47
-8016,1514195533943,70
-8017,1514195699724,68
-8018,1514195917010,65
-8019,1514196033090,63
-8020,1514196199460,73
-8021,1514196559288,72
-8022,1514197252939,71
-8023,1514197490739,69
-8024,1514197639391,67
-8025,1514197821034,65
-8026,1514197950669,64
-8027,1514197987813,63
-8028,1514198075792,65
-8029,1514198136636,64
-8030,1514198304373,65
-8031,1514198497642,62
-8032,1514198871381,61
-8033,1514199239338,58
-8034,1514199277217,56
-8035,1514199346942,57
-8036,1514199437244,57
-8037,1514199477347,58
-8038,1514199497608,60
-8039,1514199541332,64
-8040,1514199620669,64
-8041,1514199684120,63
-8042,1514199726623,64
-8043,1514199847107,65
-8044,1514200235394,65
-8045,1514200715880,64
-8046,1514200746091,61
-8047,1514200760280,63
-8048,1514200811765,72
-8049,1514200825690,73
-8050,1514201086057,83
-8051,1514201400087,81
-8052,1514201696976,78
-8053,1514201920489,75
-8054,1514202294189,74
-8055,1514202499785,72
-8056,1514202507355,71
-8057,1514202790768,91
-8058,1514203180323,91
-8059,1514203501651,88
-8060,1514203884051,85
-8061,1514204205212,82
-8062,1514204209493,79
-8063,1514204259899,120
-8064,1514204785436,121
-8065,1514205020404,120
-8066,1514205122546,118
-8067,1514205304752,116
-8068,1514206000693,114
-8069,1514207162252,114
-8070,1514207179447,111
-8071,1514207206950,123
-8072,1514207277381,129
-8073,1514207510670,129
-8074,1514207632707,126
-8075,1514208150066,125
-8076,1514208568740,122
-8077,1514208666181,118
-8078,1514209349943,116
-8079,1514210040388,113
-8080,1514210770235,109
-8081,1514211711129,105
-8082,1514212237288,101
-8083,1514212659318,98
-8084,1514213255110,94
-8085,1514213872640,90
-8086,1514214368390,86
-8087,1514214798554,82
-8088,1514215742682,87
-8089,1514216483574,85
-8090,1514216681170,82
-8091,1514216765807,80
-8092,1514217238635,78
-8093,1514217314507,75
-8094,1514217449377,76
-8095,1514217557563,76
-8096,1514217594574,74
-8097,1514217807609,75
-8098,1514218028341,72
-8099,1514218175515,68
-8100,1514218324225,65
-8101,1514218443714,63
-8102,1514218533471,60
-8103,1514218576311,58
-8104,1514218611313,59
-8105,1514218744865,59
-8106,1514218860732,55
-8107,1514218875112,53
-8108,1514219108502,60
-8109,1514219205622,58
-8110,1514219433638,56
-8111,1514219663654,53
-8112,1514219681265,53
-8113,1514219700255,57
-8114,1514220004759,60
-8115,1514220025477,56
-8116,1514220091350,71
-8117,1514220137886,70
-8118,1514220409774,69
-8119,1514220927463,67
-8120,1514221174903,63
-8121,1514221345196,60
-8122,1514221350020,57
-8123,1514221712933,82
-8124,1514222111357,77
-8125,1514222553673,74
-8126,1514223032046,70
-8127,1514223345722,67
-8128,1514223564987,64
-8129,1514223616261,61
-8130,1514223696652,61
-8131,1514223744063,59
-8132,1514223937118,57
-8133,1514224156365,54
-8134,1514224498114,50
-8135,1514224827690,47
-8136,1514225079114,45
-8137,1514225274036,41
-8138,1514225335305,38
-8139,1514225389620,39
-8140,1514225454927,38
-8141,1514225462532,36
-8142,1514225476746,45
-8143,1514225492364,50
-8144,1514225578903,54
-8145,1514225741615,51
-8146,1514225993722,47
-8147,1514226186447,45
-8148,1514226296403,46
-8149,1514226433416,45
-8150,1514226531312,48
-8151,1514226727395,45
-8152,1514227099844,41
-8153,1514227356054,38
-8154,1514227360322,35
-8155,1514227383577,51
-8156,1514227501673,51
-8157,1514227522132,59
-8158,1514227577486,63
-8159,1514227674234,61
-8160,1514227791142,59
-8161,1514227855006,55
-8162,1514227958175,54
-8163,1514228086260,73
-8164,1514228152773,73
-8165,1514228247497,73
-8166,1514228346349,71
-8167,1514228657093,71
-8168,1514228968387,69
-8169,1514229095525,66
-8170,1514229215091,64
-8171,1514229309521,69
-8172,1514229557629,73
-8173,1514229895138,72
-8174,1514230402791,70
-8175,1514230649390,68
-8176,1514230758609,66
-8177,1514230807415,65
-8178,1514230894312,66
-8179,1514231108443,65
-8180,1514231268148,63
-8181,1514231437429,60
-8182,1514231451320,58
-8183,1514231475084,65
-8184,1514231533212,68
-8185,1514231956712,67
-8186,1514232099065,64
-8187,1514232148054,62
-8188,1514232184195,62
-8189,1514232580142,62
-8190,1514232655812,59
-8191,1514232664543,58
-8192,1514233057563,71
-8193,1514233322402,68
-8194,1514233420304,65
-8195,1514233606528,64
-8196,1514233860458,61
-8197,1514234048159,61
-8198,1514234157443,58
-8199,1514234184758,56
-8200,1514234373880,58
-8201,1514234378486,55
-8202,1514234521021,80
-8203,1514234559560,78
-8204,1514234759483,80
-8205,1514234893429,79
-8206,1514235199376,77
-8207,1514235362638,73
-8208,1514235696131,75
-8209,1514236072067,72
-8210,1514236173947,68
-8211,1514236310717,66
-8212,1514236362732,63
-8213,1514236566316,66
-8214,1514236820006,66
-8215,1514236935286,63
-8216,1514236992792,63
-8217,1514237148564,63
-8218,1514237198203,63
-8219,1514237255782,62
-8220,1514237410987,61
-8221,1514237451047,58
-8222,1514237522266,58
-8223,1514237573323,70
-8224,1514237615519,70
-8225,1514237927450,71
-8226,1514238216402,68
-8227,1514238286916,65
-8228,1514238419919,64
-8229,1514238530209,62
-8230,1514238731964,60
-8231,1514239453719,59
-8232,1514240114143,57
-8233,1514240391729,53
-8234,1514240906310,50
-8235,1514241160975,47
-8236,1514241332335,44
-8237,1514241353123,41
-8238,1514241400829,42
-8239,1514241435382,41
-8240,1514241641472,42
-8241,1514241855683,39
-8242,1514242021698,42
-8243,1514242193381,42
-8244,1514242250980,43
-8245,1514242326435,43
-8246,1514242389410,41
-8247,1514242462300,39
-8248,1514242661553,38
-8249,1514242692475,35
-8250,1514242798661,35
-8251,1514242806863,33
-8252,1514242815227,39
-8253,1514242837097,47
-8254,1514243078723,49
-8255,1514243140053,56
-8256,1514243203838,56
-8257,1514243342476,57
-8258,1514243642043,58
-8259,1514244032713,55
-8260,1514244520250,54
-8261,1514244990492,51
-8262,1514245301233,49
-8263,1514245611553,47
-8264,1514245918145,44
-8265,1514246092409,43
-8266,1514246281745,42
-8267,1514246406045,39
-8268,1514246464728,37
-8269,1514246529322,36
-8270,1514246686371,35
-8271,1514246878632,33
-8272,1514246949765,31
-8273,1514247095291,29
-8274,1514247240367,26
-8275,1514247263632,24
-8276,1514247282812,23
-8277,1514247331109,24
-8278,1514247407580,23
-8279,1514247474014,22
-8280,1514247573572,20
-8281,1514247673592,18
-8282,1514247706238,15
-8283,1514247734080,18
-8284,1514247766010,20
-8285,1514247780890,21
-8286,1514247978869,21
-8287,1514248088174,18
-8288,1514248140574,17
-8289,1514248188192,18
-8290,1514248233477,15
-8291,1514248278530,15
-8292,1514248303154,20
-8293,1514248335060,20
-8294,1514248376663,20
-8295,1514248401864,19
-8296,1514248417213,19
-8297,1514248472112,19
-8298,1514248529021,18
-8299,1514248561145,16
-8300,1514248589134,17
-8301,1514248608609,16
-8302,1514248662965,30
-8303,1514248714234,30
-8304,1514248729138,31
-8305,1514248803039,35
-8306,1514248877299,35
-8307,1514248905124,33
-8308,1514248934163,35
-8309,1514248948823,36
-8310,1514248992725,40
-8311,1514249076386,40
-8312,1514249199686,39
-8313,1514249522192,39
-8314,1514249803803,38
-8315,1514249871226,35
-8316,1514249959505,35
-8317,1514250190364,35
-8318,1514250383253,34
-8319,1514250622757,33
-8320,1514250871558,32
-8321,1514250904051,30
-8322,1514250934900,32
-8323,1514250997349,33
-8324,1514251048687,34
-8325,1514251145329,36
-8326,1514251340973,35
-8327,1514251522328,33
-8328,1514251597944,33
-8329,1514251702305,32
-8330,1514251821803,31
-8331,1514251915839,30
-8332,1514252083099,29
-8333,1514252189227,27
-8334,1514252256808,26
-8335,1514252361940,25
-8336,1514252511088,23
-8337,1514252703548,22
-8338,1514252801597,22
-8339,1514252816545,22
-8340,1514252854584,25
-8341,1514252890219,25
-8342,1514252911713,24
-8343,1514252947088,26
-8344,1514252972004,25
-8345,1514253001137,26
-8346,1514253092887,27
-8347,1514253366398,26
-8348,1514253602732,25
-8349,1514253710143,24
-8350,1514253791998,23
-8351,1514253839892,22
-8352,1514253930381,26
-8353,1514254015385,31
-8354,1514254168835,31
-8355,1514254298800,31
-8356,1514254343923,31
-8357,1514254461798,31
-8358,1514254572427,31
-8359,1514254690009,30
-8360,1514254787515,29
-8361,1514254985091,28
-8362,1514255204916,27
-8363,1514255271486,26
-8364,1514255378346,25
-8365,1514255491353,24
-8366,1514255541902,23
-8367,1514255604434,22
-8368,1514255732130,22
-8369,1514255877660,21
-8370,1514255976714,21
-8371,1514256038146,19
-8372,1514256096329,19
-8373,1514256147861,18
-8374,1514256191631,18
-8375,1514256238362,17
-8376,1514256361765,18
-8377,1514256483668,17
-8378,1514256515400,17
-8379,1514256583827,16
-8380,1514256639830,16
-8381,1514256687686,15
-8382,1514256746196,15
-8383,1514256835593,14
-8384,1514256903740,14
-8385,1514256955564,13
-8386,1514256991175,13
-8387,1514256999656,13
-8388,1514257097882,16
-8389,1514257226939,14
-8390,1514257290042,14
-8391,1514257325063,13
-8392,1514257385684,12
-8393,1514257440500,12
-8394,1514257456435,11
-8395,1514257505218,12
-8396,1514257555160,12
-8397,1514257577103,12
-8398,1514257608980,12
-8399,1514257634149,12
-8400,1514257655747,12
-8401,1514257677756,13
-8402,1514257712767,14
-8403,1514257799389,14
-8404,1514257875969,13
-8405,1514257934767,15
-8406,1514258012398,15
-8407,1514258058926,14
-8408,1514258089970,15
-8409,1514258121525,17
-8410,1514258140010,19
-8411,1514258204964,21
-8412,1514258282227,22
-8413,1514258326888,21
-8414,1514258365114,21
-8415,1514258390663,21
-8416,1514258493986,22
-8417,1514258610014,22
-8418,1514258674638,21
-8419,1514258774542,21
-8420,1514258834726,20
-8421,1514258864923,19
-8422,1514258922079,21
-8423,1514258983706,22
-8424,1514259018535,22
-8425,1514259036824,23
-8426,1514259048561,25
-8427,1514259119065,28
-8428,1514259229558,29
-8429,1514259286810,28
-8430,1514259383651,28
-8431,1514259505742,28
-8432,1514259626026,27
-8433,1514259776271,27
-8434,1514259847202,26
-8435,1514260031290,26
-8436,1514260259560,25
-8437,1514260372330,24
-8438,1514260421063,23
-8439,1514260481400,23
-8440,1514260549965,25
-8441,1514260604557,24
-8442,1514260632614,25
-8443,1514260718841,27
-8444,1514260795203,27
-8445,1514260851629,28
-8446,1514260925944,29
-8447,1514261016796,29
-8448,1514261146991,29
-8449,1514261287153,28
-8450,1514261381651,27
-8451,1514261442130,27
-8452,1514261552398,27
-8453,1514261637116,27
-8454,1514261800965,26
-8455,1514261988277,26
-8456,1514262104258,25
-8457,1514262215090,25
-8458,1514262274787,25
-8459,1514262304580,24
-8460,1514262316625,26
-8461,1514262338823,30
-8462,1514262392920,31
-8463,1514262489672,31
-8464,1514262609531,32
-8465,1514262670386,31
-8466,1514262761127,31
-8467,1514262837531,31
-8468,1514262869194,31
-8469,1514262943627,31
-8470,1514263008217,31
-8471,1514263073893,31
-8472,1514263159085,32
-8473,1514263232755,32
-8474,1514263267784,31
-8475,1514263416988,32
-8476,1514263578165,32
-8477,1514263815431,31
-8478,1514264141189,29
-8479,1514264266594,29
-8480,1514264337241,28
-8481,1514264486322,28
-8482,1514264580624,27
-8483,1514264628065,26
-8484,1514264695753,26
-8485,1514264762726,26
-8486,1514264882274,24
-8487,1514265011984,25
-8488,1514265139397,26
-8489,1514265243536,25
-8490,1514265344814,24
-8491,1514265542315,24
-8492,1514265672097,22
-8493,1514265735723,22
-8494,1514265858077,21
-8495,1514265941545,21
-8496,1514265993533,21
-8497,1514266060552,20
-8498,1514266096541,20
-8499,1514266129981,20
-8500,1514266141449,21
-8501,1514266214382,25
-8502,1514266294687,25
-8503,1514266321575,24
-8504,1514266352750,25
-8505,1514266387202,25
-8506,1514266466584,26
-8507,1514266573470,26
-8508,1514266654888,25
-8509,1514266702684,25
-8510,1514266733720,25
-8511,1514266779350,26
-8512,1514266847324,26
-8513,1514267121130,26
-8514,1514267355207,26
-8515,1514267433370,24
-8516,1514267549461,25
-8517,1514267699066,24
-8518,1514267802771,23
-8519,1514267824533,22
-8520,1514267843142,24
-8521,1514267868274,25
-8522,1514267932700,27
-8523,1514268124944,27
-8524,1514268296689,26
-8525,1514268339329,26
-8526,1514268505032,27
-8527,1514268670613,28
-8528,1514268701546,28
-8529,1514268720748,29
-8530,1514268747500,32
-8531,1514268878853,33
-8532,1514269021822,32
-8533,1514269069768,31
-8534,1514269218951,31
-8535,1514269371666,30
-8536,1514269459049,30
-8537,1514269531000,29
-8538,1514269657131,29
-8539,1514269779066,28
-8540,1514269853129,28
-8541,1514270006540,27
-8542,1514270170111,26
-8543,1514270410135,27
-8544,1514270644151,24
-8545,1514270698002,25
-8546,1514270765717,25
-8547,1514270842156,25
-8548,1514270870461,25
-8549,1514270882480,25
-8550,1514270920885,29
-8551,1514270995152,29
-8552,1514271217132,29
-8553,1514271426902,28
-8554,1514271468589,26
-8555,1514271494028,27
-8556,1514271512444,28
-8557,1514271580420,30
-8558,1514271648682,30
-8559,1514271683704,30
-8560,1514271783035,31
-8561,1514271861507,32
-8562,1514271889985,34
-8563,1514272019489,35
-8564,1514272139834,35
-8565,1514272164740,35
-8566,1514272236579,36
-8567,1514272314843,36
-8568,1514272370574,36
-8569,1514272423132,37
-8570,1514272451644,38
-8571,1514272541427,40
-8572,1514272678843,39
-8573,1514272833679,39
-8574,1514272937782,38
-8575,1514273218070,39
-8576,1514273552836,38
-8577,1514273664592,36
-8578,1514273682866,36
-8579,1514273855253,39
-8580,1514274062357,38
-8581,1514274191446,37
-8582,1514274233558,36
-8583,1514274292311,37
-8584,1514274346939,37
-8585,1514274514245,37
-8586,1514274677594,36
-8587,1514274747976,36
-8588,1514274799108,35
-8589,1514274866000,35
-8590,1514274918491,35
-8591,1514275157199,34
-8592,1514275394417,34
-8593,1514275612286,32
-8594,1514275920138,30
-8595,1514276037832,29
-8596,1514276121864,29
-8597,1514276204688,27
-8598,1514276230135,27
-8599,1514276258784,29
-8600,1514276287125,29
-8601,1514276426226,32
-8602,1514276569169,32
-8603,1514276755793,31
-8604,1514276936360,31
-8605,1514277010331,30
-8606,1514277097801,30
-8607,1514277142095,29
-8608,1514277175502,29
-8609,1514277298729,29
-8610,1514277505996,29
-8611,1514277669468,29
-8612,1514277747659,28
-8613,1514277791791,28
-8614,1514277855399,27
-8615,1514277890366,27
-8616,1514277918648,27
-8617,1514277969444,28
-8618,1514278001162,28
-8619,1514278130139,28
-8620,1514278243053,28
-8621,1514278315016,29
-8622,1514278390246,29
-8623,1514278415115,28
-8624,1514278440564,29
-8625,1514278542225,31
-8626,1514278728375,31
-8627,1514278839641,29
-8628,1514278996859,28
-8629,1514279190896,27
-8630,1514279277845,28
-8631,1514279399950,28
-8632,1514279523458,28
-8633,1514279561150,27
-8634,1514279592446,27
-8635,1514279656477,28
-8636,1514279782385,27
-8637,1514279915813,26
-8638,1514280018984,26
-8639,1514280125488,24
-8640,1514280245019,24
-8641,1514280339950,23
-8642,1514280396048,22
-8643,1514280440500,21
-8644,1514280476044,21
-8645,1514280524779,20
-8646,1514280556161,20
-8647,1514280662727,20
-8648,1514280756335,19
-8649,1514280887024,19
-8650,1514280958883,20
-8651,1514281016243,19
-8652,1514281043741,20
-8653,1514281146910,19
-8654,1514281167540,18
-8655,1514281231635,20
-8656,1514281299412,20
-8657,1514281308857,21
-8658,1514281407678,25
-8659,1514281497990,24
-8660,1514281527516,24
-8661,1514281603986,25
-8662,1514281664249,24
-8663,1514281757032,25
-8664,1514281826708,25
-8665,1514281885282,24
-8666,1514281912937,25
-8667,1514281955438,26
-8668,1514282009875,27
-8669,1514282082756,27
-8670,1514282219277,26
-8671,1514282246776,28
-8672,1514282306570,29
-8673,1514282367372,28
-8674,1514282445219,28
-8675,1514282508470,28
-8676,1514282550409,26
-8677,1514282588055,27
-8678,1514282676701,28
-8679,1514282918484,29
-8680,1514282962312,28
-8681,1514283020945,29
-8682,1514283117668,28
-8683,1514283166702,29
-8684,1514283260376,29
-8685,1514283364147,29
-8686,1514283385777,28
-8687,1514283435359,30
-8688,1514283498902,30
-8689,1514283506615,30
-8690,1514283511001,39
-8691,1514283625302,59
-8692,1514283630221,59
-8693,1514283756376,85
-8694,1514283860235,84
-8695,1514284004285,84
-8696,1514284282585,83
-8697,1514284628537,82
-8698,1514284653298,80
-8699,1514284799206,87
-8700,1514285029007,86
-8701,1514285277948,86
-8702,1514285423810,84
-8703,1514285665935,84
-8704,1514285716363,82
-8705,1514285873255,83
-8706,1514286152848,82
-8707,1514286603139,80
-8708,1514287360372,79
-8709,1514287699658,78
-8710,1514287968051,76
-8711,1514288140139,75
-8712,1514288234608,73
-8713,1514288313054,72
-8714,1514288529090,73
-8715,1514288827428,71
-8716,1514289010535,70
-8717,1514289147335,69
-8718,1514289179631,69
-8719,1514289269227,72
-8720,1514289507817,72
-8721,1514289710174,71
-8722,1514289755298,68
-8723,1514289982992,71
-8724,1514290292402,70
-8725,1514290525921,69
-8726,1514290665576,67
-8727,1514290874508,66
-8728,1514291229147,65
-8729,1514291402825,62
-8730,1514291434012,61
-8731,1514291465380,63
-8732,1514291609708,65
-8733,1514291670285,64
-8734,1514291723725,65
-8735,1514291797240,65
-8736,1514291992565,65
-8737,1514292077935,63
-8738,1514292428038,62
-8739,1514292712807,60
-8740,1514292752137,59
-8741,1514292906279,59
-8742,1514293065252,57
-8743,1514293146540,55
-8744,1514293319248,55
-8745,1514293492256,53
-8746,1514293582533,52
-8747,1514293635432,50
-8748,1514293683554,50
-8749,1514293745384,50
-8750,1514293847742,49
-8751,1514293975714,47
-8752,1514294086592,46
-8753,1514294297116,45
-8754,1514294488942,42
-8755,1514294531877,41
-8756,1514294573117,40
-8757,1514294678024,40
-8758,1514294749117,41
-8759,1514294757054,39
-8760,1514294792518,49
-8761,1514294823703,50
-8762,1514294904731,51
-8763,1514295147020,50
-8764,1514295232881,47
-8765,1514295293158,46
-8766,1514295347958,44
-8767,1514295469017,45
-8768,1514295618686,43
-8769,1514295930784,41
-8770,1514296413125,38
-8771,1514296431015,36
-8772,1514296460176,38
-8773,1514296476021,39
-8774,1514296554537,42
-8775,1514296597597,40
-8776,1514296733446,40
-8777,1514296820755,38
-8778,1514296840425,36
-8779,1514296898895,38
-8780,1514297010600,36
-8781,1514297045450,34
-8782,1514297230888,33
-8783,1514297314319,31
-8784,1514297325915,29
-8785,1514297378526,32
-8786,1514297455899,31
-8787,1514297705287,29
-8788,1514297851199,27
-8789,1514298007578,24
-8790,1514298104505,26
-8791,1514298227919,35
-8792,1514298326099,33
-8793,1514298376409,45
-8794,1514298461471,46
-8795,1514298506106,45
-8796,1514298560777,46
-8797,1514298629733,45
-8798,1514298694096,45
-8799,1514298778004,48
-8800,1514298925731,48
-8801,1514299131278,46
-8802,1514299273986,45
-8803,1514299431205,44
-8804,1514299569854,42
-8805,1514299709493,42
-8806,1514299884569,42
-8807,1514300228325,40
-8808,1514300555427,38
-8809,1514300787968,36
-8810,1514301028803,34
-8811,1514301219066,32
-8812,1514301265929,31
-8813,1514301307304,30
-8814,1514301474493,31
-8815,1514301642100,30
-8816,1514301703736,28
-8817,1514301806056,27
-8818,1514301943129,26
-8819,1514302054000,26
-8820,1514302180404,26
-8821,1514302354998,24
-8822,1514302484522,22
-8823,1514302600690,23
-8824,1514302737506,21
-8825,1514302789815,19
-8826,1514302831249,18
-8827,1514302850243,18
-8828,1514302878139,18
-8829,1514302912679,17
-8830,1514302974662,17
-8831,1514303015659,17
-8832,1514303034393,18
-8833,1514303049110,19
-8834,1514303070714,21
-8835,1514303143415,23
-8836,1514303280743,23
-8837,1514303384437,22
-8838,1514303460279,21
-8839,1514303528209,19
-8840,1514303628613,18
-8841,1514303708365,18
-8842,1514303747714,17
-8843,1514303800769,16
-8844,1514303899331,15
-8845,1514303997363,14
-8846,1514304021835,13
-8847,1514304052715,13
-8848,1514304087758,13
-8849,1514304117157,13
-8850,1514304166432,13
-8851,1514304197807,12
-8852,1514304231071,12
-8853,1514304258997,11
-8854,1514304284100,10
-8855,1514304306185,10
-8856,1514304324931,9
-8857,1514304347425,10
-8858,1514304368953,9
-8859,1514304390910,9
-8860,1514304409410,14
-8861,1514304425418,16
-8862,1514304450520,19
-8863,1514304574431,19
-8864,1514304704063,18
-8865,1514304769563,17
-8866,1514304815015,17
-8867,1514304826934,17
-8868,1514304842125,19
-8869,1514304864304,21
-8870,1514304886338,21
-8871,1514305046796,22
-8872,1514305259688,23
-8873,1514305351255,23
-8874,1514305383586,25
-8875,1514305540625,26
-8876,1514305661640,25
-8877,1514305758692,25
-8878,1514305813425,24
-8879,1514305950530,25
-8880,1514306169144,25
-8881,1514306292465,24
-8882,1514306337145,25
-8883,1514306453813,24
-8884,1514306580909,23
-8885,1514306660836,26
-8886,1514306761124,26
-8887,1514306887768,25
-8888,1514306964390,24
-8889,1514307041010,23
-8890,1514307163122,23
-8891,1514307236968,22
-8892,1514307284390,22
-8893,1514307332298,22
-8894,1514307348744,23
-8895,1514307402963,26
-8896,1514307464922,26
-8897,1514307566053,27
-8898,1514307803164,27
-8899,1514307967584,27
-8900,1514307989283,26
-8901,1514308084386,28
-8902,1514308179305,28
-8903,1514308221645,27
-8904,1514308295644,28
-8905,1514308477164,28
-8906,1514308703545,27
-8907,1514308789957,26
-8908,1514308828182,26
-8909,1514309013060,25
-8910,1514309145202,25
-8911,1514309249274,24
-8912,1514309357984,24
-8913,1514309403520,23
-8914,1514309429237,23
-8915,1514309458047,24
-8916,1514309506978,25
-8917,1514309587918,25
-8918,1514309661553,25
-8919,1514309781256,25
-8920,1514309870967,24
-8921,1514310039193,24
-8922,1514310165727,22
-8923,1514310321623,21
-8924,1514310465374,21
-8925,1514310542027,19
-8926,1514310557719,19
-8927,1514310647665,21
-8928,1514310732027,21
-8929,1514310773858,21
-8930,1514310808582,21
-8931,1514310996400,21
-8932,1514311309439,20
-8933,1514311478880,21
-8934,1514311520285,21
-8935,1514311600937,22
-8936,1514311708351,21
-8937,1514311768801,20
-8938,1514311820324,21
-8939,1514311878630,21
-8940,1514311939813,21
-8941,1514311977604,20
-8942,1514311996002,19
-8943,1514312026947,21
-8944,1514312188579,22
-8945,1514312334781,21
-8946,1514312418520,20
-8947,1514312486102,20
-8948,1514312511624,19
-8949,1514312609622,20
-8950,1514312732181,20
-8951,1514312871420,19
-8952,1514312978921,19
-8953,1514313059988,18
-8954,1514313150430,17
-8955,1514313194919,17
-8956,1514313248521,17
-8957,1514313335098,17
-8958,1514313410148,16
-8959,1514313439341,16
-8960,1514313480247,16
-8961,1514313536000,16
-8962,1514313590852,17
-8963,1514313634632,18
-8964,1514313692631,17
-8965,1514313806341,17
-8966,1514313893304,17
-8967,1514313924684,16
-8968,1514313980758,18
-8969,1514314028431,18
-8970,1514314093682,19
-8971,1514314157635,20
-8972,1514314176615,20
-8973,1514314202418,20
-8974,1514314344792,22
-8975,1514314505011,22
-8976,1514314542587,21
-8977,1514314574654,21
-8978,1514314619454,22
-8979,1514314660442,22
-8980,1514314682357,23
-8981,1514314766776,23
-8982,1514314804365,23
-8983,1514314816519,24
-8984,1514314869232,28
-8985,1514315000143,28
-8986,1514315090899,27
-8987,1514315146035,27
-8988,1514315230161,26
-8989,1514315381221,27
-8990,1514315537481,25
-8991,1514315605894,25
-8992,1514315653925,25
-8993,1514315699680,26
-8994,1514315864174,26
-8995,1514316083955,26
-8996,1514316219937,26
-8997,1514316302615,26
-8998,1514316392744,25
-8999,1514316505872,24
-9000,1514316567580,23
-9001,1514316625668,25
-9002,1514316679444,25
-9003,1514316734510,25
-9004,1514316832432,25
-9005,1514316889812,25
-9006,1514317031745,25
-9007,1514317086931,24
-9008,1514317176778,24
-9009,1514317268917,24
-9010,1514317322524,23
-9011,1514317373268,23
-9012,1514317401893,24
-9013,1514317430290,25
-9014,1514317572885,26
-9015,1514317759733,26
-9016,1514317863238,26
-9017,1514318006272,26
-9018,1514318106435,25
-9019,1514318196872,25
-9020,1514318349313,25
-9021,1514318473389,24
-9022,1514318557096,22
-9023,1514318598952,22
-9024,1514318637806,21
-9025,1514318689002,22
-9026,1514318846414,23
-9027,1514318992158,23
-9028,1514319004889,22
-9029,1514319072754,25
-9030,1514319224156,26
-9031,1514319328766,25
-9032,1514319372969,25
-9033,1514319408179,25
-9034,1514319566708,25
-9035,1514319642135,24
-9036,1514319703703,24
-9037,1514319787246,24
-9038,1514320004071,24
-9039,1514320266399,22
-9040,1514320366924,22
-9041,1514320405521,22
-9042,1514320466065,22
-9043,1514320560402,23
-9044,1514320736461,23
-9045,1514320902674,21
-9046,1514320941171,22
-9047,1514320962671,21
-9048,1514321035232,23
-9049,1514321111068,23
-9050,1514321135984,23
-9051,1514321202286,23
-9052,1514321295080,23
-9053,1514321366687,23
-9054,1514321510025,23
-9055,1514321704605,22
-9056,1514321801596,21
-9057,1514321832978,20
-9058,1514321962006,21
-9059,1514322091916,20
-9060,1514322130768,20
-9061,1514322168486,20
-9062,1514322205958,20
-9063,1514322238008,20
-9064,1514322328891,21
-9065,1514322420034,20
-9066,1514322441573,19
-9067,1514322460416,21
-9068,1514322518791,23
-9069,1514322609178,22
-9070,1514322664987,22
-9071,1514322734340,21
-9072,1514322797381,21
-9073,1514322852838,22
-9074,1514322936746,22
-9075,1514323018313,22
-9076,1514323092751,21
-9077,1514323143813,20
-9078,1514323182331,21
-9079,1514323276948,22
-9080,1514323357996,21
-9081,1514323373562,21
-9082,1514323394747,24
-9083,1514323412949,26
-9084,1514323496413,30
-9085,1514323600856,30
-9086,1514323639461,30
-9087,1514323875066,31
-9088,1514324283162,30
-9089,1514324479033,29
-9090,1514324797252,29
-9091,1514325094659,27
-9092,1514325297401,27
-9093,1514325483028,26
-9094,1514325534626,25
-9095,1514325583172,26
-9096,1514325615230,26
-9097,1514325662361,27
-9098,1514325777227,27
-9099,1514325877637,26
-9100,1514325944873,25
-9101,1514326006382,26
-9102,1514326039476,25
-9103,1514326073920,27
-9104,1514326128079,27
-9105,1514326220184,28
-9106,1514326350915,27
-9107,1514326459085,26
-9108,1514326516036,26
-9109,1514326557008,27
-9110,1514326642247,26
-9111,1514326715915,26
-9112,1514326877437,26
-9113,1514326996631,26
-9114,1514327040706,26
-9115,1514327124345,26
-9116,1514327331535,26
-9117,1514327482779,25
-9118,1514327526624,24
-9119,1514327637556,25
-9120,1514327924911,24
-9121,1514328149065,23
-9122,1514328170931,22
-9123,1514328192989,23
-9124,1514328358452,25
-9125,1514328538324,24
-9126,1514328637480,24
-9127,1514328710059,23
-9128,1514328798109,22
-9129,1514328927542,24
-9130,1514329037505,22
-9131,1514329073536,22
-9132,1514329099015,22
-9133,1514329127274,24
-9134,1514329175361,26
-9135,1514329255029,25
-9136,1514329372667,25
-9137,1514329485792,25
-9138,1514329570004,24
-9139,1514329640918,24
-9140,1514329686052,23
-9141,1514329737393,23
-9142,1514329801940,23
-9143,1514329995042,23
-9144,1514330160959,22
-9145,1514330176172,21
-9146,1514330204981,23
-9147,1514330240669,25
-9148,1514330331134,26
-9149,1514330448595,26
-9150,1514330610948,23
-9151,1514330781857,24
-9152,1514330918598,24
-9153,1514331046705,23
-9154,1514331164846,22
-9155,1514331245375,22
-9156,1514331302586,21
-9157,1514331363181,20
-9158,1514331559636,21
-9159,1514331825864,19
-9160,1514331945825,18
-9161,1514332015424,18
-9162,1514332076389,17
-9163,1514332124779,18
-9164,1514332189795,18
-9165,1514332263405,17
-9166,1514332315153,17
-9167,1514332368011,17
-9168,1514332412508,18
-9169,1514332460794,18
-9170,1514332495274,18
-9171,1514332553484,18
-9172,1514332638211,18
-9173,1514332708876,17
-9174,1514332750953,17
-9175,1514332798448,17
-9176,1514332810359,17
-9177,1514332864347,19
-9178,1514332909042,20
-9179,1514332967157,20
-9180,1514333011410,19
-9181,1514333034387,19
-9182,1514333062937,21
-9183,1514333143769,23
-9184,1514333238089,24
-9185,1514333334483,23
-9186,1514333479697,24
-9187,1514333637951,23
-9188,1514333759501,22
-9189,1514333862387,21
-9190,1514333932736,21
-9191,1514334003161,21
-9192,1514334093439,20
-9193,1514334164412,19
-9194,1514334303845,19
-9195,1514334433789,18
-9196,1514334497727,18
-9197,1514334603757,18
-9198,1514334708524,18
-9199,1514334766465,18
-9200,1514334830825,17
-9201,1514334891447,17
-9202,1514334920001,17
-9203,1514335011513,18
-9204,1514335023694,18
-9205,1514335116865,21
-9206,1514335236031,21
-9207,1514335272920,20
-9208,1514335291853,20
-9209,1514335346998,22
-9210,1514335452925,22
-9211,1514335583022,22
-9212,1514335722834,21
-9213,1514335834904,21
-9214,1514335922321,20
-9215,1514336045175,20
-9216,1514336193516,19
-9217,1514336297757,19
-9218,1514336345372,18
-9219,1514336387874,18
-9220,1514336477853,18
-9221,1514336557861,18
-9222,1514336619962,17
-9223,1514336667805,17
-9224,1514336732545,19
-9225,1514336839907,18
-9226,1514336923798,17
-9227,1514336935920,17
-9228,1514337059794,19
-9229,1514337195288,19
-9230,1514337231867,18
-9231,1514337256740,18
-9232,1514337307873,19
-9233,1514337361760,20
-9234,1514337383644,21
-9235,1514337477265,22
-9236,1514337572113,23
-9237,1514337594134,22
-9238,1514337612662,23
-9239,1514337647276,25
-9240,1514337714764,26
-9241,1514337835274,26
-9242,1514337932704,26
-9243,1514337994591,26
-9244,1514338191126,26
-9245,1514338366856,24
-9246,1514338444598,25
-9247,1514338772822,26
-9248,1514339053132,25
-9249,1514339128438,25
-9250,1514339199645,25
-9251,1514339238187,25
-9252,1514339283002,25
-9253,1514339351023,25
-9254,1514339409586,25
-9255,1514339480613,24
-9256,1514339544830,24
-9257,1514339589133,25
-9258,1514339627650,25
-9259,1514339690028,26
-9260,1514339741230,25
-9261,1514339750083,25
-9262,1514339897726,31
-9263,1514339919845,31
-9264,1514339989581,33
-9265,1514340053757,32
-9266,1514340201069,32
-9267,1514340358828,32
-9268,1514340488947,31
-9269,1514340654877,31
-9270,1514340726089,30
-9271,1514340814981,30
-9272,1514341001699,30
-9273,1514341263677,29
-9274,1514341445873,29
-9275,1514341497010,27
-9276,1514341543789,27
-9277,1514341595160,30
-9278,1514341660151,29
-9279,1514341725126,30
-9280,1514341915638,30
-9281,1514342097242,30
-9282,1514342125854,29
-9283,1514342220957,31
-9284,1514342335548,31
-9285,1514342459475,30
-9286,1514342572915,29
-9287,1514342623831,29
-9288,1514342662777,29
-9289,1514342700681,30
-9290,1514342862646,31
-9291,1514343056860,30
-9292,1514343113001,29
-9293,1514343187423,29
-9294,1514343278816,29
-9295,1514343314019,28
-9296,1514343363558,29
-9297,1514343420404,29
-9298,1514343598942,29
-9299,1514343851364,28
-9300,1514343961143,27
-9301,1514344010024,26
-9302,1514344060168,27
-9303,1514344191858,27
-9304,1514344384198,26
-9305,1514344568203,27
-9306,1514344701180,26
-9307,1514344729672,25
-9308,1514344748176,27
-9309,1514344763734,29
-9310,1514344803584,33
-9311,1514344851238,34
-9312,1514344931980,33
-9313,1514345116739,33
-9314,1514345242289,32
-9315,1514345352325,32
-9316,1514345642068,31
-9317,1514345957234,30
-9318,1514346176779,28
-9319,1514346358490,27
-9320,1514346492173,26
-9321,1514346590589,25
-9322,1514346654257,25
-9323,1514346755810,24
-9324,1514346848092,24
-9325,1514346856856,23
-9326,1514346902500,27
-9327,1514346967931,28
-9328,1514347084818,30
-9329,1514347200212,28
-9330,1514347267872,27
-9331,1514347471650,27
-9332,1514347660402,27
-9333,1514347747016,26
-9334,1514347834906,26
-9335,1514347925099,25
-9336,1514348000296,25
-9337,1514348061052,24
-9338,1514348109395,24
-9339,1514348159794,26
-9340,1514348197660,26
-9341,1514348237721,27
-9342,1514348253237,28
-9343,1514348416645,30
-9344,1514348664659,29
-9345,1514348758339,28
-9346,1514348839437,28
-9347,1514348948635,27
-9348,1514349058822,26
-9349,1514349133534,25
-9350,1514349196002,24
-9351,1514349290570,24
-9352,1514349363313,24
-9353,1514349416769,23
-9354,1514349504989,23
-9355,1514349743487,23
-9356,1514349937595,22
-9357,1514350089352,21
-9358,1514350229620,21
-9359,1514350319931,20
-9360,1514350542077,19
-9361,1514350766854,18
-9362,1514350847294,21
-9363,1514350930581,20
-9364,1514351021437,21
-9365,1514351056261,21
-9366,1514351088290,21
-9367,1514351143275,22
-9368,1514351305519,22
-9369,1514351480856,21
-9370,1514351534653,20
-9371,1514351569044,19
-9372,1514351605299,20
-9373,1514351646443,20
-9374,1514351670876,20
-9375,1514351731362,20
-9376,1514351759693,20
-9377,1514351801024,22
-9378,1514351861767,22
-9379,1514351909669,22
-9380,1514351997127,21
-9381,1514352073416,21
-9382,1514352275300,21
-9383,1514352444742,20
-9384,1514352515601,20
-9385,1514352572959,19
-9386,1514352688808,19
-9387,1514352826167,18
-9388,1514352923189,18
-9389,1514352987126,18
-9390,1514353027795,17
-9391,1514353201907,18
-9392,1514353239646,16
-9393,1514353287379,16
-9394,1514353313722,17
-9395,1514353364242,17
-9396,1514353447566,18
-9397,1514353489888,17
-9398,1514353548851,17
-9399,1514353583331,17
-9400,1514353663808,17
-9401,1514353730682,16
-9402,1514353759163,16
-9403,1514353920448,17
-9404,1514354008967,16
-9405,1514354097017,15
-9406,1514354116884,14
-9407,1514354129856,15
-9408,1514354158479,17
-9409,1514354243138,18
-9410,1514354315295,20
-9411,1514354327292,20
-9412,1514354335915,24
-9413,1514354614055,29
-9414,1514354651948,29
-9415,1514354677959,29
-9416,1514354726244,31
-9417,1514354832358,31
-9418,1514354967964,31
-9419,1514355038211,29
-9420,1514355083382,29
-9421,1514355173932,30
-9422,1514355389760,29
-9423,1514355596982,29
-9424,1514355719055,28
-9425,1514355793404,27
-9426,1514355855506,29
-9427,1514355923201,30
-9428,1514356004612,30
-9429,1514356157613,29
-9430,1514356257051,29
-9431,1514356308353,29
-9432,1514356432589,29
-9433,1514356591318,28
-9434,1514356772324,28
-9435,1514356908596,27
-9436,1514356944195,26
-9437,1514357060215,27
-9438,1514357237245,26
-9439,1514357382030,26
-9440,1514357423444,25
-9441,1514357458860,26
-9442,1514357522584,27
-9443,1514357544519,29
-9444,1514357590236,31
-9445,1514357652500,32
-9446,1514357699641,31
-9447,1514357757153,32
-9448,1514357867959,32
-9449,1514357981981,32
-9450,1514358039788,32
-9451,1514358075410,32
-9452,1514358172869,33
-9453,1514358314136,33
-9454,1514358387871,32
-9455,1514358419909,32
-9456,1514358461039,33
-9457,1514358486386,34
-9458,1514358528499,35
-9459,1514358567131,36
-9460,1514358593860,37
-9461,1514358619197,38
-9462,1514358679224,40
-9463,1514358768955,41
-9464,1514358942625,40
-9465,1514359178154,40
-9466,1514359295838,38
-9467,1514359338729,38
-9468,1514359399869,39
-9469,1514359445053,39
-9470,1514359518286,40
-9471,1514359613438,40
-9472,1514359792308,39
-9473,1514359959167,38
-9474,1514360003863,38
-9475,1514360124261,39
-9476,1514360315628,39
-9477,1514360490950,38
-9478,1514360597942,38
-9479,1514360632560,37
-9480,1514360681345,39
-9481,1514360722177,40
-9482,1514360779650,40
-9483,1514360860345,39
-9484,1514360908637,39
-9485,1514360998741,39
-9486,1514361121638,39
-9487,1514361186076,38
-9488,1514361231296,38
-9489,1514361258987,39
-9490,1514361536856,41
-9491,1514361717230,39
-9492,1514361843939,38
-9493,1514361996778,37
-9494,1514362129347,36
-9495,1514362305712,35
-9496,1514362426237,34
-9497,1514362451473,33
-9498,1514362515287,35
-9499,1514362577338,34
-9500,1514362699008,35
-9501,1514362768306,34
-9502,1514362826697,33
-9503,1514363114859,33
-9504,1514363434072,32
-9505,1514363508999,30
-9506,1514363553383,29
-9507,1514363668625,29
-9508,1514363817983,30
-9509,1514363931213,29
-9510,1514363994735,27
-9511,1514364103139,27
-9512,1514364420924,27
-9513,1514364675565,29
-9514,1514364790325,28
-9515,1514364980971,28
-9516,1514365107773,28
-9517,1514365417177,27
-9518,1514365756330,26
-9519,1514365834907,24
-9520,1514365874023,24
-9521,1514365925641,25
-9522,1514365966929,25
-9523,1514366078511,24
-9524,1514366246632,24
-9525,1514366372848,22
-9526,1514366436882,21
-9527,1514366501360,21
-9528,1514366536993,21
-9529,1514366605697,21
-9530,1514366779524,20
-9531,1514367062106,19
-9532,1514367221510,18
-9533,1514367262944,17
-9534,1514367346127,17
-9535,1514367423360,15
-9536,1514367477477,14
-9537,1514367542299,14
-9538,1514367577028,13
-9539,1514367631829,12
-9540,1514367683074,11
-9541,1514367691930,11
-9542,1514367760190,13
-9543,1514367775415,12
-9544,1514367797551,14
-9545,1514367848695,15
-9546,1514367962377,15
-9547,1514368086453,14
-9548,1514368139507,13
-9549,1514368161256,12
-9550,1514368182564,12
-9551,1514368233950,13
-9552,1514368288885,13
-9553,1514368308418,12
-9554,1514368330049,12
-9555,1514368357795,12
-9556,1514368405682,13
-9557,1514368507048,13
-9558,1514368577895,14
-9559,1514368641632,13
-9560,1514368710426,13
-9561,1514368728970,14
-9562,1514368773681,17
-9563,1514368847904,16
-9564,1514368915547,16
-9565,1514369026129,16
-9566,1514369172231,15
-9567,1514369265676,14
-9568,1514369326552,14
-9569,1514369404643,14
-9570,1514369493838,13
-9571,1514369556275,14
-9572,1514369620773,13
-9573,1514369730785,13
-9574,1514369901319,12
-9575,1514370002096,12
-9576,1514370036523,11
-9577,1514370080964,11
-9578,1514370105892,10
-9579,1514370193817,11
-9580,1514370271058,11
-9581,1514370302535,11
-9582,1514370377790,11
-9583,1514370428718,12
-9584,1514370506753,12
-9585,1514370594685,11
-9586,1514370655035,11
-9587,1514370714027,12
-9588,1514370751916,11
-9589,1514370783842,12
-9590,1514370802843,14
-9591,1514370817555,14
-9592,1514370830569,16
-9593,1514370842709,18
-9594,1514370861359,21
-9595,1514370876643,23
-9596,1514370921967,25
-9597,1514370966388,25
-9598,1514371002193,27
-9599,1514371042855,29
-9600,1514371116579,29
-9601,1514371236568,29
-9602,1514371345487,30
-9603,1514371454582,30
-9604,1514371550997,29
-9605,1514371591805,29
-9606,1514371619927,29
-9607,1514371734720,31
-9608,1514372012393,30
-9609,1514372223712,30
-9610,1514372297900,30
-9611,1514372350165,29
-9612,1514372594711,30
-9613,1514372846544,29
-9614,1514372894485,28
-9615,1514372935766,29
-9616,1514372973880,29
-9617,1514373009267,30
-9618,1514373106078,30
-9619,1514373201251,30
-9620,1514373253026,29
-9621,1514373336583,30
-9622,1514373521620,31
-9623,1514373727094,31
-9624,1514373828854,30
-9625,1514373894278,29
-9626,1514373984594,29
-9627,1514374098665,28
-9628,1514374166532,28
-9629,1514374313518,29
-9630,1514374623994,29
-9631,1514374867122,27
-9632,1514374948216,27
-9633,1514374986231,26
-9634,1514375013959,27
-9635,1514375102623,28
-9636,1514375186532,27
-9637,1514375347009,27
-9638,1514375531031,26
-9639,1514375568446,26
-9640,1514375622338,26
-9641,1514375676813,26
-9642,1514375692039,28
-9643,1514375752340,30
-9644,1514375814700,31
-9645,1514375835639,31
-9646,1514375923023,34
-9647,1514376007253,33
-9648,1514376094201,34
-9649,1514376215857,33
-9650,1514376280490,33
-9651,1514376318740,33
-9652,1514376376527,33
-9653,1514376421233,34
-9654,1514376502360,35
-9655,1514376627848,35
-9656,1514376748319,35
-9657,1514376822051,35
-9658,1514376960711,34
-9659,1514377233807,33
-9660,1514377490642,32
-9661,1514377661734,31
-9662,1514377775782,31
-9663,1514377830266,30
-9664,1514377857721,30
-9665,1514378040023,33
-9666,1514378104159,31
-9667,1514378152866,30
-9668,1514378193880,31
-9669,1514378271675,31
-9670,1514378338424,31
-9671,1514378441671,31
-9672,1514378518337,29
-9673,1514378543174,29
-9674,1514378600485,31
-9675,1514378661672,30
-9676,1514378696170,29
-9677,1514378718833,31
-9678,1514378770240,33
-9679,1514378834858,33
-9680,1514378866784,32
-9681,1514378900994,33
-9682,1514378981291,34
-9683,1514379146226,33
-9684,1514379283432,32
-9685,1514379387248,31
-9686,1514379512989,30
-9687,1514379581617,29
-9688,1514379619657,28
-9689,1514379657863,28
-9690,1514379693830,29
-9691,1514379754752,30
-9692,1514379868367,30
-9693,1514379989223,29
-9694,1514380043626,31
-9695,1514380205239,32
-9696,1514380567870,33
-9697,1514380795313,32
-9698,1514380854707,31
-9699,1514380909230,32
-9700,1514380924795,32
-9701,1514381112822,36
-9702,1514381286909,35
-9703,1514381377104,34
-9704,1514381448276,33
-9705,1514381500172,33
-9706,1514381539255,33
-9707,1514381570859,35
-9708,1514381586103,36
-9709,1514381668711,40
-9710,1514381809809,40
-9711,1514381910386,39
-9712,1514382090722,39
-9713,1514382274213,37
-9714,1514382413703,36
-9715,1514382555608,36
-9716,1514382594572,36
-9717,1514382715403,37
-9718,1514382765548,36
-9719,1514382780309,37
-9720,1514382808910,41
-9721,1514382867060,44
-9722,1514383009843,44
-9723,1514383165690,43
-9724,1514383247268,42
-9725,1514383348351,41
-9726,1514383388904,41
-9727,1514383493385,41
-9728,1514383638700,41
-9729,1514383711840,40
-9730,1514383886501,39
-9731,1514384160926,38
-9732,1514384194215,37
-9733,1514384290653,37
-9734,1514384338202,37
-9735,1514384389351,38
-9736,1514384438023,38
-9737,1514384507431,38
-9738,1514384515284,38
-9739,1514384530536,48
-9740,1514384542207,53
-9741,1514384712354,63
-9742,1514384897673,62
-9743,1514384967820,62
-9744,1514385242726,63
-9745,1514385353218,61
-9746,1514385578546,62
-9747,1514385800605,60
-9748,1514386152534,59
-9749,1514386417520,58
-9750,1514386504104,56
-9751,1514386637201,56
-9752,1514386727278,56
-9753,1514386892098,55
-9754,1514387256186,55
-9755,1514387629335,53
-9756,1514387673605,52
-9757,1514387709570,52
-9758,1514387770556,54
-9759,1514387864938,54
-9760,1514388007078,53
-9761,1514388113027,52
-9762,1514388240411,50
-9763,1514388724365,50
-9764,1514388847458,48
-9765,1514388897468,48
-9766,1514388975011,48
-9767,1514389109315,47
-9768,1514389166222,46
-9769,1514389640297,47
-9770,1514389681558,45
-9771,1514389841880,45
-9772,1514389900751,45
-9773,1514390005588,44
-9774,1514390156507,44
-9775,1514390387703,43
-9776,1514390518053,42
-9777,1514390723401,41
-9778,1514390946896,41
-9779,1514391029999,40
-9780,1514391058127,38
-9781,1514391080082,41
-9782,1514391150059,45
-9783,1514391259211,44
-9784,1514391344783,42
-9785,1514391472252,41
-9786,1514391553487,39
-9787,1514391622530,40
-9788,1514391838320,39
-9789,1514391872464,37
-9790,1514391953768,39
-9791,1514392153066,38
-9792,1514392267196,37
-9793,1514392313037,35
-9794,1514392380067,35
-9795,1514392486284,35
-9796,1514392616399,33
-9797,1514392693545,32
-9798,1514392742538,31
-9799,1514392790665,30
-9800,1514392828517,30
-9801,1514392847113,32
-9802,1514392909000,33
-9803,1514393013448,33
-9804,1514393198042,32
-9805,1514393346109,30
-9806,1514393498327,29
-9807,1514393666074,28
-9808,1514393783739,27
-9809,1514394048026,28
-9810,1514394310271,26
-9811,1514394486139,25
-9812,1514394588809,23
-9813,1514394634769,22
-9814,1514394674369,21
-9815,1514394832158,20
-9816,1514395010361,19
-9817,1514395074537,17
-9818,1514395120158,16
-9819,1514395159889,15
-9820,1514395205434,17
-9821,1514395233919,17
-9822,1514395282731,18
-9823,1514395328288,17
-9824,1514395342971,16
-9825,1514395358790,17
-9826,1514395374280,19
-9827,1514395411575,20
-9828,1514395498816,20
-9829,1514395602938,18
-9830,1514395691584,17
-9831,1514395740083,15
-9832,1514395778331,15
-9833,1514395811144,15
-9834,1514395826481,14
-9835,1514395911650,15
-9836,1514395953543,13
-9837,1514396030669,14
-9838,1514396108684,12
-9839,1514396128066,17
-9840,1514396141179,20
-9841,1514396168682,28
-9842,1514396228769,29
-9843,1514396291706,29
-9844,1514396325635,28
-9845,1514396393254,29
-9846,1514396460348,29
-9847,1514396496200,29
-9848,1514396604765,30
-9849,1514396734914,28
-9850,1514396816030,28
-9851,1514396903808,27
-9852,1514396983930,27
-9853,1514397032868,27
-9854,1514397061605,26
-9855,1514397099853,27
-9856,1514397148411,27
-9857,1514397189327,28
-9858,1514397275614,30
-9859,1514397387348,29
-9860,1514397440093,28
-9861,1514397481751,29
-9862,1514397577384,30
-9863,1514397664533,29
-9864,1514397758326,28
-9865,1514397904705,27
-9866,1514398050422,27
-9867,1514398207013,26
-9868,1514398374748,26
-9869,1514398471980,25
-9870,1514398549077,24
-9871,1514398638232,25
-9872,1514398691521,24
-9873,1514398766326,25
-9874,1514398821781,24
-9875,1514398880184,23
-9876,1514398938887,23
-9877,1514398980172,22
-9878,1514399066947,22
-9879,1514399134381,22
-9880,1514399172728,21
-9881,1514399198223,22
-9882,1514399209873,25
-9883,1514399258750,30
-9884,1514399330478,30
-9885,1514399361013,30
-9886,1514399558629,31
-9887,1514399757711,30
-9888,1514399875897,29
-9889,1514400009529,29
-9890,1514400136117,29
-9891,1514400210708,28
-9892,1514400391897,28
-9893,1514400595615,27
-9894,1514400639834,27
-9895,1514400690597,27
-9896,1514400702541,27
-9897,1514400792797,30
-9898,1514400896952,31
-9899,1514400991298,30
-9900,1514401064948,29
-9901,1514401080285,30
-9902,1514401131708,36
-9903,1514401289051,35
-9904,1514401418842,35
-9905,1514401450447,34
-9906,1514401633400,35
-9907,1514401819486,35
-9908,1514401889596,33
-9909,1514401982200,33
-9910,1514402052617,32
-9911,1514402119272,32
-9912,1514402216755,31
-9913,1514402311790,30
-9914,1514402352901,30
-9915,1514402449539,30
-9916,1514402552716,29
-9917,1514402594473,29
-9918,1514402642584,29
-9919,1514402769587,29
-9920,1514402926187,29
-9921,1514403019488,27
-9922,1514403076784,27
-9923,1514403268085,27
-9924,1514403462399,25
-9925,1514403507027,25
-9926,1514403539413,26
-9927,1514403661096,27
-9928,1514403780392,28
-9929,1514403930756,27
-9930,1514404080216,26
-9931,1514404118338,24
-9932,1514404179105,25
-9933,1514404221788,25
-9934,1514404256899,25
-9935,1514404282763,26
-9936,1514404401336,27
-9937,1514404517673,26
-9938,1514404611908,25
-9939,1514404624222,24
-9940,1514404659044,28
-9941,1514404680904,30
-9942,1514405028407,33
-9943,1514405143405,31
-9944,1514405234650,31
-9945,1514405372131,32
-9946,1514405512820,30
-9947,1514405583526,30
-9948,1514405618204,30
-9949,1514405738648,31
-9950,1514405848280,30
-9951,1514405915640,29
-9952,1514405947819,29
-9953,1514406086722,30
-9954,1514406257966,29
-9955,1514406313463,29
-9956,1514406344591,29
-9957,1514406380858,31
-9958,1514406448154,32
-9959,1514406564787,32
-9960,1514406649088,31
-9961,1514406707348,31
-9962,1514406765549,31
-9963,1514406784228,31
-9964,1514406881675,34
-9965,1514407033267,33
-9966,1514407150526,32
-9967,1514407230476,32
-9968,1514407355148,31
-9969,1514407478781,30
-9970,1514407673795,29
-9971,1514407806644,27
-9972,1514407869658,27
-9973,1514407982817,27
-9974,1514408082403,26
-9975,1514408175545,25
-9976,1514408275825,24
-9977,1514408350941,24
-9978,1514408438362,23
-9979,1514408538444,22
-9980,1514408682794,21
-9981,1514408801587,21
-9982,1514408830316,20
-9983,1514408845553,24
-9984,1514408886819,26
-9985,1514408932150,26
-9986,1514408982829,28
-9987,1514409046577,27
-9988,1514409091363,26
-9989,1514409122360,26
-9990,1514409203316,27
-9991,1514409281285,27
-9992,1514409472510,26
-9993,1514409730612,25
-9994,1514409852381,23
-9995,1514409943516,23
-9996,1514410034656,22
-9997,1514410070174,24
-9998,1514410159878,24
-9999,1514410247246,23
-10000,1514410276121,23
-10001,1514410304182,23
-10002,1514410434830,27
-10003,1514410542793,27
-10004,1514410719931,25
-10005,1514410836146,24
-10006,1514410931825,25
-10007,1514410950819,24
-10008,1514410974277,26
-10009,1514411015579,27
-10010,1514411094459,27
-10011,1514411163992,28
-10012,1514411227989,28
-10013,1514411354201,26
-10014,1514411441178,26
-10015,1514411482349,26
-10016,1514411540138,27
-10017,1514411702553,27
-10018,1514411890592,26
-10019,1514411960835,25
-10020,1514411988857,25
-10021,1514412014064,25
-10022,1514412033445,27
-10023,1514412064886,29
-10024,1514412155452,29
-10025,1514412222227,28
-10026,1514412313244,29
-10027,1514412610368,29
-10028,1514412851337,28
-10029,1514412909010,26
-10030,1514412931554,26
-10031,1514412972708,27
-10032,1514413033206,27
-10033,1514413090260,27
-10034,1514413177034,27
-10035,1514413413792,27
-10036,1514413616567,27
-10037,1514413727560,26
-10038,1514413829585,26
-10039,1514413993888,24
-10040,1514414199823,25
-10041,1514414312258,25
-10042,1514414411089,26
-10043,1514414482124,25
-10044,1514414526694,25
-10045,1514414565235,25
-10046,1514414650063,25
-10047,1514414733411,24
-10048,1514414808535,24
-10049,1514414909320,24
-10050,1514414972861,24
-10051,1514415046331,24
-10052,1514415144918,23
-10053,1514415224558,23
-10054,1514415282238,23
-10055,1514415310837,22
-10056,1514415325700,22
-10057,1514415348243,26
-10058,1514415424957,28
-10059,1514415554317,28
-10060,1514415655675,28
-10061,1514415703786,26
-10062,1514415725000,27
-10063,1514415747569,29
-10064,1514415862785,32
-10065,1514416031690,32
-10066,1514416165529,31
-10067,1514416242073,30
-10068,1514416393029,30
-10069,1514416567231,29
-10070,1514416638503,28
-10071,1514416697916,28
-10072,1514416735639,28
-10073,1514416778851,29
-10074,1514416900977,29
-10075,1514417062673,27
-10076,1514417309881,27
-10077,1514417522793,26
-10078,1514417781416,25
-10079,1514418033924,24
-10080,1514418077859,22
-10081,1514418117217,22
-10082,1514418244116,23
-10083,1514418497608,22
-10084,1514418648972,22
-10085,1514418723514,22
-10086,1514418808086,22
-10087,1514418879992,22
-10088,1514418957318,21
-10089,1514419054773,21
-10090,1514419188242,22
-10091,1514419317797,21
-10092,1514419369819,20
-10093,1514419441904,20
-10094,1514419548553,19
-10095,1514419656502,18
-10096,1514419744525,17
-10097,1514419802400,17
-10098,1514419863523,16
-10099,1514419936464,16
-10100,1514420034580,15
-10101,1514420154046,15
-10102,1514420219362,15
-10103,1514420303601,15
-10104,1514420420247,14
-10105,1514420465950,13
-10106,1514420599120,13
-10107,1514420677012,11
-10108,1514420719586,12
-10109,1514420756913,12
-10110,1514420791720,13
-10111,1514420817174,13
-10112,1514420842657,13
-10113,1514420861446,14
-10114,1514420870280,14
-10115,1514420885540,17
-10116,1514421035188,19
-10117,1514421224653,18
-10118,1514421298348,17
-10119,1514421340360,17
-10120,1514421369325,17
-10121,1514421385743,17
-10122,1514421475954,20
-10123,1514421491344,21
-10124,1514421516287,23
-10125,1514421583908,25
-10126,1514421691856,25
-10127,1514421749733,25
-10128,1514421797138,24
-10129,1514421844155,25
-10130,1514421872699,25
-10131,1514421903977,26
-10132,1514421922518,28
-10133,1514421940521,30
-10134,1514421965157,34
-10135,1514422036799,36
-10136,1514422197143,36
-10137,1514422359167,35
-10138,1514422430430,35
-10139,1514422475932,34
-10140,1514422513704,34
-10141,1514422551452,35
-10142,1514422620782,36
-10143,1514422705306,36
-10144,1514422779720,36
-10145,1514422956073,36
-10146,1514423132924,35
-10147,1514423160728,35
-10148,1514423250709,36
-10149,1514423288160,36
-10150,1514423770276,37
-10151,1514424257263,36
-10152,1514424501305,34
-10153,1514424578717,34
-10154,1514424683868,34
-10155,1514424807113,33
-10156,1514424891499,33
-10157,1514424972315,34
-10158,1514425092659,34
-10159,1514425224850,35
-10160,1514425320785,34
-10161,1514425362203,33
-10162,1514425383542,34
-10163,1514425405280,38
-10164,1514425553333,42
-10165,1514425891557,42
-10166,1514426159550,40
-10167,1514426310290,39
-10168,1514426397802,39
-10169,1514426417531,39
-10170,1514426503579,42
-10171,1514426597195,42
-10172,1514426779020,42
-10173,1514426958422,41
-10174,1514427048322,41
-10175,1514427142603,41
-10176,1514427222463,40
-10177,1514427388216,40
-10178,1514427497270,39
-10179,1514427679708,39
-10180,1514427943569,37
-10181,1514428195597,36
-10182,1514428207734,36
-10183,1514428334742,41
-10184,1514428474200,40
-10185,1514428558913,40
-10186,1514428635550,40
-10187,1514428673095,39
-10188,1514428704029,40
-10189,1514428751239,42
-10190,1514428884137,43
-10191,1514429069941,41
-10192,1514429196736,40
-10193,1514429270630,39
-10194,1514429345795,39
-10195,1514429413085,38
-10196,1514429549650,38
-10197,1514429778765,37
-10198,1514430113569,36
-10199,1514430381925,34
-10200,1514430450067,33
-10201,1514430543923,33
-10202,1514430652431,32
-10203,1514430696649,30
-10204,1514430833491,30
-10205,1514430975477,29
-10206,1514431014937,28
-10207,1514431033450,28
-10208,1514431068068,29
-10209,1514431103117,29
-10210,1514431125511,30
-10211,1514431216220,31
-10212,1514431324528,31
-10213,1514431359848,30
-10214,1514431421785,31
-10215,1514431465626,32
-10216,1514431536469,32
-10217,1514431600829,32
-10218,1514431626718,31
-10219,1514431664315,33
-10220,1514431793381,33
-10221,1514431955312,32
-10222,1514432168525,32
-10223,1514432377262,30
-10224,1514432502464,30
-10225,1514432588779,29
-10226,1514432627040,29
-10227,1514432672718,29
-10228,1514432707279,29
-10229,1514432722419,29
-10230,1514432763239,33
-10231,1514432867516,33
-10232,1514432955392,33
-10233,1514433027028,34
-10234,1514433100985,35
-10235,1514433175689,36
-10236,1514433232884,36
-10237,1514433339095,36
-10238,1514433594866,34
-10239,1514433805190,33
-10240,1514433852886,33
-10241,1514433874473,34
-10242,1514433929539,36
-10243,1514433980867,37
-10244,1514434058966,37
-10245,1514434199380,37
-10246,1514434327530,36
-10247,1514434385524,35
-10248,1514434437633,35
-10249,1514434487185,36
-10250,1514434610810,36
-10251,1514434717206,36
-10252,1514434791427,34
-10253,1514434920453,34
-10254,1514434987409,33
-10255,1514435005852,32
-10256,1514435102706,35
-10257,1514435233755,34
-10258,1514435331821,33
-10259,1514435545742,32
-10260,1514435894500,31
-10261,1514436086276,30
-10262,1514436134920,29
-10263,1514436205824,30
-10264,1514436241575,31
-10265,1514436272597,31
-10266,1514436321497,32
-10267,1514436520877,32
-10268,1514436772934,30
-10269,1514436856756,30
-10270,1514436921368,31
-10271,1514436989127,30
-10272,1514437021079,31
-10273,1514437127509,31
-10274,1514437220803,30
-10275,1514437396183,29
-10276,1514437607787,28
-10277,1514437773916,27
-10278,1514437845120,26
-10279,1514437914058,25
-10280,1514437992835,25
-10281,1514438177094,24
-10282,1514438373355,22
-10283,1514438489036,24
-10284,1514438608142,23
-10285,1514438680199,22
-10286,1514438735204,22
-10287,1514438880731,22
-10288,1514438994979,22
-10289,1514439009906,22
-10290,1514439096931,24
-10291,1514439160543,24
-10292,1514439178860,23
-10293,1514439197313,24
-10294,1514439264373,26
-10295,1514439422493,26
-10296,1514439519755,26
-10297,1514439538007,25
-10298,1514439592843,26
-10299,1514439667680,26
-10300,1514439827249,25
-10301,1514439970072,24
-10302,1514440008544,23
-10303,1514440078781,23
-10304,1514440133055,23
-10305,1514440197474,22
-10306,1514440288905,22
-10307,1514440391492,21
-10308,1514440468349,21
-10309,1514440484012,21
-10310,1514440499195,23
-10311,1514440550783,27
-10312,1514440598252,27
-10313,1514440642916,26
-10314,1514440685195,28
-10315,1514440913716,28
-10316,1514441136262,27
-10317,1514441187898,27
-10318,1514441212270,26
-10319,1514441250992,29
-10320,1514441318960,30
-10321,1514441367153,28
-10322,1514441505126,29
-10323,1514441537088,28
-10324,1514441592250,29
-10325,1514441614375,28
-10326,1514441633905,29
-10327,1514441655326,32
-10328,1514441870992,35
-10329,1514442079709,34
-10330,1514442223940,35
-10331,1514442284663,35
-10332,1514442355880,35
-10333,1514442475994,35
-10334,1514442585138,34
-10335,1514442669793,33
-10336,1514442770219,33
-10337,1514442923025,33
-10338,1514443058287,32
-10339,1514443336396,31
-10340,1514443679979,29
-10341,1514443769007,29
-10342,1514443800174,30
-10343,1514443922892,32
-10344,1514444077528,31
-10345,1514444164592,30
-10346,1514444315182,29
-10347,1514444503289,29
-10348,1514444613085,28
-10349,1514444727314,27
-10350,1514444846377,28
-10351,1514444917474,27
-10352,1514445058125,26
-10353,1514445217889,25
-10354,1514445364446,25
-10355,1514445488205,25
-10356,1514445565414,25
-10357,1514445646417,25
-10358,1514445704111,25
-10359,1514445735914,24
-10360,1514445758674,24
-10361,1514445832793,26
-10362,1514445923882,25
-10363,1514445978769,24
-10364,1514446097829,24
-10365,1514446242009,24
-10366,1514446339702,24
-10367,1514446412972,24
-10368,1514446444363,23
-10369,1514446489991,24
-10370,1514446620249,24
-10371,1514446721393,23
-10372,1514446749976,23
-10373,1514446827273,24
-10374,1514446907495,24
-10375,1514447004359,24
-10376,1514447121180,22
-10377,1514447249024,22
-10378,1514447367457,21
-10379,1514447412169,20
-10380,1514447431038,20
-10381,1514447494986,21
-10382,1514447563618,20
-10383,1514447595606,20
-10384,1514447617857,19
-10385,1514447635750,20
-10386,1514447713882,21
-10387,1514447872799,21
-10388,1514448009024,20
-10389,1514448130977,19
-10390,1514448215406,19
-10391,1514448253451,19
-10392,1514448321048,19
-10393,1514448362940,19
-10394,1514448436762,20
-10395,1514448512499,19
-10396,1514448527362,19
-10397,1514448588573,21
-10398,1514448665260,21
-10399,1514448712931,21
-10400,1514448876780,21
-10401,1514449025094,20
-10402,1514449070838,19
-10403,1514449115647,19
-10404,1514449134549,19
-10405,1514449205506,20
-10406,1514449285085,19
-10407,1514449319995,19
-10408,1514449390758,19
-10409,1514449573357,19
-10410,1514449741780,18
-10411,1514449789108,19
-10412,1514449804568,19
-10413,1514449831474,22
-10414,1514449889396,23
-10415,1514449983288,23
-10416,1514450057645,22
-10417,1514450141332,21
-10418,1514450209251,21
-10419,1514450230804,22
-10420,1514450272250,24
-10421,1514450313844,23
-10422,1514450406748,25
-10423,1514450492504,24
-10424,1514450521183,24
-10425,1514450571870,25
-10426,1514450711696,27
-10427,1514450835017,28
-10428,1514450864577,28
-10429,1514450911740,29
-10430,1514450962546,29
-10431,1514451013240,30
-10432,1514451080670,31
-10433,1514451217248,30
-10434,1514451346860,30
-10435,1514451375038,29
-10436,1514451471844,31
-10437,1514451568359,31
-10438,1514451600347,30
-10439,1514451686878,31
-10440,1514451807296,30
-10441,1514451950265,30
-10442,1514451998647,30
-10443,1514452081509,31
-10444,1514452138537,31
-10445,1514452174220,30
-10446,1514452193008,31
-10447,1514452726308,34
-10448,1514453254980,33
-10449,1514453371340,31
-10450,1514453506281,30
-10451,1514453611298,30
-10452,1514453686485,30
-10453,1514453718135,29
-10454,1514453759287,30
-10455,1514453856176,30
-10456,1514453973982,29
-10457,1514454064836,29
-10458,1514454168702,29
-10459,1514454262200,29
-10460,1514454336545,28
-10461,1514454390620,29
-10462,1514454571184,29
-10463,1514454748788,28
-10464,1514454819592,28
-10465,1514454870305,27
-10466,1514454918569,27
-10467,1514454956385,28
-10468,1514454988604,27
-10469,1514455010335,29
-10470,1514455165220,31
-10471,1514455326708,30
-10472,1514455460684,29
-10473,1514455692631,30
-10474,1514455841401,28
-10475,1514455862566,28
-10476,1514455898091,29
-10477,1514455986191,29
-10478,1514456083096,29
-10479,1514456199009,28
-10480,1514456314564,28
-10481,1514456372643,28
-10482,1514456407043,28
-10483,1514456494749,28
-10484,1514456525706,28
-10485,1514456577488,30
-10486,1514456668046,31
-10487,1514456823073,31
-10488,1514456992998,30
-10489,1514457125697,28
-10490,1514457219918,27
-10491,1514457364592,27
-10492,1514457508878,26
-10493,1514457537318,26
-10494,1514457586661,27
-10495,1514457686001,27
-10496,1514457796045,25
-10497,1514457842969,26
-10498,1514457887325,27
-10499,1514457908941,27
-10500,1514457947224,29
-10501,1514458036875,29
-10502,1514458113699,26
-10503,1514458185392,28
-10504,1514458250607,28
-10505,1514458325636,28
-10506,1514458395113,27
-10507,1514458516309,27
-10508,1514458692012,26
-10509,1514458769045,25
-10510,1514458869208,24
-10511,1514458960053,23
-10512,1514458991027,23
-10513,1514459049006,25
-10514,1514459099971,25
-10515,1514459162122,25
-10516,1514459217066,25
-10517,1514459304344,25
-10518,1514459474435,23
-10519,1514459601655,23
-10520,1514459647906,23
-10521,1514459708885,23
-10522,1514459773966,23
-10523,1514459832731,23
-10524,1514459942675,22
-10525,1514460061557,22
-10526,1514460152634,21
-10527,1514460232094,21
-10528,1514460320057,20
-10529,1514460458919,21
-10530,1514460654729,20
-10531,1514460786943,19
-10532,1514460844812,19
-10533,1514460914237,19
-10534,1514460979203,18
-10535,1514461028154,17
-10536,1514461069563,18
-10537,1514461121645,18
-10538,1514461162932,17
-10539,1514461200576,18
-10540,1514461235543,18
-10541,1514461257599,18
-10542,1514461299670,19
-10543,1514461338239,19
-10544,1514461360700,20
-10545,1514461441405,21
-10546,1514461538085,20
-10547,1514461642581,22
-10548,1514461791128,21
-10549,1514461864886,20
-10550,1514461927183,20
-10551,1514462015946,19
-10552,1514462146250,19
-10553,1514462239416,18
-10554,1514462305716,18
-10555,1514462409405,18
-10556,1514462488155,17
-10557,1514462528085,17
-10558,1514462556322,17
-10559,1514462595615,17
-10560,1514462633873,17
-10561,1514462695485,17
-10562,1514462746944,18
-10563,1514462785448,17
-10564,1514462817459,16
-10565,1514462849361,17
-10566,1514462900685,18
-10567,1514462974815,17
-10568,1514463039499,17
-10569,1514463077337,18
-10570,1514463155156,19
-10571,1514463236050,18
-10572,1514463302852,18
-10573,1514463472561,18
-10574,1514463593842,17
-10575,1514463674688,15
-10576,1514463785107,16
-10577,1514463876313,16
-10578,1514463950465,16
-10579,1514464014276,15
-10580,1514464069505,15
-10581,1514464108364,15
-10582,1514464130240,15
-10583,1514464243560,16
-10584,1514464325882,15
-10585,1514464393552,16
-10586,1514464455046,16
-10587,1514464512377,16
-10588,1514464566964,16
-10589,1514464619296,15
-10590,1514464667046,15
-10591,1514464688638,15
-10592,1514464710904,16
-10593,1514464723146,16
-10594,1514464737940,20
-10595,1514464759555,21
-10596,1514464801022,23
-10597,1514464835719,23
-10598,1514464964730,24
-10599,1514465120723,24
-10600,1514465216855,25
-10601,1514465304980,25
-10602,1514465396283,25
-10603,1514465480159,25
-10604,1514465518128,24
-10605,1514465651521,26
-10606,1514465920243,25
-10607,1514466089938,25
-10608,1514466181685,23
-10609,1514466346396,23
-10610,1514466443376,23
-10611,1514466465990,22
-10612,1514466617047,23
-10613,1514466769502,24
-10614,1514466913428,23
-10615,1514467062433,22
-10616,1514467092145,22
-10617,1514467181225,23
-10618,1514467312924,23
-10619,1514467457210,22
-10620,1514467609002,21
-10621,1514467741145,21
-10622,1514467830003,21
-10623,1514467865303,21
-10624,1514467952640,22
-10625,1514468035024,21
-10626,1514468057232,20
-10627,1514468171537,22
-10628,1514468272074,22
-10629,1514468296841,21
-10630,1514468331477,22
-10631,1514468389330,22
-10632,1514468420304,22
-10633,1514468504267,22
-10634,1514468558802,23
-10635,1514468586789,22
-10636,1514468645167,24
-10637,1514468691198,24
-10638,1514468719574,24
-10639,1514468803649,26
-10640,1514469010450,25
-10641,1514469215583,25
-10642,1514469319566,24
-10643,1514469387279,24
-10644,1514469423035,25
-10645,1514469480702,25
-10646,1514469558978,26
-10647,1514469603984,26
-10648,1514469642168,26
-10649,1514469725935,27
-10650,1514469796864,26
-10651,1514469824932,26
-10652,1514469849860,28
-10653,1514470137302,29
-10654,1514470401185,28
-10655,1514470422465,27
-10656,1514470516766,28
-10657,1514470660264,28
-10658,1514470839571,28
-10659,1514470941563,28
-10660,1514471040846,28
-10661,1514471102036,27
-10662,1514471160680,27
-10663,1514471298994,28
-10664,1514471500787,27
-10665,1514471665250,27
-10666,1514471723569,26
-10667,1514471784237,26
-10668,1514471865282,26
-10669,1514472151970,26
-10670,1514472422380,25
-10671,1514472447915,24
-10672,1514472508040,25
-10673,1514472568772,25
-10674,1514472676167,25
-10675,1514472773801,24
-10676,1514472796287,24
-10677,1514472837335,25
-10678,1514472907572,25
-10679,1514472971842,25
-10680,1514473016668,24
-10681,1514473041611,24
-10682,1514473057122,25
-10683,1514473095748,29
-10684,1514473189579,30
-10685,1514473307031,29
-10686,1514473375069,28
-10687,1514473413303,28
-10688,1514473441423,28
-10689,1514473492113,29
-10690,1514473554437,29
-10691,1514473615991,29
-10692,1514473776265,30
-10693,1514473925820,30
-10694,1514473991331,30
-10695,1514474063178,31
-10696,1514474104045,32
-10697,1514474164837,33
-10698,1514474222451,33
-10699,1514474265210,34
-10700,1514474284328,34
-10701,1514474338679,37
-10702,1514474399316,38
-10703,1514474418260,38
-10704,1514474427449,41
-10705,1514474540856,51
-10706,1514474634045,51
-10707,1514474726105,50
-10708,1514474857416,49
-10709,1514475068018,49
-10710,1514475451207,48
-10711,1514475746405,46
-10712,1514475943518,46
-10713,1514476101285,44
-10714,1514476184409,44
-10715,1514476290512,43
-10716,1514476368116,43
-10717,1514476466947,43
-10718,1514476560807,42
-10719,1514476710118,42
-10720,1514476845175,41
-10721,1514476896552,40
-10722,1514476963160,41
-10723,1514477076046,40
-10724,1514477271361,39
-10725,1514477442734,39
-10726,1514477513354,37
-10727,1514477611029,38
-10728,1514477734438,37
-10729,1514477900316,36
-10730,1514478140721,35
-10731,1514478278722,35
-10732,1514478327783,34
-10733,1514478365920,34
-10734,1514478411028,35
-10735,1514478475109,36
-10736,1514478555032,36
-10737,1514478716550,36
-10738,1514478845529,35
-10739,1514478972330,35
-10740,1514479084996,34
-10741,1514479200956,33
-10742,1514479365599,32
-10743,1514479508563,30
-10744,1514479550521,29
-10745,1514479575795,31
-10746,1514479745709,32
-10747,1514479834250,31
-10748,1514479956235,31
-10749,1514480046746,31
-10750,1514480085501,30
-10751,1514480175896,30
-10752,1514480362476,30
-10753,1514480583346,30
-10754,1514480727716,29
-10755,1514480881952,27
-10756,1514481000859,27
-10757,1514481129693,27
-10758,1514481260207,25
-10759,1514481315985,24
-10760,1514481357947,23
-10761,1514481385770,24
-10762,1514481439636,24
-10763,1514481553591,24
-10764,1514481751842,23
-10765,1514481894033,22
-10766,1514481945653,20
-10767,1514482004482,20
-10768,1514482032564,20
-10769,1514482064209,19
-10770,1514482144551,19
-10771,1514482211999,18
-10772,1514482247706,18
-10773,1514482279787,18
-10774,1514482301664,17
-10775,1514482395513,19
-10776,1514482503602,17
-10777,1514482592928,17
-10778,1514482740163,16
-10779,1514482864764,16
-10780,1514482917081,15
-10781,1514482942131,13
-10782,1514482982357,14
-10783,1514483016639,15
-10784,1514483174609,16
-10785,1514483341434,15
-10786,1514483401984,13
-10787,1514483456234,12
-10788,1514483477552,12
-10789,1514483499431,13
-10790,1514483508257,14
-10791,1514483547035,17
-10792,1514483601450,17
-10793,1514483643001,15
-10794,1514483753709,15
-10795,1514483862833,14
-10796,1514483913721,13
-10797,1514483962744,13
-10798,1514484004096,12
-10799,1514484042671,13
-10800,1514484057672,13
-10801,1514484098669,15
-10802,1514484199896,15
-10803,1514484290459,15
-10804,1514484318301,16
-10805,1514484346615,21
-10806,1514484384592,22
-10807,1514484443308,22
-10808,1514484483841,23
-10809,1514484517528,24
-10810,1514484687360,24
-10811,1514484885735,23
-10812,1514484972801,23
-10813,1514485041062,22
-10814,1514485159673,21
-10815,1514485273009,21
-10816,1514485324195,20
-10817,1514485401864,21
-10818,1514485494380,20
-10819,1514485548319,20
-10820,1514485563630,20
-10821,1514485575391,23
-10822,1514485802015,27
-10823,1514486036413,26
-10824,1514486156472,26
-10825,1514486279638,25
-10826,1514486350074,24
-10827,1514486404720,24
-10828,1514486498189,25
-10829,1514486786753,24
-10830,1514486994761,22
-10831,1514487030317,22
-10832,1514487094898,22
-10833,1514487205087,22
-10834,1514487298125,23
-10835,1514487326193,23
-10836,1514487415402,24
-10837,1514487541873,24
-10838,1514487742862,23
-10839,1514487900219,23
-10840,1514487941987,22
-10841,1514487971331,22
-10842,1514488108795,23
-10843,1514488290861,22
-10844,1514488388293,22
-10845,1514488498882,21
-10846,1514488645319,22
-10847,1514488758027,21
-10848,1514488864221,21
-10849,1514488941163,21
-10850,1514489035050,20
-10851,1514489125980,20
-10852,1514489147794,20
-10853,1514489166229,21
-10854,1514489205065,23
-10855,1514489249917,23
-10856,1514489265180,22
-10857,1514489362438,26
-10858,1514489473217,25
-10859,1514489577413,24
-10860,1514489661304,24
-10861,1514489713013,24
-10862,1514489806346,25
-10863,1514489894257,24
-10864,1514489950030,24
-10865,1514490070706,24
-10866,1514490224681,22
-10867,1514490299292,22
-10868,1514490337411,22
-10869,1514490402019,23
-10870,1514490530413,23
-10871,1514490624955,22
-10872,1514490669717,22
-10873,1514490701346,23
-10874,1514490730116,23
-10875,1514490780815,25
-10876,1514490894308,25
-10877,1514491017250,25
-10878,1514491121905,24
-10879,1514491184959,23
-10880,1514491256441,22
-10881,1514491323668,22
-10882,1514491371973,22
-10883,1514491440669,22
-10884,1514491475937,22
-10885,1514491521283,22
-10886,1514491632336,22
-10887,1514491753831,21
-10888,1514491785955,21
-10889,1514491810556,22
-10890,1514491862756,23
-10891,1514491924043,25
-10892,1514491979056,25
-10893,1514492022568,25
-10894,1514492180917,25
-10895,1514492413996,24
-10896,1514492544151,23
-10897,1514492625552,23
-10898,1514492706282,22
-10899,1514492872990,22
-10900,1514493048712,21
-10901,1514493150376,21
-10902,1514493204222,20
-10903,1514493253321,20
-10904,1514493310735,20
-10905,1514493339544,20
-10906,1514493347873,21
-10907,1514493377200,27
-10908,1514493422616,28
-10909,1514493480251,29
-10910,1514493552826,29
-10911,1514493587642,29
-10912,1514493664745,30
-10913,1514493713256,30
-10914,1514493741336,30
-10915,1514493816037,31
-10916,1514493970560,31
-10917,1514494084127,30
-10918,1514494163897,29
-10919,1514494232379,29
-10920,1514494281245,29
-10921,1514494338701,31
-10922,1514494371504,33
-10923,1514494389582,34
-10924,1514494467068,37
-10925,1514494545081,36
-10926,1514494586890,36
-10927,1514494630981,37
-10928,1514494920940,38
-10929,1514495323670,38
-10930,1514495739759,36
-10931,1514496049147,35
-10932,1514496150116,34
-10933,1514496255026,34
-10934,1514496394745,33
-10935,1514496671017,33
-10936,1514496867215,32
-10937,1514497136812,31
-10938,1514497380388,30
-10939,1514497467410,29
-10940,1514497535726,28
-10941,1514497629305,28
-10942,1514497714720,29
-10943,1514497793747,27
-10944,1514497893467,27
-10945,1514497964067,27
-10946,1514497982457,26
-10947,1514498072459,29
-10948,1514498173240,28
-10949,1514498228356,27
-10950,1514498322714,26
-10951,1514498583078,26
-10952,1514498788421,25
-10953,1514498911889,25
-10954,1514499035526,25
-10955,1514499088936,24
-10956,1514499292699,25
-10957,1514499463373,25
-10958,1514499606743,24
-10959,1514499758750,23
-10960,1514499797098,22
-10961,1514499829170,23
-10962,1514499854306,24
-10963,1514499885611,25
-10964,1514499963373,25
-10965,1514500055761,25
-10966,1514500095281,25
-10967,1514500140725,25
-10968,1514500204918,25
-10969,1514500278741,25
-10970,1514500333067,25
-10971,1514500364871,24
-10972,1514500442965,25
-10973,1514500562656,25
-10974,1514500648884,24
-10975,1514500766422,25
-10976,1514500884418,24
-10977,1514500915313,23
-10978,1514500954383,23
-10979,1514500989927,24
-10980,1514501022259,24
-10981,1514501047052,25
-10982,1514501174282,25
-10983,1514501295004,25
-10984,1514501327267,24
-10985,1514501387460,26
-10986,1514501547859,25
-10987,1514501650796,24
-10988,1514501662994,23
-10989,1514501688464,27
-10990,1514501723313,29
-10991,1514501751187,30
-10992,1514501766341,31
-10993,1514501923714,34
-10994,1514502059509,34
-10995,1514502110490,33
-10996,1514502157821,33
-10997,1514502179416,33
-10998,1514502292174,35
-10999,1514502399365,35
-11000,1514502454668,34
-11001,1514502493567,34
-11002,1514502557284,34
-11003,1514502647098,34
-11004,1514502684836,34
-11005,1514502847450,34
-11006,1514503035802,34
-11007,1514503285767,35
-11008,1514503564179,35
-11009,1514503732564,34
-11010,1514503864202,33
-11011,1514504044158,33
-11012,1514504235688,32
-11013,1514504341111,31
-11014,1514504388333,31
-11015,1514504432511,32
-11016,1514504570238,33
-11017,1514504776548,32
-11018,1514504938387,31
-11019,1514505032679,30
-11020,1514505068404,30
-11021,1514505105714,31
-11022,1514505141609,32
-11023,1514505200526,33
-11024,1514505252285,35
-11025,1514505287422,36
-11026,1514505312697,37
-11027,1514505354888,40
-11028,1514505573867,41
-11029,1514505787196,40
-11030,1514505897091,39
-11031,1514506040023,38
-11032,1514506156148,37
-11033,1514506341938,37
-11034,1514506487169,36
-11035,1514506605827,35
-11036,1514506902684,35
-11037,1514507149573,33
-11038,1514507231385,31
-11039,1514507341353,31
-11040,1514507476277,30
-11041,1514507592849,29
-11042,1514507685087,27
-11043,1514507719801,28
-11044,1514507865827,29
-11045,1514508016503,27
-11046,1514508032072,26
-11047,1514508047061,31
-11048,1514508078151,34
-11049,1514508103650,36
-11050,1514508463068,38
-11051,1514508905349,36
-11052,1514509058742,35
-11053,1514509224422,33
-11054,1514509376233,32
-11055,1514509420539,31
-11056,1514509520729,32
-11057,1514509624061,31
-11058,1514509733557,29
-11059,1514509817937,28
-11060,1514509840631,28
-11061,1514509875401,29
-11062,1514509920136,30
-11063,1514509992444,31
-11064,1514510158837,31
-11065,1514510406892,30
-11066,1514510606321,28
-11067,1514510726483,28
-11068,1514510821293,27
-11069,1514510859348,27
-11070,1514510871189,27
-11071,1514510919178,31
-11072,1514510977014,31
-11073,1514511007981,31
-11074,1514511029591,31
-11075,1514511144132,33
-11076,1514511256630,33
-11077,1514511288082,32
-11078,1514511322686,33
-11079,1514511525658,32
-11080,1514511826312,33
-11081,1514511993102,33
-11082,1514512084791,32
-11083,1514512179715,30
-11084,1514512251632,29
-11085,1514512299542,30
-11086,1514512405451,29
-11087,1514512547962,28
-11088,1514512675270,27
-11089,1514512756740,28
-11090,1514512794843,28
-11091,1514512818771,29
-11092,1514512868681,31
-11093,1514513030275,33
-11094,1514513253671,32
-11095,1514513411445,31
-11096,1514513505701,30
-11097,1514513567917,30
-11098,1514513642517,31
-11099,1514513696968,31
-11100,1514513708830,31
-11101,1514513774158,37
-11102,1514513811892,37
-11103,1514513833985,38
-11104,1514513881520,41
-11105,1514513933999,42
-11106,1514513982093,42
-11107,1514514092126,42
-11108,1514514226157,42
-11109,1514514331410,41
-11110,1514514408968,39
-11111,1514514467135,40
-11112,1514514535067,39
-11113,1514514693574,39
-11114,1514514876488,38
-11115,1514515002838,37
-11116,1514515073249,37
-11117,1514515104366,36
-11118,1514515263256,37
-11119,1514515426382,36
-11120,1514515517167,35
-11121,1514515612105,35
-11122,1514515659936,34
-11123,1514515692314,35
-11124,1514515736890,36
-11125,1514515879832,37
-11126,1514516037785,37
-11127,1514516216580,38
-11128,1514516422245,37
-11129,1514516549585,36
-11130,1514516743806,34
-11131,1514516903706,34
-11132,1514516965119,32
-11133,1514517049199,32
-11134,1514517278988,31
-11135,1514517538926,30
-11136,1514517623274,29
-11137,1514517652018,27
-11138,1514517838245,29
-11139,1514518026059,27
-11140,1514518140328,26
-11141,1514518354278,24
-11142,1514518485130,23
-11143,1514518574121,22
-11144,1514518682874,22
-11145,1514518765581,20
-11146,1514518827430,20
-11147,1514518954680,20
-11148,1514519089300,21
-11149,1514519127510,21
-11150,1514519162457,22
-11151,1514519270357,23
-11152,1514519365725,21
-11153,1514519398160,20
-11154,1514519426829,20
-11155,1514519447667,20
-11156,1514519466122,22
-11157,1514519482399,23
-11158,1514519553016,25
-11159,1514519639404,25
-11160,1514519674092,23
-11161,1514519715733,25
-11162,1514519797220,26
-11163,1514519883044,25
-11164,1514519940629,24
-11165,1514519988349,24
-11166,1514520030178,23
-11167,1514520074678,23
-11168,1514520117359,23
-11169,1514520143943,23
-11170,1514520234788,23
-11171,1514520343079,25
-11172,1514520411600,25
-11173,1514520458782,24
-11174,1514520486941,25
-11175,1514520538201,27
-11176,1514520581692,27
-11177,1514520644661,27
-11178,1514520780144,28
-11179,1514520914687,27
-11180,1514521100435,26
-11181,1514521295082,25
-11182,1514521384666,24
-11183,1514521421168,23
-11184,1514521439675,23
-11185,1514521549913,24
-11186,1514521721493,24
-11187,1514521803077,23
-11188,1514521847477,22
-11189,1514522003572,22
-11190,1514522218232,22
-11191,1514522322366,20
-11192,1514522350672,21
-11193,1514522393892,22
-11194,1514522435714,21
-11195,1514522490664,21
-11196,1514522539287,20
-11197,1514522617022,20
-11198,1514522691936,20
-11199,1514522703685,18
-11200,1514522741518,21
-11201,1514522779599,25
-11202,1514522805468,25
-11203,1514522836769,26
-11204,1514522892029,29
-11205,1514522929973,29
-11206,1514523078919,31
-11207,1514523267935,31
-11208,1514523395044,30
-11209,1514523511258,29
-11210,1514523657849,28
-11211,1514523792930,28
-11212,1514523824652,28
-11213,1514523843357,29
-11214,1514523869301,31
-11215,1514523895370,33
-11216,1514523933126,34
-11217,1514524296978,36
-11218,1514524718574,36
-11219,1514524891718,35
-11220,1514525038247,34
-11221,1514525206858,33
-11222,1514525387521,32
-11223,1514525570566,32
-11224,1514525698326,32
-11225,1514525752602,32
-11226,1514525845088,32
-11227,1514525921068,32
-11228,1514526039379,31
-11229,1514526154009,30
-11230,1514526295493,30
-11231,1514526458328,29
-11232,1514526526856,28
-11233,1514526691450,28
-11234,1514526880384,27
-11235,1514526960828,25
-11236,1514526994087,25
-11237,1514527013609,26
-11238,1514527112561,29
-11239,1514527140892,28
-11240,1514527179823,29
-11241,1514527219862,30
-11242,1514527298950,29
-11243,1514527386169,29
-11244,1514527477180,28
-11245,1514527598335,28
-11246,1514527792925,27
-11247,1514528055561,25
-11248,1514528225898,25
-11249,1514528308345,23
-11250,1514528354812,23
-11251,1514528370315,23
-11252,1514528589508,25
-11253,1514528778527,23
-11254,1514528847473,23
-11255,1514528948096,23
-11256,1514528993606,23
-11257,1514529029993,24
-11258,1514529110891,26
-11259,1514529175682,25
-11260,1514529210382,24
-11261,1514529267780,25
-11262,1514529526213,26
-11263,1514529763150,25
-11264,1514529868878,24
-11265,1514529997698,23
-11266,1514530053952,22
-11267,1514530104861,23
-11268,1514530156066,22
-11269,1514530181088,23
-11270,1514530259952,24
-11271,1514530370578,24
-11272,1514530435008,24
-11273,1514530502885,23
-11274,1514530587459,23
-11275,1514530767891,23
-11276,1514530937463,22
-11277,1514530989154,22
-11278,1514531024078,21
-11279,1514531076769,21
-11280,1514531138851,21
-11281,1514531338907,21
-11282,1514531536561,19
-11283,1514531591561,19
-11284,1514531640559,19
-11285,1514531652793,19
-11286,1514531729789,22
-11287,1514531869516,22
-11288,1514531955049,21
-11289,1514531981219,21
-11290,1514532000920,21
-11291,1514532036082,22
-11292,1514532070694,22
-11293,1514532100374,23
-11294,1514532122120,24
-11295,1514532148702,26
-11296,1514532177106,26
-11297,1514532238618,27
-11298,1514532293263,27
-11299,1514532370018,27
-11300,1514532402987,28
-11301,1514532481218,29
-11302,1514532551467,29
-11303,1514532594446,29
-11304,1514532705889,31
-11305,1514532801562,30
-11306,1514532843058,30
-11307,1514532881585,31
-11308,1514532901320,31
-11309,1514532947754,33
-11310,1514533028692,34
-11311,1514533093816,34
-11312,1514533119518,33
-11313,1514533287343,36
-11314,1514533432742,36
-11315,1514533535605,36
-11316,1514533612710,37
-11317,1514533742347,38
-11318,1514533915855,37
-11319,1514534067672,36
-11320,1514534119865,35
-11321,1514534144521,36
-11322,1514534338926,37
-11323,1514534589623,37
-11324,1514534734770,35
-11325,1514534868616,35
-11326,1514534955346,34
-11327,1514535007175,33
-11328,1514535206075,34
-11329,1514535375443,33
-11330,1514535501077,32
-11331,1514535603685,31
-11332,1514535749371,31
-11333,1514535882096,29
-11334,1514535921613,29
-11335,1514535975570,29
-11336,1514536025691,29
-11337,1514536057562,29
-11338,1514536111566,32
-11339,1514536177874,32
-11340,1514536204103,33
-11341,1514536255723,35
-11342,1514536329634,35
-11343,1514536453475,35
-11344,1514536583578,35
-11345,1514536670051,34
-11346,1514536728685,33
-11347,1514536750216,33
-11348,1514536785494,36
-11349,1514536925281,36
-11350,1514537075675,35
-11351,1514537256279,34
-11352,1514537415149,35
-11353,1514537452943,34
-11354,1514537556733,34
-11355,1514537679727,34
-11356,1514537790385,33
-11357,1514537884477,32
-11358,1514538062852,32
-11359,1514538270466,31
-11360,1514538366075,30
-11361,1514538435102,30
-11362,1514538492521,30
-11363,1514538568980,29
-11364,1514538676924,28
-11365,1514538738455,28
-11366,1514538783409,28
-11367,1514538910185,27
-11368,1514539013917,27
-11369,1514539059234,26
-11370,1514539349853,26
-11371,1514539674924,26
-11372,1514539784970,24
-11373,1514539874613,24
-11374,1514539971303,23
-11375,1514540062264,23
-11376,1514540257863,21
-11377,1514540443454,20
-11378,1514540471687,19
-11379,1514540637101,20
-11380,1514540708637,19
-11381,1514540736961,18
-11382,1514540748631,17
-11383,1514540786711,20
-11384,1514540837749,20
-11385,1514540866371,19
-11386,1514540878330,21
-11387,1514541020113,23
-11388,1514541119378,22
-11389,1514541172870,22
-11390,1514541267010,22
-11391,1514541443786,22
-11392,1514541733409,20
-11393,1514541927087,20
-11394,1514541959619,20
-11395,1514542046758,20
-11396,1514542129085,21
-11397,1514542147717,21
-11398,1514542187545,23
-11399,1514542215480,22
-11400,1514542346723,23
-11401,1514542487073,23
-11402,1514542532092,22
-11403,1514542573498,22
-11404,1514542651462,23
-11405,1514542757054,22
-11406,1514542848511,21
-11407,1514542893125,21
-11408,1514542924433,22
-11409,1514542943196,23
-11410,1514542977866,25
-11411,1514543035202,26
-11412,1514543113406,27
-11413,1514543167611,27
-11414,1514543228887,27
-11415,1514543318701,27
-11416,1514543373806,26
-11417,1514543504084,26
-11418,1514543625362,25
-11419,1514543679248,25
-11420,1514543730578,25
-11421,1514543740142,25
-11422,1514543838211,32
-11423,1514543960617,31
-11424,1514544005200,30
-11425,1514544090669,30
-11426,1514544203537,30
-11427,1514544303757,29
-11428,1514544396385,29
-11429,1514544458163,29
-11430,1514544503405,28
-11431,1514544556075,28
-11432,1514544599909,28
-11433,1514544736980,29
-11434,1514544827718,27
-11435,1514544859420,28
-11436,1514544891183,28
-11437,1514545088157,29
-11438,1514545371509,29
-11439,1514545672799,29
-11440,1514545751562,27
-11441,1514545839172,28
-11442,1514546082774,28
-11443,1514546316333,27
-11444,1514546383368,26
-11445,1514546448874,26
-11446,1514546484341,27
-11447,1514546555821,27
-11448,1514546624510,28
-11449,1514546636416,29
-11450,1514546665424,33
-11451,1514546728469,35
-11452,1514546832269,35
-11453,1514546912690,34
-11454,1514546966729,35
-11455,1514547034189,35
-11456,1514547102261,35
-11457,1514547292450,35
-11458,1514547451983,34
-11459,1514547613799,33
-11460,1514547799212,32
-11461,1514547969477,31
-11462,1514548193174,31
-11463,1514548293007,30
-11464,1514548483295,29
-11465,1514548691627,29
-11466,1514548730334,28
-11467,1514548869931,28
-11468,1514548979617,28
-11469,1514549079591,27
-11470,1514549219215,27
-11471,1514549300512,26
-11472,1514549370475,25
-11473,1514549432786,25
-11474,1514549525204,24
-11475,1514549641924,24
-11476,1514549719645,22
-11477,1514549745005,22
-11478,1514549796339,22
-11479,1514549856989,23
-11480,1514549879679,21
-11481,1514550002755,23
-11482,1514550103259,22
-11483,1514550252175,23
-11484,1514550425162,22
-11485,1514550486708,21
-11486,1514550561637,21
-11487,1514550638224,23
-11488,1514550761210,22
-11489,1514550884013,21
-11490,1514550995851,20
-11491,1514551116866,19
-11492,1514551151276,18
-11493,1514551186573,18
-11494,1514551241728,18
-11495,1514551279869,18
-11496,1514551305291,18
-11497,1514551336891,18
-11498,1514551359441,19
-11499,1514551460418,20
-11500,1514551504734,20
-11501,1514551539708,21
-11502,1514551555256,20
-11503,1514551606066,22
-11504,1514551644719,23
-11505,1514551731986,23
-11506,1514551835933,22
-11507,1514551891142,21
-11508,1514551998411,21
-11509,1514552098404,21
-11510,1514552179848,21
-11511,1514552245523,21
-11512,1514552260557,20
-11513,1514552269386,23
-11514,1514552284811,28
-11515,1514552312317,31
-11516,1514552371446,33
-11517,1514552422561,33
-11518,1514552449433,33
-11519,1514552497251,35
-11520,1514552603595,35
-11521,1514552726588,35
-11522,1514552791624,36
-11523,1514552853414,36
-11524,1514552927480,36
-11525,1514552951998,37
-11526,1514553083097,39
-11527,1514553302407,39
-11528,1514553568665,37
-11529,1514553760495,36
-11530,1514553848917,36
-11531,1514553902588,35
-11532,1514553978245,36
-11533,1514554039526,37
-11534,1514554081352,36
-11535,1514554109866,37
-11536,1514554118736,39
-11537,1514554262022,49
-11538,1514554374785,49
-11539,1514554514633,47
-11540,1514554611742,47
-11541,1514554663072,46
-11542,1514554698514,47
-11543,1514555017581,48
-11544,1514555489827,47
-11545,1514555838602,45
-11546,1514556027380,44
-11547,1514556057654,44
-11548,1514556224122,45
-11549,1514556390389,45
-11550,1514556501229,47
-11551,1514556679189,47
-11552,1514556778665,46
-11553,1514556845992,46
-11554,1514556971821,46
-11555,1514557176705,46
-11556,1514557336753,45
-11557,1514557472449,45
-11558,1514557621280,44
-11559,1514557774885,42
-11560,1514557988761,42
-11561,1514558088013,40
-11562,1514558245386,40
-11563,1514558433578,38
-11564,1514558483178,38
-11565,1514558743390,38
-11566,1514559074479,36
-11567,1514559181889,35
-11568,1514559256758,35
-11569,1514559353939,34
-11570,1514559407592,34
-11571,1514559441944,34
-11572,1514559510448,34
-11573,1514559552007,34
-11574,1514559740379,35
-11575,1514559869622,33
-11576,1514560001618,31
-11577,1514560163050,31
-11578,1514560220720,31
-11579,1514560260396,31
-11580,1514560319328,31
-11581,1514560357712,32
-11582,1514560372683,31
-11583,1514560482710,35
-11584,1514560666466,33
-11585,1514560837082,32
-11586,1514560912550,32
-11587,1514560988758,31
-11588,1514561070850,29
-11589,1514561203992,28
-11590,1514561316183,27
-11591,1514561351939,26
-11592,1514561425218,26
-11593,1514561502540,25
-11594,1514561583720,24
-11595,1514561704262,24
-11596,1514561812040,22
-11597,1514561868738,22
-11598,1514561883853,21
-11599,1514561962170,24
-11600,1514562078064,23
-11601,1514562153738,22
-11602,1514562203510,21
-11603,1514562245076,22
-11604,1514562390520,22
-11605,1514562518239,21
-11606,1514562529956,20
-11607,1514562548615,22
-11608,1514562588071,23
-11609,1514562623288,22
-11610,1514562644736,22
-11611,1514562710953,23
-11612,1514562774982,22
-11613,1514562814228,23
-11614,1514562852725,25
-11615,1514562907557,26
-11616,1514563065886,27
-11617,1514563260315,27
-11618,1514563344986,26
-11619,1514563369955,26
-11620,1514563562788,28
-11621,1514563771513,26
-11622,1514563841184,25
-11623,1514563934705,24
-11624,1514564015072,24
-11625,1514564069619,24
-11626,1514564107621,25
-11627,1514564230197,24
-11628,1514564351371,24
-11629,1514564396643,22
-11630,1514564453842,22
-11631,1514564491814,21
-11632,1514564640673,22
-11633,1514564802318,21
-11634,1514564889699,20
-11635,1514564947894,19
-11636,1514565097139,20
-11637,1514565128945,24
-11638,1514565210035,25
-11639,1514565328858,25
-11640,1514565403471,24
-11641,1514565498261,23
-11642,1514565585746,24
-11643,1514565610951,25
-11644,1514565712550,25
-11645,1514565850570,24
-11646,1514565953111,23
-11647,1514566084452,23
-11648,1514566237720,23
-11649,1514566420238,22
-11650,1514566530275,21
-11651,1514566626201,21
-11652,1514566697190,21
-11653,1514566743315,20
-11654,1514566992990,21
-11655,1514567242260,20
-11656,1514567294527,18
-11657,1514567322921,19
-11658,1514567356989,19
-11659,1514567410448,19
-11660,1514567445411,19
-11661,1514567493657,19
-11662,1514567562446,19
-11663,1514567694223,18
-11664,1514567820116,18
-11665,1514567855142,17
-11666,1514567925378,17
-11667,1514567986477,17
-11668,1514568017840,15
-11669,1514568096360,16
-11670,1514568195506,15
-11671,1514568289278,15
-11672,1514568340405,15
-11673,1514568355170,15
-11674,1514568364316,17
-11675,1514568544669,20
-11676,1514568692889,19
-11677,1514568817325,18
-11678,1514568888196,17
-11679,1514568937617,17
-11680,1514568975616,17
-11681,1514569035534,18
-11682,1514569106282,18
-11683,1514569147354,19
-11684,1514569185626,20
-11685,1514569253728,20
-11686,1514569295632,19
-11687,1514569435445,20
-11688,1514569641756,18
-11689,1514569858275,18
-11690,1514569880992,17
-11691,1514569925508,18
-11692,1514569984160,18
-11693,1514570057478,18
-11694,1514570122054,17
-11695,1514570140641,17
-11696,1514570152736,18
-11697,1514570210400,20
-11698,1514570394835,21
-11699,1514570603977,21
-11700,1514570690966,20
-11701,1514570761853,19
-11702,1514570803235,19
-11703,1514570821812,19
-11704,1514570854009,21
-11705,1514570892930,21
-11706,1514570951770,22
-11707,1514570992549,22
-11708,1514571050550,24
-11709,1514571129067,25
-11710,1514571169369,24
-11711,1514571245490,26
-11712,1514571413470,26
-11713,1514571528557,25
-11714,1514571572407,25
-11715,1514571604011,26
-11716,1514571745555,27
-11717,1514571818055,27
-11718,1514571865445,26
-11719,1514571906812,27
-11720,1514571981632,28
-11721,1514572055607,28
-11722,1514572207021,28
-11723,1514572361393,27
-11724,1514572405688,26
-11725,1514572489155,27
-11726,1514572579657,27
-11727,1514572634348,27
-11728,1514572665588,27
-11729,1514572716364,28
-11730,1514572805203,29
-11731,1514572879710,28
-11732,1514572924447,29
-11733,1514573028062,29
-11734,1514573131032,28
-11735,1514573191734,28
-11736,1514573322773,27
-11737,1514573494553,27
-11738,1514573595083,27
-11739,1514573714243,27
-11740,1514573820332,25
-11741,1514573871379,26
-11742,1514573919915,26
-11743,1514573962259,26
-11744,1514574021786,27
-11745,1514574086018,28
-11746,1514574237180,27
-11747,1514574422023,26
-11748,1514574498735,26
-11749,1514574556897,25
-11750,1514574621385,25
-11751,1514574656014,25
-11752,1514574671957,25
-11753,1514574687067,28
-11754,1514574698890,31
-11755,1514574717138,37
-11756,1514575143902,39
-11757,1514575521683,39
-11758,1514575637811,38
-11759,1514575702416,38
-11760,1514575826490,37
-11761,1514575943890,37
-11762,1514575985804,37
-11763,1514576070551,37
-11764,1514576169506,38
-11765,1514576302946,36
-11766,1514576435970,36
-11767,1514576519257,35
-11768,1514576580517,35
-11769,1514576715445,35
-11770,1514576878147,35
-11771,1514576982165,34
-11772,1514577048605,33
-11773,1514577087288,33
-11774,1514577136855,34
-11775,1514577174727,36
-11776,1514577186530,37
-11777,1514577381602,43
-11778,1514577627080,42
-11779,1514577887229,40
-11780,1514578119812,39
-11781,1514578290327,39
-11782,1514578434796,38
-11783,1514578571721,37
-11784,1514578668975,36
-11785,1514578857342,37
-11786,1514579056135,35
-11787,1514579157532,34
-11788,1514579237648,34
-11789,1514579290880,33
-11790,1514579342569,33
-11791,1514579402689,34
-11792,1514579574443,33
-11793,1514579810032,32
-11794,1514579962593,31
-11795,1514580127990,31
-11796,1514580264015,29
-11797,1514580394298,31
-11798,1514580500010,29
-11799,1514580589632,29
-11800,1514580670782,28
-11801,1514580899648,27
-11802,1514581095174,26
-11803,1514581162819,25
-11804,1514581286592,26
-11805,1514581400380,26
-11806,1514581545059,25
-11807,1514581714236,24
-11808,1514581836415,23
-11809,1514581972287,22
-11810,1514582051368,21
-11811,1514582129409,21
-11812,1514582186209,21
-11813,1514582201235,20
-11814,1514582248675,22
-11815,1514582349864,22
-11816,1514582440541,22
-11817,1514582511875,21
-11818,1514582607815,21
-11819,1514582664991,21
-11820,1514582702589,21
-11821,1514582744071,21
-11822,1514582765972,21
-11823,1514582790230,22
-11824,1514582824304,22
-11825,1514582859156,23
-11826,1514582882019,23
-11827,1514582916864,24
-11828,1514582996189,25
-11829,1514583064247,25
-11830,1514583136802,24
-11831,1514583212709,24
-11832,1514583328406,23
-11833,1514583450375,23
-11834,1514583492079,22
-11835,1514583539570,22
-11836,1514583617113,21
-11837,1514583664430,21
-11838,1514583735786,20
-11839,1514583825438,20
-11840,1514583873610,18
-11841,1514583917801,18
-11842,1514583964913,19
-11843,1514584006197,18
-11844,1514584057029,18
-11845,1514584089878,18
-11846,1514584174487,18
-11847,1514584314122,17
-11848,1514584485105,16
-11849,1514584541947,15
-11850,1514584562014,14
-11851,1514584577625,14
-11852,1514584605779,16
-11853,1514584646643,18
-11854,1514584675467,19
-11855,1514584697104,23
-11856,1514584729245,26
-11857,1514584848404,27
-11858,1514585028941,26
-11859,1514585165022,25
-11860,1514585225040,24
-11861,1514585253514,24
-11862,1514585395870,25
-11863,1514585558304,25
-11864,1514585596270,24
-11865,1514585786553,23
-11866,1514585930322,24
-11867,1514586022843,23
-11868,1514586123298,23
-11869,1514586207591,23
-11870,1514586330795,22
-11871,1514586446754,21
-11872,1514586498842,20
-11873,1514586531340,20
-11874,1514586545104,22
-11875,1514586608792,25
-11876,1514586659175,26
-11877,1514586821447,29
-11878,1514586983057,29
-11879,1514587079398,27
-11880,1514587136093,27
-11881,1514587200315,27
-11882,1514587229733,27
-11883,1514587342204,28
-11884,1514587523246,27
-11885,1514587677056,27
-11886,1514587874015,26
-11887,1514588048461,25
-11888,1514588267962,24
-11889,1514588456718,24
-11890,1514588667162,24
-11891,1514588877197,23
-11892,1514589013648,22
-11893,1514589084242,22
-11894,1514589158766,21
-11895,1514589207902,21
-11896,1514589294911,21
-11897,1514589348507,20
-11898,1514589409551,20
-11899,1514589483598,20
-11900,1514589541405,20
-11901,1514589617870,20
-11902,1514589668871,18
-11903,1514589692851,18
-11904,1514589759758,19
-11905,1514589840085,19
-11906,1514589904367,18
-11907,1514590371066,18
-11908,1514591181715,17
-11909,1514591816709,16
-11910,1514592455927,14
-11911,1514592799800,13
-11912,1514593244352,12
-11913,1514594050203,12
-11914,1514594974213,11
-11915,1514595636110,12
-11916,1514595664272,11
-11917,1514595695658,10
-11918,1514595711773,10
-11919,1514595738552,10
-11920,1514595773533,10
-11921,1514595812425,11
-11922,1514595850315,11
-11923,1514595907854,11
-11924,1514595950717,12
-11925,1514596046956,11
-11926,1514596163275,12
-11927,1514596204286,11
-11928,1514596249034,12
-11929,1514596267344,12
-11930,1514596271469,12
-11931,1514596305763,19
-11932,1514596338958,19
-11933,1514596356662,19
-11934,1514596375981,21
-11935,1514596401625,23
-11936,1514596423465,24
-11937,1514596498581,27
-11938,1514596614723,26
-11939,1514596734005,26
-11940,1514596784453,25
-11941,1514597048393,25
-11942,1514597500459,25
-11943,1514597759847,24
-11944,1514597810278,23
-11945,1514597854963,23
-11946,1514597895978,24
-11947,1514598022826,24
-11948,1514598165293,24
-11949,1514598196152,23
-11950,1514598252053,23
-11951,1514598322189,23
-11952,1514598393519,25
-11953,1514598442709,24
-11954,1514598497327,25
-11955,1514598597886,26
-11956,1514598732510,26
-11957,1514598804777,27
-11958,1514598833707,26
-11959,1514598939992,27
-11960,1514598950614,26
-11961,1514598987344,32
-11962,1514599014466,33
-11963,1514599062077,35
-11964,1514599130046,35
-11965,1514599180988,36
-11966,1514599231539,36
-11967,1514599334896,37
-11968,1514599466719,36
-11969,1514599609352,36
-11970,1514599623406,35
-11971,1514599787613,40
-11972,1514600006455,39
-11973,1514600190193,38
-11974,1514600353664,38
-11975,1514600361324,39
-11976,1514600376804,50
-11977,1514600402492,57
-11978,1514600457905,60
-11979,1514600581387,61
-11980,1514600749108,61
-11981,1514600957477,61
-11982,1514601080843,61
-11983,1514601122760,61
-11984,1514601267686,62
-11985,1514601438635,62
-11986,1514601635252,61
-11987,1514601835678,60
-11988,1514601857258,59
-11989,1514601927536,63
-11990,1514601932098,63
-11991,1514602056098,95
-11992,1514602257418,94
-11993,1514602467090,93
-11994,1514602597084,92
-11995,1514602731000,91
-11996,1514602772789,91
-11997,1514603039767,94
-11998,1514603331556,92
-11999,1514603559429,90
-12000,1514603827932,89
-12001,1514603925384,87
-12002,1514604054610,87
-12003,1514604311616,87
-12004,1514604508318,85
-12005,1514604602685,84
-12006,1514604800655,84
-12007,1514605045394,83
-12008,1514605798154,81
-12009,1514606510631,78
-12010,1514606827730,75
-12011,1514607251233,73
-12012,1514607572847,71
-12013,1514607808272,69
-12014,1514608114199,66
-12015,1514608477135,65
-12016,1514608898198,62
-12017,1514609343646,60
-12018,1514609398427,58
-12019,1514609454897,58
-12020,1514609607471,58
-12021,1514609772500,57
-12022,1514609856818,55
-12023,1514610091355,54
-12024,1514610315688,52
-12025,1514610364838,50
-12026,1514610626345,50
-12027,1514610897718,47
-12028,1514610973621,46
-12029,1514611080137,44
-12030,1514611107300,43
-12031,1514611155544,48
-12032,1514611242399,48
-12033,1514611265878,46
-12034,1514611306535,50
-12035,1514611414164,52
-12036,1514611504235,51
-12037,1514611816812,50
-12038,1514611824450,49
-12039,1514611866229,62
-12040,1514611937200,63
-12041,1514612023688,61
-12042,1514612202384,60
-12043,1514612358677,58
-12044,1514612391680,56
-12045,1514612697917,58
-12046,1514612974339,56
-12047,1514613081563,53
-12048,1514613180820,51
-12049,1514613311787,49
-12050,1514613387142,48
-12051,1514613499508,47
-12052,1514613572463,46
-12053,1514613772258,44
-12054,1514613988562,41
-12055,1514614087282,40
-12056,1514614159874,38
-12057,1514614247252,36
-12058,1514614330897,34
-12059,1514614423877,33
-12060,1514614518636,31
-12061,1514614641334,31
-12062,1514614715474,30
-12063,1514614805943,29
-12064,1514614873876,28
-12065,1514615026559,27
-12066,1514615201630,24
-12067,1514615243861,22
-12068,1514615330079,21
-12069,1514615420449,19
-12070,1514615461734,17
-12071,1514615493421,18
-12072,1514615519297,17
-12073,1514615576774,16
-12074,1514615621459,14
-12075,1514615676843,11
-12076,1514615720335,15
-12077,1514615779577,17
-12078,1514615858929,18
-12079,1514615869696,17
-12080,1514615888392,19
-12081,1514615900903,19
-12082,1514616030989,20
-12083,1514616129018,19
-12084,1514616182623,18
-12085,1514616302507,17
-12086,1514616422536,15
-12087,1514616482910,13
-12088,1514616496904,11
-12089,1514616504990,14
-12090,1514616514167,17
-12091,1514616528484,35
-12092,1514616577522,40
-12093,1514616720570,40
-12094,1514616837088,39
-12095,1514616891562,39
-12096,1514617014223,39
-12097,1514617041536,40
-12098,1514617114092,41
-12099,1514617197512,42
-12100,1514617216412,41
-12101,1514617241233,44
-12102,1514617287589,48
-12103,1514617415075,48
-12104,1514617577701,48
-12105,1514617922790,46
-12106,1514618490492,46
-12107,1514618764247,43
-12108,1514618902500,42
-12109,1514619162392,41
-12110,1514619352511,39
-12111,1514619383704,38
-12112,1514619407492,39
-12113,1514619517007,40
-12114,1514619528254,39
-12115,1514619535891,45
-12116,1514619579644,58
-12117,1514619630928,58
-12118,1514619656283,58
-12119,1514619678057,62
-12120,1514619931067,67
-12121,1514620034766,65
-12122,1514620430145,64
-12123,1514620493596,62
-12124,1514620805512,63
-12125,1514621546730,60
-12126,1514622135343,59
-12127,1514622300708,56
-12128,1514622387922,54
-12129,1514622483107,54
-12130,1514622526199,53
-12131,1514622620097,55
-12132,1514622732980,54
-12133,1514622800680,53
-12134,1514622808268,55
-12135,1514622843994,71
-12136,1514622901277,73
-12137,1514623004564,74
-12138,1514623087225,73
-12139,1514623412745,80
-12140,1514623442893,80
-12141,1514623526613,84
-12142,1514623576665,84
-12143,1514623629335,86
-12144,1514623750722,87
-12145,1514623942915,88
-12146,1514624089055,86
-12147,1514624699385,85
-12148,1514625583750,83
-12149,1514625787242,81
-12150,1514626025726,79
-12151,1514626355636,77
-12152,1514626712712,75
-12153,1514626920118,74
-12154,1514627177557,72
-12155,1514627257856,70
-12156,1514627368992,70
-12157,1514627643104,68
-12158,1514627971226,67
-12159,1514628209075,64
-12160,1514628898962,63
-12161,1514629435720,60
-12162,1514629500910,57
-12163,1514629596974,58
-12164,1514629730208,56
-12165,1514629777299,55
-12166,1514629881613,55
-12167,1514630107040,54
-12168,1514630376154,52
-12169,1514630568487,49
-12170,1514630718436,47
-12171,1514630723001,45
-12172,1514631013906,66
-12173,1514631296242,64
-12174,1514631643755,62
-12175,1514631797771,60
-12176,1514632328684,57
-12177,1514632368542,55
-12178,1514632429614,55
-12179,1514632447229,54
-12180,1514632572746,60
-12181,1514632606433,59
-12182,1514632654601,61
-12183,1514632681815,61
-12184,1514632824327,63
-12185,1514632889437,61
-12186,1514632913106,60
-12187,1514633063267,62
-12188,1514633142176,60
-12189,1514633340529,59
-12190,1514633370931,58
-12191,1514633571358,61
-12192,1514633831175,62
-12193,1514633859015,60
-12194,1514633908129,61
-12195,1514633919087,61
-12196,1514633931306,71
-12197,1514634321885,82
-12198,1514634511503,81
-12199,1514634747653,79
-12200,1514635006388,76
-12201,1514635096898,75
-12202,1514635229373,76
-12203,1514635344897,74
-12204,1514635683451,72
-12205,1514636109334,69
-12206,1514636392682,66
-12207,1514636540430,62
-12208,1514636686988,60
-12209,1514636972463,58
-12210,1514637147328,54
-12211,1514637454548,51
-12212,1514637708302,50
-12213,1514637804761,48
-12214,1514638015889,45
-12215,1514638372203,47
-12216,1514638491243,50
-12217,1514638538758,50
-12218,1514638650664,50
-12219,1514638726095,51
-12220,1514638758747,53
-12221,1514638833204,54
-12222,1514638911783,52
-12223,1514638986529,51
-12224,1514639059491,50
-12225,1514639135439,49
-12226,1514639139965,48
-12227,1514639375985,70
-12228,1514639574224,67
-12229,1514639761261,64
-12230,1514639801952,63
-12231,1514639816153,64
-12232,1514640164763,72
-12233,1514640542134,69
-12234,1514640732591,66
-12235,1514640996665,72
-12236,1514641274229,71
-12237,1514641418024,71
-12238,1514641737914,69
-12239,1514641823820,67
-12240,1514641950011,65
-12241,1514642137259,67
-12242,1514642141593,65
-12243,1514642309471,99
-12244,1514642548146,100
-12245,1514642610374,98
-12246,1514643002689,97
-12247,1514643480981,95
-12248,1514644230304,92
-12249,1514644538788,89
-12250,1514644762113,86
-12251,1514644814070,83
-12252,1514645014255,84
-12253,1514645085136,80
-12254,1514645221093,80
-12255,1514645261991,78
-12256,1514645380670,79
-12257,1514645484173,78
-12258,1514645592516,76
-12259,1514645864933,74
-12260,1514646278584,71
-12261,1514646589200,67
-12262,1514646816661,63
-12263,1514646824368,61
-12264,1514647030886,77
-12265,1514647367989,74
-12266,1514647607616,71
-12267,1514647704261,69
-12268,1514647741314,67
-12269,1514648055057,67
-12270,1514648075687,63
-12271,1514648103539,67
-12272,1514648140256,80
-12273,1514648710756,81
-12274,1514648960765,78
-12275,1514649208512,75
-12276,1514649212874,72
-12277,1514649615515,108
-12278,1514649770921,105
-12279,1514649872982,103
-12280,1514650270690,104
-12281,1514650777931,101
-12282,1514650920276,99
-12283,1514651169880,97
-12284,1514651538228,96
-12285,1514651585262,93
-12286,1514652175205,95
-12287,1514652950935,94
-12288,1514652972408,90
-12289,1514653207419,96
-12290,1514653591972,93
-12291,1514653655136,91
-12292,1514653891563,91
-12293,1514654209369,86
-12294,1514654526023,85
-12295,1514654713314,83
-12296,1514654832563,87
-12297,1514654951047,91
-12298,1514655024886,90
-12299,1514655126062,89
-12300,1514655491638,87
-12301,1514655508665,83
-12302,1514655709453,92
-12303,1514656086529,90
-12304,1514656657184,87
-12305,1514657187831,83
-12306,1514657418233,79
-12307,1514657669233,76
-12308,1514657735518,73
-12309,1514657958797,72
-12310,1514658211558,69
-12311,1514658253255,66
-12312,1514658686612,65
-12313,1514659114830,61
-12314,1514659132669,58
-12315,1514659167471,61
-12316,1514659484798,61
-12317,1514659845319,58
-12318,1514660012784,55
-12319,1514660177601,51
-12320,1514660194595,49
-12321,1514660224785,53
-12322,1514660305122,53
-12323,1514660398959,52
-12324,1514660797557,49
-12325,1514661297875,46
-12326,1514661414530,42
-12327,1514661614984,52
-12328,1514661871591,48
-12329,1514661948078,45
-12330,1514662048494,43
-12331,1514662056072,42
-12332,1514662132894,56
-12333,1514662214549,54
-12334,1514662269169,52
-12335,1514662384192,50
-12336,1514662774990,48
-12337,1514662844594,44
-12338,1514663040034,42
-12339,1514663060863,38
-12340,1514663122567,39
-12341,1514663176120,37
-12342,1514663203315,35
-12343,1514663271516,52
-12344,1514663352275,51
-12345,1514663443273,49
-12346,1514663529686,49
-12347,1514663603831,46
-12348,1514663791186,45
-12349,1514663857935,41
-12350,1514663953820,40
-12351,1514664101798,38
-12352,1514664165289,36
-12353,1514664292383,34
-12354,1514664370096,33
-12355,1514664523830,31
-12356,1514664646605,30
-12357,1514664736649,28
-12358,1514664882572,26
-12359,1514664926835,23
-12360,1514664931118,21
-12361,1514664959705,29
-12362,1514665146027,28
-12363,1514665183293,25
-12364,1514665231527,33
-12365,1514665372565,31
-12366,1514665470403,28
-12367,1514665587439,26
-12368,1514665674242,24
-12369,1514665774956,23
-12370,1514665878688,20
-12371,1514665975576,21
-12372,1514666016907,21
-12373,1514666028694,22
-12374,1514666082112,23
-12375,1514666128919,21
-12376,1514666182876,19
-12377,1514666227804,37
-12378,1514666320148,37
-12379,1514666334288,36
-12380,1514666446806,40
-12381,1514666553342,39
-12382,1514666781365,37
-12383,1514666936970,36
-12384,1514667071842,34
-12385,1514667290199,32
-12386,1514667340052,32
-12387,1514667351513,31
-12388,1514667380779,35
-12389,1514667392379,41
-12390,1514667463105,45
-12391,1514667527419,46
-12392,1514667575241,46
-12393,1514667732125,46
-12394,1514667792585,45
-12395,1514667974799,44
-12396,1514668041721,41
-12397,1514668125546,41
-12398,1514668163372,40
-12399,1514668180969,42
-12400,1514668324851,46
-12401,1514668470909,44
-12402,1514668494528,48
-12403,1514668525354,50
-12404,1514668645335,52
-12405,1514668858262,50
-12406,1514669099879,48
-12407,1514669169444,46
-12408,1514669263321,45
-12409,1514669306659,45
-12410,1514669452163,45
-12411,1514669466661,43
-12412,1514669703798,50
-12413,1514670197710,47
-12414,1514670587306,45
-12415,1514670955014,46
-12416,1514671323062,46
-12417,1514671449999,44
-12418,1514671631768,42
-12419,1514671859179,40
-12420,1514672045810,38
-12421,1514672073568,40
-12422,1514672171483,43
-12423,1514672176240,42
-12424,1514672442168,61
-12425,1514672754980,59
-12426,1514673057739,57
-12427,1514673362410,54
-12428,1514673453785,52
-12429,1514673521354,51
-12430,1514673927805,51
-12431,1514674461090,49
-12432,1514674583631,52
-12433,1514674604966,52
-12434,1514674654938,56
-12435,1514674793215,57
-12436,1514674927426,55
-12437,1514674971175,54
-12438,1514675018481,55
-12439,1514675058618,55
-12440,1514675108186,58
-12441,1514675136704,59
-12442,1514675364410,61
-12443,1514675741816,61
-12444,1514675948493,60
-12445,1514675972472,58
-12446,1514675976925,62
-12447,1514676157116,93
-12448,1514676535161,91
-12449,1514676788989,89
-12450,1514677047781,87
-12451,1514677124081,85
-12452,1514677210946,85
-12453,1514677280258,84
-12454,1514677379335,84
-12455,1514677623274,83
-12456,1514677975532,81
-12457,1514678112197,79
-12458,1514678293658,76
-12459,1514678424792,74
-12460,1514678553127,73
-12461,1514678738693,77
-12462,1514678749715,76
-12463,1514678793151,89
-12464,1514679042412,91
-12465,1514679314421,89
-12466,1514679593763,86
-12467,1514679816657,85
-12468,1514680345039,82
-12469,1514680949541,79
-12470,1514681495193,76
-12471,1514681540481,73
-12472,1514681723132,73
-12473,1514681991358,72
-12474,1514682074233,70
-12475,1514682193737,70
-12476,1514682279489,68
-12477,1514682440263,67
-12478,1514682487952,65
-12479,1514682789017,65
-12480,1514682833052,66
-12481,1514683183885,65
-12482,1514683797313,63
-12483,1514684110466,60
-12484,1514684152897,57
-12485,1514684238898,57
-12486,1514684246906,55
-12487,1514684612248,69
-12488,1514684786421,69
-12489,1514685015712,68
-12490,1514685168137,69
-12491,1514685425100,67
-12492,1514685579632,65
-12493,1514685601212,63
-12494,1514685633485,67
-12495,1514686322026,70
-12496,1514687437036,67
-12497,1514688630669,64
-12498,1514688694483,60
-12499,1514688771126,59
-12500,1514688793353,62
-12501,1514688951742,65
-12502,1514689290646,62
-12503,1514689653471,62
-12504,1514689681081,61
-12505,1514689785666,63
-12506,1514689901207,61
-12507,1514690007122,59
-12508,1514690394889,58
-12509,1514690406763,54
-12510,1514690428411,63
-12511,1514690491263,67
-12512,1514690623249,68
-12513,1514690776731,66
-12514,1514690859533,64
-12515,1514691236294,62
-12516,1514691407430,58
-12517,1514691574703,56
-12518,1514691686847,54
-12519,1514691750576,51
-12520,1514691783807,49
-12521,1514691808802,48
-12522,1514691850610,51
-12523,1514691898537,51
-12524,1514691953115,60
-12525,1514692205932,59
-12526,1514692233025,56
-12527,1514692268576,58
-12528,1514692310898,58
-12529,1514692363811,58
-12530,1514692377910,58
-12531,1514692471181,64
-12532,1514692676072,62
-12533,1514692882789,59
-12534,1514693018162,58
-12535,1514693140460,57
-12536,1514693182097,55
-12537,1514693209128,54
-12538,1514693366275,57
-12539,1514693528944,55
-12540,1514693593876,53
-12541,1514693681924,52
-12542,1514693898248,52
-12543,1514694335083,50
-12544,1514694401459,46
-12545,1514694406047,44
-12546,1514694648038,66
-12547,1514694912057,80
-12548,1514694950706,78
-12549,1514695033191,80
-12550,1514695062317,78
-12551,1514695335097,82
-12552,1514695536244,80
-12553,1514695808479,78
-12554,1514695852887,77
-12555,1514696007892,77
-12556,1514696048240,75
-12557,1514696179082,77
-12558,1514696341194,75
-12559,1514696509315,72
-12560,1514696565989,70
-12561,1514697073454,70
-12562,1514697255357,67
-12563,1514697749208,72
-12564,1514697823715,72
-12565,1514697955764,71
-12566,1514698202520,70
-12567,1514698455444,67
-12568,1514698839126,64
-12569,1514699026277,61
-12570,1514699176096,59
-12571,1514699336720,56
-12572,1514699360979,56
-12573,1514699544912,58
-12574,1514699578884,55
-12575,1514699616374,56
-12576,1514699742952,57
-12577,1514699865744,55
-12578,1514700057784,53
-12579,1514700198712,52
-12580,1514700303720,49
-12581,1514700324727,49
-12582,1514700375085,51
-12583,1514700392772,50
-12584,1514700439446,53
-12585,1514700591298,53
-12586,1514700768197,51
-12587,1514700882557,57
-12588,1514701155929,54
-12589,1514701218357,52
-12590,1514701436348,51
-12591,1514701646331,48
-12592,1514701680437,45
-12593,1514701743307,46
-12594,1514701823268,47
-12595,1514702090569,48
-12596,1514702232092,45
-12597,1514702392384,43
-12598,1514702492200,40
-12599,1514702506176,38
-12600,1514702793083,42
-12601,1514703107989,43
-12602,1514703143729,40
-12603,1514703172024,40
-12604,1514703183997,40
-12605,1514703383793,46
-12606,1514703395274,44
-12607,1514703423447,51
-12608,1514703558427,53
-12609,1514703913314,49
-12610,1514703927419,52
-12611,1514704039074,60
-12612,1514704062939,60
-12613,1514704083434,62
-12614,1514704214763,67
-12615,1514704228648,65
-12616,1514704297289,73
-12617,1514704588308,72
-12618,1514704904428,69
-12619,1514705161152,67
-12620,1514705254407,64
-12621,1514705271420,63
-12622,1514705421122,71
-12623,1514705745721,70
-12624,1514706036554,68
-12625,1514706467783,66
-12626,1514706816714,62
-12627,1514706943249,61
-12628,1514706950887,60
-12629,1514707031437,78
-12630,1514707135116,78
-12631,1514707228642,81
-12632,1514707318409,80
-12633,1514707741993,78
-12634,1514708302999,75
-12635,1514708408077,72
-12636,1514708416122,71
-12637,1514708477771,90
-12638,1514708815391,92
-12639,1514708968725,88
-12640,1514709068882,86
-12641,1514709073314,85
-12642,1514709153830,128
-12643,1514709194739,128
-12644,1514709463930,130
-12645,1514710826499,127
-12646,1514712194261,134
-12647,1514712442063,130
-12648,1514712446546,128
-12649,1514712916556,194
-12650,1514713145902,190
-12651,1514713500316,190
-12652,1514714376809,186
-12653,1514714473190,182
-12654,1514715686797,181
-12655,1514715969981,179
-12656,1514716478796,175
-12657,1514716939937,173
-12658,1514718626234,169
-12659,1514718956219,164
-12660,1514719313927,160
-12661,1514719385550,157
-12662,1514719482074,157
-12663,1514719898571,156
-12664,1514721256622,152
-12665,1514721260826,148
-12666,1514721382539,227
-12667,1514722029046,226
-12668,1514723869500,220
-12669,1514723965231,214
-12670,1514724233656,213
-12671,1514724630018,208
-12672,1514724793725,203
-12673,1514724858491,202
-12674,1514725234660,203
-12675,1514725404690,200
-12676,1514725408965,197
-12677,1514725524401,302
-12678,1514725614045,300
-12679,1514725843041,299
-12680,1514726184228,295
-12681,1514726500436,288
-12682,1514727401685,285
-12683,1514727531764,277
-12684,1514728005788,277
-12685,1514729023495,271
-12686,1514729382140,264
-12687,1514729868713,257
-12688,1514730036154,251
-12689,1514730089565,246
-12690,1514731639321,249
-12691,1514733225566,240
-12692,1514734925465,233
-12693,1514735166328,225
-12694,1514735370208,220
-12695,1514735627518,214
-12696,1514735694944,208
-12697,1514735790703,207
-12698,1514736342683,204
-12699,1514736497456,196
-12700,1514736919695,194
-12701,1514737803919,185
-12702,1514737915077,177
-12703,1514737994441,173
-12704,1514738099875,172
-12705,1514738344593,170
-12706,1514738691942,163
-12707,1514739160070,160
-12708,1514739610208,154
-12709,1514739693720,147
-12710,1514740064952,142
-12711,1514740144545,139
-12712,1514740326178,135
-12713,1514740559264,131
-12714,1514740767448,128
-12715,1514740997922,121
-12716,1514741362780,119
-12717,1514741586908,113
-12718,1514742068254,106
-12719,1514742603515,98
-12720,1514742702660,90
-12721,1514742889281,84
-12722,1514742929666,82
-12723,1514743036919,79
-12724,1514743205010,72
-12725,1514743229090,66
-12726,1514743273934,64
-12727,1514743564933,59
-12728,1514743605509,52
-12729,1514743636035,56
-12730,1514743697700,53
-12731,1514743860467,48
-12732,1514744056119,41
-12733,1514744309378,34
-12734,1514744321036,26
-12735,1514744366896,24
-12736,1514744380799,18
-12737,1514744391875,23
-12738,1514744396040,22
-12739,1514744400370,26
-12740,1514744411129,33
-12741,1514744431701,33
-12742,1514744456986,52
-12743,1514744540120,51
-12744,1514744577921,48
-12745,1514744809614,44
-12746,1514744826766,37
-12747,1514744971782,34
-12748,1514744982669,28
-12749,1514745010666,61
-12750,1514745024673,59
-12751,1514745052745,63
-12752,1514745187458,62
-12753,1514745371392,57
-12754,1514745524279,52
-12755,1514745730629,45
-12756,1514745788637,40
-12757,1514745829076,34
-12758,1514745865745,30
-12759,1514745880008,25
-12760,1514745939127,22
-12761,1514746010125,17
-12762,1514746126261,12
-12763,1514746166483,7
-12764,1514746227980,1
-12765,1514746232473,1
-12766,1514746244683,30
-12767,1514746335124,33
-12768,1514746500513,28
-12769,1514746537404,23
-12770,1514746614955,21
-12771,1514746623030,17
-12772,1514746673712,16
-12773,1514746738511,13
-12774,1514746742783,12
-12775,1514746746922,13
-12776,1514746834100,16
-12777,1514746870970,68
-12778,1514746895567,71
-12779,1514747601632,78
-12780,1514747698171,75
-12781,1514747862377,74
-12782,1514748047321,72
-12783,1514748104959,70
-12784,1514748112639,71
-12785,1514748146368,89
-12786,1514748425048,92
-12787,1514748501694,89
-12788,1514748898089,88
-12789,1514749249878,85
-12790,1514749583742,87
-12791,1514749643384,84
-12792,1514749660449,83
-12793,1514749854031,91
-12794,1514750350644,89
-12795,1514750404158,85
-12796,1514750488298,85
-12797,1514750945236,87
-12798,1514751151714,86
-12799,1514751418028,83
-12800,1514751567639,81
-12801,1514751578555,78
-12802,1514751810610,92
-12803,1514752107223,89
-12804,1514752430838,89
-12805,1514752724282,87
-12806,1514753052671,84
-12807,1514753519536,81
-12808,1514753543723,77
-12809,1514753701247,80
-12810,1514753862037,79
-12811,1514754720414,77
-12812,1514754916488,74
-12813,1514755279857,72
-12814,1514755585702,68
-12815,1514756013973,65
-12816,1514756327490,62
-12817,1514756368074,59
-12818,1514756492615,58
-12819,1514756727678,55
-12820,1514756732004,51
-12821,1514756821731,77
-12822,1514756829780,74
-12823,1514756844021,94
-12824,1514756963902,106
-12825,1514758049879,103
-12826,1514759482991,101
-12827,1514759676365,99
-12828,1514759729783,95
-12829,1514759880950,96
-12830,1514759892705,94
-12831,1514759907759,108
-12832,1514760090148,121
-12833,1514760143787,117
-12834,1514760275514,117
-12835,1514760462065,116
-12836,1514760560894,112
-12837,1514760715404,111
-12838,1514760825926,109
-12839,1514760900111,113
-12840,1514760998547,119
-12841,1514761685559,120
-12842,1514762402662,117
-12843,1514762766486,115
-12844,1514762774512,111
-12845,1514763455087,140
-12846,1514763679800,135
-12847,1514763867389,134
-12848,1514764136211,130
-12849,1514764420211,130
-12850,1514764460617,127
-12851,1514764547554,135
-12852,1514764739937,136
-12853,1514764771271,133
-12854,1514765030621,139
-12855,1514765070435,135
-12856,1514765120419,137
-12857,1514765475339,139
-12858,1514765924369,136
-12859,1514766127656,132
-12860,1514766407434,129
-12861,1514766749211,125
-12862,1514766819373,121
-12863,1514766884584,120
-12864,1514767262686,118
-12865,1514767452717,113
-12866,1514767891365,109
-12867,1514768467945,107
-12868,1514768681589,102
-12869,1514769213855,98
-12870,1514769739359,93
-12871,1514770111395,89
-12872,1514770525485,87
-12873,1514770780068,81
-12874,1514770942046,77
-12875,1514771004854,75
-12876,1514771145761,77
-12877,1514771437501,73
-12878,1514771783658,70
-12879,1514771937932,69
-12880,1514771991523,65
-12881,1514772101962,63
-12882,1514772122419,60
-12883,1514772328962,62
-12884,1514772392909,59
-12885,1514772530431,67
-12886,1514772551023,66
-12887,1514772578111,70
-12888,1514773095296,73
-12889,1514773950976,67
-12890,1514773958777,63
-12891,1514774126997,77
-12892,1514774375389,75
-12893,1514774621052,76
-12894,1514774799212,73
-12895,1514774886445,68
-12896,1514774979894,66
-12897,1514775003547,64
-12898,1514775040520,65
-12899,1514775051270,66
-12900,1514775161702,75
-12901,1514775207453,71
-12902,1514775602993,79
-12903,1514776158712,74
-12904,1514776270123,69
-12905,1514776401884,66
-12906,1514776448617,62
-12907,1514776466161,60
-12908,1514776487054,63
-12909,1514776504391,69
-12910,1514776574403,73
-12911,1514776712460,71
-12912,1514776736129,66
-12913,1514776766750,68
-12914,1514776777183,68
-12915,1514777013476,78
-12916,1514777043617,73
-12917,1514777186226,72
-12918,1514777657633,70
-12919,1514777718165,64
-12920,1514777997387,61
-12921,1514778034152,70
-12922,1514778196206,70
-12923,1514778381268,76
-12924,1514779184084,80
-12925,1514779365990,77
-12926,1514779608342,72
-12927,1514779864605,68
-12928,1514779921561,64
-12929,1514779960985,64
-12930,1514780008028,63
-12931,1514780184037,71
-12932,1514780270958,75
-12933,1514780757081,73
-12934,1514780890748,72
-12935,1514780953494,70
-12936,1514781020347,69
-12937,1514781144071,68
-12938,1514781242382,65
-12939,1514781442420,63
-12940,1514781548173,61
-12941,1514781672271,60
-12942,1514781900215,56
-12943,1514781910973,53
-12944,1514782242369,60
-12945,1514782266362,72
-12946,1514782469680,75
-12947,1514782541698,74
-12948,1514782726119,71
-12949,1514782878511,69
-12950,1514782906386,67
-12951,1514782985825,72
-12952,1514783056850,72
-12953,1514783145327,71
-12954,1514783264673,73
-12955,1514783363948,72
-12956,1514783490741,73
-12957,1514783791737,74
-12958,1514783890261,70
-12959,1514784125595,69
-12960,1514784140180,66
-12961,1514784187256,74
-12962,1514784505881,74
-12963,1514784783470,72
-12964,1514785013847,71
-12965,1514785420723,67
-12966,1514785908668,64
-12967,1514786226234,61
-12968,1514786233981,58
-12969,1514786315431,72
-12970,1514786375716,70
-12971,1514786478303,68
-12972,1514786742982,66
-12973,1514786813296,63
-12974,1514787206623,61
-12975,1514787681379,58
-12976,1514787688793,55
-12977,1514787726716,68
-12978,1514787996872,69
-12979,1514788027375,65
-12980,1514788246405,66
-12981,1514788448331,63
-12982,1514788488118,60
-12983,1514788518733,63
-12984,1514788642153,63
-12985,1514788666083,60
-12986,1514788683165,63
-12987,1514788701421,71
-12988,1514788998359,79
-12989,1514789029618,74
-12990,1514789080380,76
-12991,1514789136556,84
-12992,1514789291338,84
-12993,1514789469960,80
-12994,1514789557097,77
-12995,1514789597349,75
-12996,1514790091150,75
-12997,1514790105502,72
-12998,1514790341389,83
-12999,1514790352073,81
-13000,1514790415011,102
-13001,1514790422667,101
-13002,1514790596600,130
-13003,1514790620039,127
-13004,1514790890121,134
-13005,1514790977763,131
-13006,1514791201922,129
-13007,1514791272252,127
-13008,1514791631120,130
-13009,1514791940247,129
-13010,1514792291069,130
-13011,1514792398170,126
-13012,1514792543614,124
-13013,1514792587895,125
-13014,1514792651147,129
-13015,1514792998961,137
-13016,1514793047046,133
-13017,1514793118304,138
-13018,1514793361280,138
-13019,1514793613639,134
-13020,1514793645344,132
-13021,1514793716964,137
-13022,1514793973207,139
-13023,1514795049285,135
-13024,1514795181723,131
-13025,1514795624004,128
-13026,1514796160113,124
-13027,1514796528747,119
-13028,1514796532950,115
-13029,1514796547249,177
-13030,1514796611214,203
-13031,1514796809790,205
-13032,1514797068698,202
-13033,1514798040753,198
-13034,1514798287216,192
-13035,1514798723953,187
-13036,1514798851909,183
-13037,1514799373703,181
-13038,1514800024574,176
-13039,1514800268291,170
-13040,1514800762159,166
-13041,1514800942591,161
-13042,1514800946834,156
-13043,1514801501491,238
-13044,1514802684839,238
-13045,1514802757048,231
-13046,1514803003923,233
-13047,1514803700690,229
-13048,1514803796528,223
-13049,1514803875374,221
-13050,1514803993594,220
-13051,1514804051931,219
-13052,1514804260289,221
-13053,1514804346565,217
-13054,1514804562707,217
-13055,1514804971745,211
-13056,1514805134243,205
-13057,1514805155415,201
-13058,1514805409913,215
-13059,1514805768589,210
-13060,1514806330682,203
-13061,1514806416969,201
-13062,1514806476490,200
-13063,1514806653091,200
-13064,1514806758433,195
-13065,1514807405959,190
-13066,1514808331623,183
-13067,1514808714048,174
-13068,1514808837801,167
-13069,1514809391297,171
-13070,1514810460372,165
-13071,1514810757889,158
-13072,1514811243469,151
-13073,1514811643732,145
-13074,1514811831828,137
-13075,1514811932370,131
-13076,1514812148415,126
-13077,1514812643374,129
-13078,1514813327497,123
-13079,1514813404485,116
-13080,1514813661628,114
-13081,1514813688807,107
-13082,1514814282948,109
-13083,1514814472539,103
-13084,1514814661558,99
-13085,1514814747808,93
-13086,1514814939491,90
-13087,1514814983517,88
-13088,1514815378153,90
-13089,1514815779680,83
-13090,1514816190791,78
-13091,1514816263647,73
-13092,1514816369238,69
-13093,1514816384365,63
-13094,1514816749378,67
-13095,1514816813179,60
-13096,1514816861804,56
-13097,1514816873184,51
-13098,1514816970536,60
-13099,1514817039756,55
-13100,1514817129582,58
-13101,1514817192231,54
-13102,1514817510303,65
-13103,1514817712517,60
-13104,1514817833917,59
-13105,1514817987634,54
-13106,1514818060865,50
-13107,1514818123654,45
-13108,1514818209638,43
-13109,1514818386930,38
-13110,1514818553579,32
-13111,1514818691510,25
-13112,1514818864194,21
-13113,1514818908764,15
-13114,1514818924075,12
-13115,1514818962253,11
-13116,1514819028645,5
-13117,1514819096777,2
-13118,1514819115276,1
-13119,1514819119680,1
-13120,1514819131555,1
-13121,1514819139467,1
-13122,1514819151473,1
-13123,1514819160246,1
-13124,1514819168910,1
-13125,1514819176346,1
-13126,1514819180615,1
-13127,1514819185383,1
-13128,1514819189805,1
-13129,1514819198985,1
-13130,1514819203157,1
-13131,1514819210594,1
-13132,1514819215194,1
-13133,1514819223938,1
-13134,1514819231975,1
-13135,1514819236235,1
-13136,1514819240722,1
-13137,1514819249283,1
-13138,1514819261441,1
-13139,1514819265828,1
-13140,1514819270135,1
-13141,1514819274761,1
-13142,1514819286633,1
-13143,1514819295104,1
-13144,1514819299358,1
-13145,1514819307147,1
-13146,1514819311439,1
-13147,1514819315564,1
-13148,1514819323139,1
-13149,1514819331942,1
-13150,1514819336242,1
-13151,1514819340650,1
-13152,1514819349256,1
-13153,1514819361449,1
-13154,1514819370174,1
-13155,1514819377782,1
-13156,1514819382173,1
-13157,1514819386403,1
-13158,1514819390872,1
-13159,1514819399333,1
-13160,1514819403826,1
-13161,1514819412978,1
-13162,1514819422053,1
-13163,1514819430902,1
-13164,1514819443236,1
-13165,1514819451719,1
-13166,1514819456035,1
-13167,1514819460574,1
-13168,1514819465039,1
-13169,1514819472764,1
-13170,1514819477177,1
-13171,1514819481403,1
-13172,1514819485903,1
-13173,1514819494419,1
-13174,1514819498707,1
-13175,1514819503184,1
-13176,1514819508016,1
-13177,1514819512354,1
-13178,1514819520963,1
-13179,1514819525475,1
-13180,1514819529717,1
-13181,1514819534111,1
-13182,1514819538449,1
-13183,1514819546139,1
-13184,1514819550441,1
-13185,1514819554650,1
-13186,1514819558980,1
-13187,1514819563282,1
-13188,1514819567545,1
-13189,1514819571887,1
-13190,1514819576057,1
-13191,1514819584564,1
-13192,1514819588772,1
-13193,1514819593302,1
-13194,1514819601821,1
-13195,1514819610386,1
-13196,1514819615230,1
-13197,1514819623859,2
-13198,1514819632963,6
-13199,1514819640402,8
-13200,1514819658155,11
-13201,1514819715238,13
-13202,1514819719617,13
-13203,1514819738357,20
-13204,1514819815486,22
-13205,1514819823050,22
-13206,1514819905542,28
-13207,1514819929361,29
-13208,1514820002617,32
-13209,1514820036237,32
-13210,1514820093827,35
-13211,1514820154309,35
-13212,1514820249359,36
-13213,1514820305766,35
-13214,1514820342601,36
-13215,1514820428847,38
-13216,1514820534992,38
-13217,1514820545934,39
-13218,1514820590602,46
-13219,1514820719032,47
-13220,1514820876917,47
-13221,1514821031304,46
-13222,1514821231477,46
-13223,1514821488005,45
-13224,1514821518425,45
-13225,1514821591162,48
-13226,1514821598931,47
-13227,1514821666164,61
-13228,1514821696788,62
-13229,1514822263016,65
-13230,1514822448272,64
-13231,1514822674687,64
-13232,1514822698563,63
-13233,1514823179011,67
-13234,1514823885208,66
-13235,1514824175442,65
-13236,1514824269907,64
-13237,1514824422166,64
-13238,1514824678446,63
-13239,1514824810598,62
-13240,1514824888026,62
-13241,1514825199169,62
-13242,1514825236924,61
-13243,1514825247858,64
-13244,1514825350589,76
-13245,1514825354975,76
-13246,1514825776102,115
-13247,1514825845627,113
-13248,1514825958086,115
-13249,1514826139360,114
-13250,1514826509220,114
-13251,1514826886010,111
-13252,1514827010284,110
-13253,1514827206076,109
-13254,1514827454169,108
-13255,1514827478283,106
-13256,1514827557958,114
-13257,1514827710522,114
-13258,1514828123840,113
-13259,1514828306668,111
-13260,1514828317793,110
-13261,1514828485695,130
-13262,1514828683200,129
-13263,1514828783130,127
-13264,1514828836896,126
-13265,1514829146090,129
-13266,1514829231442,126
-13267,1514829291926,126
-13268,1514829365996,128
-13269,1514829384233,129
-13270,1514829659582,142
-13271,1514830105991,140
-13272,1514830803508,136
-13273,1514831208951,133
-13274,1514831240419,130
-13275,1514831321456,135
-13276,1514831406848,135
-13277,1514831476801,135
-13278,1514831559655,135
-13279,1514831808203,135
-13280,1514831838789,133
-13281,1514831943840,138
-13282,1514832208968,138
-13283,1514832558560,135
-13284,1514832663883,130
-13285,1514832832276,129
-13286,1514832836685,127
-13287,1514833492861,191
-13288,1514833624287,187
-13289,1514833935297,184
-13290,1514833952691,180
-13291,1514834129122,200
-13292,1514834245140,196
-13293,1514834628895,194
-13294,1514834759954,190
-13295,1514835548687,187
-13296,1514835682892,181
-13297,1514836226119,179
-13298,1514837288297,173
-13299,1514837508251,168
-13300,1514838913701,165
-13301,1514838937811,159
-13302,1514839634617,169
-13303,1514839713593,166
-13304,1514839819725,167
-13305,1514839975080,164
-13306,1514840638062,163
-13307,1514841250749,158
-13308,1514841439288,153
-13309,1514841765912,150
-13310,1514842148948,145
-13311,1514842216316,141
-13312,1514842436566,140
-13313,1514842748707,135
-13314,1514842766338,130
-13315,1514842951477,143
-13316,1514843208133,139
-13317,1514843913060,133
-13318,1514843954164,131
-13319,1514844382112,134
-13320,1514844655587,128
-13321,1514845007094,123
-13322,1514845101286,118
-13323,1514845273506,114
-13324,1514845797798,109
-13325,1514846224576,105
-13326,1514846275033,99
-13327,1514846362469,105
-13328,1514846418272,102
-13329,1514846561392,102
-13330,1514846610763,98
-13331,1514846828676,97
-13332,1514847310623,91
-13333,1514847779683,88
-13334,1514847903921,82
-13335,1514848154868,77
-13336,1514848192285,71
-13337,1514848352966,70
-13338,1514848512965,65
-13339,1514848567893,60
-13340,1514848638630,57
-13341,1514848692261,53
-13342,1514848749562,48
-13343,1514848820261,46
-13344,1514848870616,48
-13345,1514848937847,45
-13346,1514849286727,62
-13347,1514849914725,56
-13348,1514849961276,53
-13349,1514850093921,51
-13350,1514850101814,46
-13351,1514850205299,55
-13352,1514850236091,51
-13353,1514850360373,50
-13354,1514850374688,45
-13355,1514850460149,47
-13356,1514850590155,48
-13357,1514850630092,44
-13358,1514850699088,42
-13359,1514850836102,38
-13360,1514850851505,33
-13361,1514850917935,45
-13362,1514850989916,42
-13363,1514851126905,38
-13364,1514851151104,34
-13365,1514851162037,35
-13366,1514851205615,37
-13367,1514851288786,36
-13368,1514851378644,34
-13369,1514851424858,31
-13370,1514851438780,36
-13371,1514851443127,37
-13372,1514851483960,52
-13373,1514851600301,50
-13374,1514851690305,46
-13375,1514851875494,46
-13376,1514852017953,43
-13377,1514852095337,40
-13378,1514852274837,39
-13379,1514852341676,35
-13380,1514852421971,31
-13381,1514852463998,33
-13382,1514852504208,31
-13383,1514852557349,28
-13384,1514852587788,25
-13385,1514852602292,22
-13386,1514852609901,22
-13387,1514852620629,59
-13388,1514852671679,68
-13389,1514852848024,69
-13390,1514852911859,65
-13391,1514852988271,76
-13392,1514853088904,76
-13393,1514853490774,76
-13394,1514853514313,72
-13395,1514853710088,77
-13396,1514853730814,74
-13397,1514853751877,81
-13398,1514854052479,86
-13399,1514854099230,82
-13400,1514854237767,82
-13401,1514854479239,80
-13402,1514854599839,84
-13403,1514854637980,82
-13404,1514854733404,85
-13405,1514855390643,85
-13406,1514855440249,82
-13407,1514855595067,82
-13408,1514856037714,80
-13409,1514856120585,76
-13410,1514856337482,75
-13411,1514856486670,73
-13412,1514856510504,72
-13413,1514856775018,75
-13414,1514857078782,73
-13415,1514857268311,78
-13416,1514857379740,75
-13417,1514857463960,74
-13418,1514857580519,72
-13419,1514857601196,74
-13420,1514857771683,79
-13421,1514857785874,77
-13422,1514857992701,85
-13423,1514858063349,84
-13424,1514858511975,83
-13425,1514858783841,80
-13426,1514858808165,77
-13427,1514859094280,82
-13428,1514859161057,80
-13429,1514859308200,81
-13430,1514859480494,78
-13431,1514859525008,78
-13432,1514859553952,78
-13433,1514859585118,81
-13434,1514859845420,83
-13435,1514860127805,80
-13436,1514860175243,77
-13437,1514860195863,78
-13438,1514860200183,84
-13439,1514860264222,126
-13440,1514860308180,127
-13441,1514860360180,131
-13442,1514860412572,133
-13443,1514860571839,134
-13444,1514860919878,132
-13445,1514861323831,128
-13446,1514861598324,124
-13447,1514861863892,120
-13448,1514862202035,116
-13449,1514862357391,113
-13450,1514862433359,110
-13451,1514862639187,115
-13452,1514863160243,112
-13453,1514863872112,108
-13454,1514864081559,104
-13455,1514864435848,105
-13456,1514864492884,101
-13457,1514864598527,100
-13458,1514864678455,99
-13459,1514864789676,97
-13460,1514865116990,94
-13461,1514865661408,92
-13462,1514865998865,88
-13463,1514866240911,85
-13464,1514866392568,81
-13465,1514866922944,79
-13466,1514867321683,78
-13467,1514867413412,75
-13468,1514867513009,72
-13469,1514867682021,70
-13470,1514867784469,66
-13471,1514868065150,66
-13472,1514868439955,72
-13473,1514868595499,70
-13474,1514869187678,67
-13475,1514869757861,63
-13476,1514869771797,60
-13477,1514869822916,66
-13478,1514869827248,65
-13479,1514869838392,96
-13480,1514870024911,112
-13481,1514870072032,109
-13482,1514870188119,110
-13483,1514870623634,107
-13484,1514870860171,103
-13485,1514871234747,100
-13486,1514871852119,97
-13487,1514872554288,96
-13488,1514872688111,97
-13489,1514872722331,95
-13490,1514872726741,97
-13491,1514872754908,146
-13492,1514872803285,154
-13493,1514873358337,155
-13494,1514874355867,150
-13495,1514874380211,148
-13496,1514874578031,157
-13497,1514874959215,157
-13498,1514875445782,157
-13499,1514876013661,151
-13500,1514876034405,148
-13501,1514876257187,160
-13502,1514877117700,156
-13503,1514877319535,150
-13504,1514877820811,148
-13505,1514878127627,144
-13506,1514878355376,138
-13507,1514878467723,136
-13508,1514878853961,133
-13509,1514879243041,128
-13510,1514879838552,124
-13511,1514880042451,118
-13512,1514880046808,114
-13513,1514880367202,174
-13514,1514880413732,169
-13515,1514880500833,171
-13516,1514880594958,169
-13517,1514880619226,167
-13518,1514881656292,177
-13519,1514882783100,171
-13520,1514883228930,168
-13521,1514883775737,162
-13522,1514884578259,162
-13523,1514885796154,156
-13524,1514885961887,150
-13525,1514886430295,146
-13526,1514886602823,140
-13527,1514887286661,138
-13528,1514887824552,131
-13529,1514888261799,127
-13530,1514889149583,121
-13531,1514890056120,115
-13532,1514890139605,110
-13533,1514890384342,110
-13534,1514890663359,108
-13535,1514891112970,102
-13536,1514891401085,96
-13537,1514891809747,91
-13538,1514892160958,90
-13539,1514892618791,108
-13540,1514892669036,105
-13541,1514893465113,107
-13542,1514893524859,105
-13543,1514893685364,106
-13544,1514893784604,104
-13545,1514894233051,101
-13546,1514894749132,96
-13547,1514894967037,91
-13548,1514895000785,87
-13549,1514895047939,87
-13550,1514895055601,87
-13551,1514895084094,110
-13552,1514895113017,114
-13553,1514895278446,117
-13554,1514895547554,112
-13555,1514896334202,107
-13556,1514896824465,101
-13557,1514896862428,98
-13558,1514897152654,99
-13559,1514897170153,95
-13560,1514897198310,102
-13561,1514897487466,104
-13562,1514897501561,99
-13563,1514897505931,109
-13564,1514897549174,162
-13565,1514897556802,164
-13566,1514898026219,208
-13567,1514898161047,200
-13568,1514898206322,196
-13569,1514898317979,198
-13570,1514899787573,194
-13571,1514900030127,186
-13572,1514901159131,180
-13573,1514901388756,171
-13574,1514901590973,164
-13575,1514901892696,157
-13576,1514901966370,150
-13577,1514903726746,150
-13578,1514905622175,143
-13579,1514905685418,153
-13580,1514906177337,161
-13581,1514906288728,155
-13582,1514906494904,153
-13583,1514906577399,148
-13584,1514906780793,143
-13585,1514906985213,138
-13586,1514907368382,131
-13587,1514907789485,125
-13588,1514907891568,117
-13589,1514908296494,112
-13590,1514908884331,108
-13591,1514909248522,128
-13592,1514909252995,128
-13593,1514909435684,193
-13594,1514909646557,188
-13595,1514909869666,181
-13596,1514910583074,183
-13597,1514911628809,177
-13598,1514911983754,170
-13599,1514911994470,163
-13600,1514912210410,192
-13601,1514912465923,195
-13602,1514912750168,189
-13603,1514912872206,183
-13604,1514912965397,179
-13605,1514913346767,175
-13606,1514914125074,169
-13607,1514914711292,162
-13608,1514915070955,155
-13609,1514915130085,148
-13610,1514915660993,146
-13611,1514916191860,138
-13612,1514916212710,132
-13613,1514916515136,171
-13614,1514916583685,165
-13615,1514916716534,168
-13616,1514917195981,166
-13617,1514918251304,161
-13618,1514918315058,163
-13619,1514918442898,162
-13620,1514918584302,157
-13621,1514918885676,153
-13622,1514918960962,147
-13623,1514919773961,145
-13624,1514920890096,137
-13625,1514921208208,131
-13626,1514921347547,125
-13627,1514921578195,121
-13628,1514921749386,114
-13629,1514921841588,109
-13630,1514922233959,104
-13631,1514922241876,98
-13632,1514922261297,120
-13633,1514922286738,128
-13634,1514922855266,132
-13635,1514922908781,126
-13636,1514923248978,123
-13637,1514923372484,116
-13638,1514923734851,110
-13639,1514924317021,103
-13640,1514924570823,95
-13641,1514924948320,90
-13642,1514925426025,82
-13643,1514925611710,76
-13644,1514925658699,70
-13645,1514925732013,67
-13646,1514925805181,61
-13647,1514925899954,54
-13648,1514925927190,48
-13649,1514925955059,47
-13650,1514925959352,44
-13651,1514926162764,75
-13652,1514926477682,72
-13653,1514926904044,69
-13654,1514927079667,62
-13655,1514927103747,56
-13656,1514927179618,54
-13657,1514927259404,47
-13658,1514927486424,44
-13659,1514927560749,37
-13660,1514927671027,36
-13661,1514927678393,34
-13662,1514927708634,38
-13663,1514927809412,41
-13664,1514928001036,65
-13665,1514928065283,64
-13666,1514928188788,86
-13667,1514928274446,83
-13668,1514928600101,81
-13669,1514928966909,81
-13670,1514929092850,78
-13671,1514929129735,73
-13672,1514929274795,74
-13673,1514929343968,69
-13674,1514929465300,66
-13675,1514929486720,63
-13676,1514929655292,65
-13677,1514929666106,62
-13678,1514929903451,70
-13679,1514930230381,65
-13680,1514930450793,62
-13681,1514930478289,57
-13682,1514930512105,58
-13683,1514930628429,56
-13684,1514930732597,55
-13685,1514930813282,51
-13686,1514930937450,47
-13687,1514930958003,42
-13688,1514931132835,41
-13689,1514931202053,37
-13690,1514931294375,32
-13691,1514931338406,28
-13692,1514931455073,23
-13693,1514931600772,54
-13694,1514931624663,51
-13695,1514931642761,51
-13696,1514931883388,55
-13697,1514932259254,51
-13698,1514932385497,46
-13699,1514932553828,42
-13700,1514932594104,56
-13701,1514932638415,56
-13702,1514932825475,56
-13703,1514933295371,53
-13704,1514933460461,51
-13705,1514933701538,49
-13706,1514933728954,45
-13707,1514933884978,45
-13708,1514933899456,42
-13709,1514933914313,45
-13710,1514934104672,50
-13711,1514934333520,47
-13712,1514934703996,43
-13713,1514935111511,46
-13714,1514935119060,43
-13715,1514935197401,56
-13716,1514935421933,54
-13717,1514935649180,51
-13718,1514935673421,47
-13719,1514935805020,50
-13720,1514935812896,48
-13721,1514935852084,59
-13722,1514936012115,59
-13723,1514936033006,58
-13724,1514936056805,60
-13725,1514936081165,62
-13726,1514936112720,63
-13727,1514936176358,65
-13728,1514936715551,63
-13729,1514936739308,59
-13730,1514936934924,62
-13731,1514937073417,58
-13732,1514937188573,69
-13733,1514937193734,73
-13734,1514937227517,109
-13735,1514937326344,113
-13736,1514937590602,114
-13737,1514937608366,111
-13738,1514937626383,122
-13739,1514937773861,134
-13740,1514938201121,131
-13741,1514938700096,127
-13742,1514938759533,122
-13743,1514938953128,123
-13744,1514939183400,120
-13745,1514939236250,117
-13746,1514939253489,119
-13747,1514939377334,132
-13748,1514939618703,129
-13749,1514939781564,127
-13750,1514940447581,126
-13751,1514941512176,133
-13752,1514942384068,129
-13753,1514942440839,125
-13754,1514942484176,125
-13755,1514942562269,128
-13756,1514943137057,129
-13757,1514943237674,125
-13758,1514943389757,124
-13759,1514943744723,121
-13760,1514944231907,117
-13761,1514944278774,112
-13762,1514944469445,119
-13763,1514944666098,117
-13764,1514944827344,114
-13765,1514945255514,111
-13766,1514945659868,108
-13767,1514945696808,104
-13768,1514945867892,107
-13769,1514946064266,103
-13770,1514946310677,100
-13771,1514946340904,97
-13772,1514946484573,101
-13773,1514947384309,99
-13774,1514947683648,95
-13775,1514948162898,91
-13776,1514948440590,90
-13777,1514948628922,86
-13778,1514948764453,89
-13779,1514948979428,87
-13780,1514949179839,83
-13781,1514949221060,79
-13782,1514949301299,82
-13783,1514949645283,81
-13784,1514950177451,78
-13785,1514950423003,74
-13786,1514950851919,70
-13787,1514950895810,66
-13788,1514951374155,67
-13789,1514951542765,64
-13790,1514951572695,61
-13791,1514951612669,61
-13792,1514951723626,61
-13793,1514951728038,57
-13794,1514951913821,83
-13795,1514952032877,82
-13796,1514952179404,82
-13797,1514952591652,78
-13798,1514952886561,74
-13799,1514953370370,70
-13800,1514953997532,66
-13801,1514954220290,62
-13802,1514954991619,59
-13803,1514955035712,55
-13804,1514955175758,52
-13805,1514955452882,49
-13806,1514955745110,44
-13807,1514955806115,41
-13808,1514955920559,39
-13809,1514956075137,37
-13810,1514956082552,36
-13811,1514956086868,44
-13812,1514956100955,63
-13813,1514956115758,69
-13814,1514956332428,74
-13815,1514957034476,76
-13816,1514957607771,72
-13817,1514957664949,67
-13818,1514957755050,65
-13819,1514957934173,63
-13820,1514958297622,59
-13821,1514958418150,61
-13822,1514958607079,59
-13823,1514958699827,55
-13824,1514958734156,54
-13825,1514958778876,56
-13826,1514958909807,57
-13827,1514959077654,56
-13828,1514959204978,52
-13829,1514959255174,48
-13830,1514959316841,49
-13831,1514959420823,46
-13832,1514959428370,42
-13833,1514959667119,52
-13834,1514959988109,64
-13835,1514960052208,64
-13836,1514960366812,63
-13837,1514960972595,59
-13838,1514961335888,63
-13839,1514961448337,67
-13840,1514961815732,66
-13841,1514961905858,63
-13842,1514962059790,61
-13843,1514962347979,60
-13844,1514962597482,58
-13845,1514962634404,54
-13846,1514962809073,56
-13847,1514962823184,62
-13848,1514963326591,70
-13849,1514963383021,67
-13850,1514963548177,67
-13851,1514963562249,65
-13852,1514963566410,72
-13853,1514963687038,109
-13854,1514963713920,109
-13855,1514964395164,118
-13856,1514965468678,116
-13857,1514966850214,113
-13858,1514966973974,109
-13859,1514967282537,108
-13860,1514967871695,105
-13861,1514968240907,100
-13862,1514968382523,99
-13863,1514968527227,98
-13864,1514968603514,95
-13865,1514969019019,95
-13866,1514969449613,91
-13867,1514970002447,87
-13868,1514970006749,87
-13869,1514970070819,132
-13870,1514970299938,132
-13871,1514971016228,129
-13872,1514971070246,128
-13873,1514971309826,129
-13874,1514971450436,126
-13875,1514971936124,123
-13876,1514972002878,119
-13877,1514972152741,118
-13878,1514972301848,115
-13879,1514972445261,113
-13880,1514972490181,110
-13881,1514972768184,111
-13882,1514972808452,109
-13883,1514972986530,112
-13884,1514973244382,108
-13885,1514973346181,104
-13886,1514973541137,101
-13887,1514973695027,97
-13888,1514973705803,95
-13889,1514973743682,111
-13890,1514973824639,113
-13891,1514974062214,113
-13892,1514974199697,110
-13893,1514974243518,107
-13894,1514974539170,123
-13895,1514975312828,119
-13896,1514975906128,116
-13897,1514976008236,111
-13898,1514976140708,109
-13899,1514976376559,106
-13900,1514976640664,102
-13901,1514976746895,97
-13902,1514977095941,94
-13903,1514977471053,89
-13904,1514977864132,86
-13905,1514977869124,82
-13906,1514978021930,116
-13907,1514978219022,112
-13908,1514978236439,108
-13909,1514978240547,118
-13910,1514978321634,181
-13911,1514978351569,185
-13912,1514978584919,205
-13913,1514978795896,206
-13914,1514979491577,207
-13915,1514979552402,201
-13916,1514979698699,202
-13917,1514979891663,199
-13918,1514980183597,196
-13919,1514980234548,192
-13920,1514980924856,195
-13921,1514981775468,188
-13922,1514981906256,182
-13923,1514981929817,179
-13924,1514982856858,191
-13925,1514984707543,186
-13926,1514985646412,181
-13927,1514985972482,175
-13928,1514986801733,169
-13929,1514987347032,163
-13930,1514987398621,158
-13931,1514988679272,158
-13932,1514988719541,153
-13933,1514989245301,161
-13934,1514990010956,155
-13935,1514990412830,148
-13936,1514990546978,143
-13937,1514990729123,139
-13938,1514991120911,134
-13939,1514991722880,128
-13940,1514992296430,122
-13941,1514992415957,115
-13942,1514992544361,111
-13943,1514992637189,106
-13944,1514992988337,102
-13945,1514993675521,96
-13946,1514993689765,90
-13947,1514993762512,99
-13948,1514993978933,100
-13949,1514994139197,94
-13950,1514994189003,90
-13951,1514994298182,87
-13952,1514994358713,88
-13953,1514994530044,105
-13954,1514994534206,101
-13955,1514994681728,158
-13956,1514994889267,153
-13957,1514994916915,148
-13958,1514994995252,153
-13959,1514995716427,151
-13960,1514995783440,144
-13961,1514995882114,142
-13962,1514996036242,138
-13963,1514996131963,133
-13964,1514996186379,129
-13965,1514996657174,128
-13966,1514996970480,122
-13967,1514996987452,116
-13968,1514997125184,124
-13969,1514997189769,143
-13970,1514997310151,144
-13971,1514997594794,140
-13972,1514997981253,134
-13973,1514998400079,130
-13974,1514998729503,125
-13975,1514998836426,119
-13976,1514999045724,115
-13977,1514999249518,111
-13978,1514999520230,106
-13979,1515000111875,100
-13980,1515000316259,94
-13981,1515000613134,91
-13982,1515000856456,85
-13983,1515001193959,82
-13984,1515001522533,76
-13985,1515001578932,71
-13986,1515001775547,68
-13987,1515001792996,62
-13988,1515002013851,64
-13989,1515002317462,69
-13990,1515002413198,66
-13991,1515002534765,63
-13992,1515002667516,58
-13993,1515002764936,52
-13994,1515002878628,50
-13995,1515003057695,45
-13996,1515003091582,39
-13997,1515003153064,35
-13998,1515003289688,31
-13999,1515003386354,26
-14000,1515003517704,21
-14001,1515003561358,15
-14002,1515003598670,10
-14003,1515003621520,5
-14004,1515003646601,1
-14005,1515003650954,1
-14006,1515003655366,6
-14007,1515003662802,5
-14008,1515003673565,1
-14009,1515003678257,3
-14010,1515003686915,34
-14011,1515003777836,42
-14012,1515003864748,45
-14013,1515003905119,43
-14014,1515004207473,42
-14015,1515004211886,38
-14016,1515004219534,58
-14017,1515004295119,73
-14018,1515004464545,72
-14019,1515004607756,68
-14020,1515004829818,69
-14021,1515005263272,65
-14022,1515005329860,61
-14023,1515005624867,59
-14024,1515005691149,64
-14025,1515005826685,63
-14026,1515005934214,59
-14027,1515005945566,55
-14028,1515005960107,64
-14029,1515005987913,69
-14030,1515006151319,71
-14031,1515006451541,70
-14032,1515006884660,66
-14033,1515007226936,65
-14034,1515007511333,62
-14035,1515007889225,58
-14036,1515008308582,54
-14037,1515008503243,50
-14038,1515008546405,47
-14039,1515008554041,45
-14040,1515008834219,55
-14041,1515008930597,50
-14042,1515009073155,48
-14043,1515009080725,45
-14044,1515009146607,55
-14045,1515009279549,52
-14046,1515009303934,48
-14047,1515009378566,56
-14048,1515009389247,54
-14049,1515009634249,62
-14050,1515009883418,58
-14051,1515010000313,55
-14052,1515010193571,52
-14053,1515010412908,50
-14054,1515010570000,46
-14055,1515010734691,71
-14056,1515010788829,69
-14057,1515010953457,68
-14058,1515010971077,73
-14059,1515010992381,81
-14060,1515011152160,87
-14061,1515011338925,86
-14062,1515011356400,85
-14063,1515011607730,93
-14064,1515011889130,91
-14065,1515012154242,91
-14066,1515012683523,88
-14067,1515012832545,85
-14068,1515012974429,91
-14069,1515013069095,89
-14070,1515013206910,90
-14071,1515013619638,89
-14072,1515013731829,87
-14073,1515014012494,85
-14074,1515014143028,82
-14075,1515014353737,80
-14076,1515014361217,79
-14077,1515014483216,101
-14078,1515014497329,99
-14079,1515014783597,113
-14080,1515015083887,109
-14081,1515015158562,106
-14082,1515015182091,105
-14083,1515015222057,111
-14084,1515015475642,114
-14085,1515015759946,110
-14086,1515015764420,108
-14087,1515015994779,162
-14088,1515016292445,163
-14089,1515016461600,158
-14090,1515016700144,156
-14091,1515016823594,153
-14092,1515016901286,151
-14093,1515017254973,150
-14094,1515017497026,147
-14095,1515018109828,143
-14096,1515018452502,138
-14097,1515018803908,135
-14098,1515019090496,131
-14099,1515019810949,126
-14100,1515020570605,121
-14101,1515020620410,117
-14102,1515020758825,118
-14103,1515020983517,114
-14104,1515021159651,109
-14105,1515021370330,106
-14106,1515021828645,102
-14107,1515022546198,98
-14108,1515023080787,93
-14109,1515023473358,89
-14110,1515023661105,84
-14111,1515023834561,85
-14112,1515024068958,81
-14113,1515024276226,76
-14114,1515024732054,73
-14115,1515025066783,68
-14116,1515025080910,74
-14117,1515025277478,91
-14118,1515025539818,87
-14119,1515025816423,84
-14120,1515025830981,81
-14121,1515025860317,89
-14122,1515026009529,91
-14123,1515026427956,88
-14124,1515026561126,83
-14125,1515026614517,81
-14126,1515026852412,80
-14127,1515026877228,77
-14128,1515026918739,84
-14129,1515027036265,89
-14130,1515027474477,89
-14131,1515027838000,85
-14132,1515028023763,80
-14133,1515028255680,77
-14134,1515028528924,72
-14135,1515028602414,68
-14136,1515028659036,65
-14137,1515028786528,62
-14138,1515028946408,60
-14139,1515029281074,56
-14140,1515029649839,59
-14141,1515029730051,54
-14142,1515029848593,51
-14143,1515029859138,48
-14144,1515030178080,62
-14145,1515030300501,58
-14146,1515030451505,55
-14147,1515030587411,53
-14148,1515030878154,49
-14149,1515030882831,52
-14150,1515030951357,74
-14151,1515031124808,71
-14152,1515031218038,68
-14153,1515031377521,65
-14154,1515031621834,61
-14155,1515031936983,56
-14156,1515032003728,52
-14157,1515032075921,51
-14158,1515032200002,48
-14159,1515032307123,49
-14160,1515032344008,50
-14161,1515032502891,49
-14162,1515032631132,45
-14163,1515032662199,47
-14164,1515032713697,46
-14165,1515032874622,44
-14166,1515033058123,41
-14167,1515033118886,37
-14168,1515033249901,33
-14169,1515033449722,30
-14170,1515033584070,27
-14171,1515033611030,24
-14172,1515033657913,21
-14173,1515033718791,18
-14174,1515033749442,15
-14175,1515033797120,12
-14176,1515033804612,9
-14177,1515033822503,20
-14178,1515033839930,19
-14179,1515033871161,26
-14180,1515033912895,24
-14181,1515033980045,22
-14182,1515034016700,21
-14183,1515034090738,23
-14184,1515034138451,23
-14185,1515034155662,21
-14186,1515034211556,20
-14187,1515034245366,47
-14188,1515034311965,48
-14189,1515034396283,48
-14190,1515034501929,46
-14191,1515034559525,45
-14192,1515034644949,45
-14193,1515034727638,47
-14194,1515034741630,45
-14195,1515034808107,50
-14196,1515034918568,49
-14197,1515035061475,48
-14198,1515035121422,46
-14199,1515035132152,45
-14200,1515035248031,52
-14201,1515035430451,50
-14202,1515035460479,51
-14203,1515035591865,52
-14204,1515035753721,51
-14205,1515035916767,49
-14206,1515036123319,47
-14207,1515036167164,44
-14208,1515036245214,44
-14209,1515036395816,41
-14210,1515036572630,40
-14211,1515036707896,38
-14212,1515036853036,35
-14213,1515036885438,33
-14214,1515036919404,32
-14215,1515036982644,32
-14216,1515037087754,30
-14217,1515037178942,34
-14218,1515037253360,32
-14219,1515037273935,30
-14220,1515037299128,30
-14221,1515037313892,37
-14222,1515037332830,44
-14223,1515037574584,48
-14224,1515037582461,45
-14225,1515037586729,56
-14226,1515037732433,86
-14227,1515037927432,84
-14228,1515038285371,85
-14229,1515038611315,85
-14230,1515038959682,83
-14231,1515038993720,80
-14232,1515039145126,83
-14233,1515039202097,81
-14234,1515039565336,81
-14235,1515039949551,78
-14236,1515040082655,76
-14237,1515040252120,76
-14238,1515040579916,74
-14239,1515040604180,71
-14240,1515040705507,74
-14241,1515040995084,72
-14242,1515041777685,70
-14243,1515042183130,67
-14244,1515042207310,69
-14245,1515042500883,73
-14246,1515042605927,71
-14247,1515042712538,69
-14248,1515042998813,67
-14249,1515043302104,64
-14250,1515043352004,76
-14251,1515043392949,77
-14252,1515043481503,79
-14253,1515043669622,78
-14254,1515043752368,77
-14255,1515043929575,75
-14256,1515044059581,73
-14257,1515044146250,73
-14258,1515044193062,72
-14259,1515044383304,72
-14260,1515044682313,71
-14261,1515044966261,70
-14262,1515045146926,67
-14263,1515045326217,66
-14264,1515045564114,65
-14265,1515045656390,64
-14266,1515045845772,62
-14267,1515046022893,60
-14268,1515046107731,58
-14269,1515046261952,56
-14270,1515046352107,54
-14271,1515046680239,52
-14272,1515047061538,51
-14273,1515047142973,49
-14274,1515047164577,47
-14275,1515047223017,49
-14276,1515047243811,48
-14277,1515047278941,52
-14278,1515047331708,53
-14279,1515047372445,54
-14280,1515047409901,55
-14281,1515047482319,55
-14282,1515047651756,54
-14283,1515047719993,52
-14284,1515047731401,51
-14285,1515047767357,59
-14286,1515048201219,60
-14287,1515048205684,57
-14288,1515048449780,86
-14289,1515048681369,84
-14290,1515049075663,81
-14291,1515049336066,78
-14292,1515049417270,76
-14293,1515049461503,74
-14294,1515049601078,75
-14295,1515049686701,77
-14296,1515050013600,75
-14297,1515050452342,73
-14298,1515050463041,69
-14299,1515050506406,82
-14300,1515050681786,87
-14301,1515051607973,84
-14302,1515052462588,81
-14303,1515052572042,79
-14304,1515052732083,78
-14305,1515053180402,76
-14306,1515053207411,72
-14307,1515053242583,74
-14308,1515053397464,77
-14309,1515053738665,74
-14310,1515053993898,71
-14311,1515054104081,68
-14312,1515054213256,65
-14313,1515054352344,62
-14314,1515054450976,61
-14315,1515054609741,59
-14316,1515054614102,56
-14317,1515054668536,84
-14318,1515054765399,83
-14319,1515054769890,82
-14320,1515054963938,122
-14321,1515055309477,119
-14322,1515056442284,118
-14323,1515056881622,116
-14324,1515057400705,112
-14325,1515058101556,114
-14326,1515058350298,126
-14327,1515058406841,124
-14328,1515059077277,125
-14329,1515059236184,121
-14330,1515059292867,118
-14331,1515059600315,119
-14332,1515060031593,119
-14333,1515060082382,116
-14334,1515060165991,118
-14335,1515060222920,118
-14336,1515060274662,118
-14337,1515060376597,119
-14338,1515060432068,118
-14339,1515060847851,118
-14340,1515060921365,119
-14341,1515061262594,118
-14342,1515061520066,115
-14343,1515061691670,111
-14344,1515061895978,108
-14345,1515062073300,108
-14346,1515062397772,106
-14347,1515062515791,102
-14348,1515062529915,100
-14349,1515062663170,113
-14350,1515062850480,110
-14351,1515062969169,109
-14352,1515063013053,107
-14353,1515063118251,110
-14354,1515063358666,108
-14355,1515063745496,105
-14356,1515064156993,101
-14357,1515064488038,98
-14358,1515064605110,94
-14359,1515064753084,93
-14360,1515064809424,91
-14361,1515064940255,90
-14362,1515065095511,86
-14363,1515065208204,83
-14364,1515065323718,80
-14365,1515065652921,77
-14366,1515065894654,74
-14367,1515065980444,71
-14368,1515066099383,68
-14369,1515066166844,65
-14370,1515066476647,62
-14371,1515066758052,58
-14372,1515066924101,55
-14373,1515067033884,50
-14374,1515067143347,47
-14375,1515067361705,46
-14376,1515067543590,42
-14377,1515067580061,41
-14378,1515067646517,41
-14379,1515067736913,38
-14380,1515067793570,36
-14381,1515067906981,34
-14382,1515068125671,32
-14383,1515068183044,27
-14384,1515068273165,25
-14385,1515068314816,26
-14386,1515068336555,26
-14387,1515068381976,23
-14388,1515068402634,36
-14389,1515068457889,37
-14390,1515068525163,35
-14391,1515068586472,32
-14392,1515068657985,29
-14393,1515068693359,27
-14394,1515068751473,26
-14395,1515068851448,24
-14396,1515068943976,21
-14397,1515068948476,19
-14398,1515069000524,25
-14399,1515069004839,29
-14400,1515069035101,43
-14401,1515069068389,43
-14402,1515069111742,42
-14403,1515069159640,40
-14404,1515069353233,39
-14405,1515069576404,36
-14406,1515069596939,32
-14407,1515069607769,35
-14408,1515069672843,41
-14409,1515069700863,39
-14410,1515069952045,37
-14411,1515070246656,34
-14412,1515070419590,31
-14413,1515070540174,27
-14414,1515070607841,24
-14415,1515070722612,21
-14416,1515070739974,17
-14417,1515070855258,32
-14418,1515071003713,30
-14419,1515071037425,28
-14420,1515071051035,49
-14421,1515071192169,55
-14422,1515071484287,53
-14423,1515071520680,50
-14424,1515071834821,50
-14425,1515071876791,48
-14426,1515072004703,47
-14427,1515072153208,45
-14428,1515072258865,46
-14429,1515072286521,43
-14430,1515072470747,44
-14431,1515072487798,44
-14432,1515072529387,48
-14433,1515072572048,48
-14434,1515072745776,50
-14435,1515072977174,49
-14436,1515073048908,49
-14437,1515073143470,50
-14438,1515073247543,49
-14439,1515073391173,49
-14440,1515073438742,48
-14441,1515073627319,49
-14442,1515073713017,47
-14443,1515073876905,46
-14444,1515073934013,44
-14445,1515074022098,44
-14446,1515074087053,43
-14447,1515074170666,41
-14448,1515074413537,40
-14449,1515074536537,46
-14450,1515074733813,45
-14451,1515074840353,44
-14452,1515074974210,44
-14453,1515075001241,44
-14454,1515075091465,47
-14455,1515075217296,46
-14456,1515075305250,45
-14457,1515075376942,44
-14458,1515075394579,42
-14459,1515075615532,46
-14460,1515075763936,45
-14461,1515075924169,44
-14462,1515076054263,44
-14463,1515076278200,42
-14464,1515076351940,41
-14465,1515076460705,40
-14466,1515076494670,39
-14467,1515076561601,40
-14468,1515076629293,39
-14469,1515076975927,39
-14470,1515077000373,37
-14471,1515077140757,38
-14472,1515077260238,36
-14473,1515077335482,34
-14474,1515077453863,33
-14475,1515077458190,32
-14476,1515077483156,48
-14477,1515077677728,49
-14478,1515077864482,49
-14479,1515077979348,47
-14480,1515078033607,45
-14481,1515078441753,45
-14482,1515078869323,43
-14483,1515079187903,40
-14484,1515079448232,37
-14485,1515079482218,36
-14486,1515079602118,36
-14487,1515079784077,35
-14488,1515079788358,33
-14489,1515080033092,51
-14490,1515080370012,48
-14491,1515080483925,46
-14492,1515080500962,45
-14493,1515080519916,49
-14494,1515080602073,52
-14495,1515080781008,52
-14496,1515080802170,49
-14497,1515080875473,52
-14498,1515080912597,55
-14499,1515081013184,56
-14500,1515081145224,62
-14501,1515081396128,62
-14502,1515081837190,61
-14503,1515081874665,60
-14504,1515081936597,61
-14505,1515082191429,61
-14506,1515082454439,59
-14507,1515082574114,59
-14508,1515082831624,60
-14509,1515082888863,59
-14510,1515082967133,60
-14511,1515083071050,60
-14512,1515083207597,58
-14513,1515083324414,56
-14514,1515083447911,55
-14515,1515083507455,53
-14516,1515083633968,53
-14517,1515083667846,52
-14518,1515083756903,53
-14519,1515083860707,52
-14520,1515083949409,52
-14521,1515084089991,54
-14522,1515084149293,53
-14523,1515084228075,53
-14524,1515084331539,53
-14525,1515084491627,52
-14526,1515084631295,51
-14527,1515084643390,49
-14528,1515084732938,56
-14529,1515084838915,56
-14530,1515084993138,56
-14531,1515085171063,54
-14532,1515085238739,55
-14533,1515085294596,56
-14534,1515085361760,56
-14535,1515085516209,56
-14536,1515085563095,54
-14537,1515085719015,55
-14538,1515085876172,53
-14539,1515086127699,52
-14540,1515086244888,50
-14541,1515086298237,50
-14542,1515086426752,49
-14543,1515086444391,48
-14544,1515086657277,52
-14545,1515086885539,50
-14546,1515087071342,49
-14547,1515087140821,47
-14548,1515087223133,47
-14549,1515087445479,45
-14550,1515087677303,43
-14551,1515087754364,41
-14552,1515087878324,40
-14553,1515088018961,38
-14554,1515088037367,38
-14555,1515088089560,40
-14556,1515088262409,39
-14557,1515088289376,38
-14558,1515088345025,39
-14559,1515088399896,40
-14560,1515088453320,40
-14561,1515088616570,39
-14562,1515088781758,37
-14563,1515088835136,35
-14564,1515088941667,34
-14565,1515089130631,32
-14566,1515089184847,30
-14567,1515089189124,31
-14568,1515089319733,45
-14569,1515089448387,44
-14570,1515089619737,41
-14571,1515089636659,41
-14572,1515089719653,44
-14573,1515089854104,43
-14574,1515090098634,40
-14575,1515090206933,38
-14576,1515090361772,44
-14577,1515090652927,45
-14578,1515090967922,43
-14579,1515091004608,41
-14580,1515091065027,40
-14581,1515091095235,40
-14582,1515091133327,41
-14583,1515091161009,40
-14584,1515091564861,41
-14585,1515092130340,39
-14586,1515092361865,37
-14587,1515092472127,34
-14588,1515092551639,32
-14589,1515092581848,40
-14590,1515092753718,41
-14591,1515092824808,39
-14592,1515093139393,37
-14593,1515093185808,39
-14594,1515093299129,42
-14595,1515093464842,40
-14596,1515093478654,39
-14597,1515093486369,46
-14598,1515093543162,59
-14599,1515093648419,60
-14600,1515093659377,59
-14601,1515093723007,70
-14602,1515093882053,70
-14603,1515094117623,68
-14604,1515094328996,67
-14605,1515094409956,67
-14606,1515094553747,66
-14607,1515094792681,64
-14608,1515094947934,63
-14609,1515095153648,61
-14610,1515095157914,60
-14611,1515095185541,92
-14612,1515095284720,97
-14613,1515095288981,97
-14614,1515095551438,148
-14615,1515096240621,146
-14616,1515096861800,143
-14617,1515097000961,139
-14618,1515097405106,139
-14619,1515098263608,136
-14620,1515098930593,133
-14621,1515099162601,130
-14622,1515099397274,127
-14623,1515099796816,125
-14624,1515100293388,123
-14625,1515101349441,120
-14626,1515102372227,116
-14627,1515102959870,113
-14628,1515103039413,114
-14629,1515103470255,114
-14630,1515103615010,111
-14631,1515104133524,109
-14632,1515104260076,106
-14633,1515104413652,106
-14634,1515104506925,104
-14635,1515104702646,104
-14636,1515104806232,101
-14637,1515104959785,101
-14638,1515105081709,98
-14639,1515105266875,97
-14640,1515105277844,94
-14641,1515105335673,111
-14642,1515105398709,112
-14643,1515105461016,113
-14644,1515105511698,116
-14645,1515106354964,117
-14646,1515107214407,113
-14647,1515107496836,109
-14648,1515107730768,106
-14649,1515107917559,103
-14650,1515108260798,100
-14651,1515108395643,97
-14652,1515108477836,95
-14653,1515108606413,93
-14654,1515108641174,91
-14655,1515109190876,95
-14656,1515109278715,92
-14657,1515109493562,89
-14658,1515109905756,88
-14659,1515110452116,84
-14660,1515110780760,82
-14661,1515111003050,78
-14662,1515111248998,75
-14663,1515111291041,71
-14664,1515111388294,71
-14665,1515111432292,69
-14666,1515111606650,68
-14667,1515112040588,65
-14668,1515112327537,70
-14669,1515112419449,66
-14670,1515112575911,65
-14671,1515112772017,61
-14672,1515112825794,61
-14673,1515112882977,59
-14674,1515112908194,58
-14675,1515112943254,59
-14676,1515112962020,60
-14677,1515113514739,63
-14678,1515113878715,59
-14679,1515113902546,54
-14680,1515114063807,57
-14681,1515114352584,53
-14682,1515114403247,51
-14683,1515114624959,50
-14684,1515114845349,48
-14685,1515114912297,44
-14686,1515114972213,41
-14687,1515115318923,39
-14688,1515115681435,34
-14689,1515115730756,30
-14690,1515115754423,29
-14691,1515115802193,28
-14692,1515115843028,25
-14693,1515115891129,22
-14694,1515115935955,19
-14695,1515115991481,17
-14696,1515115995829,13
-14697,1515116063051,19
-14698,1515116125661,23
-14699,1515116143354,20
-14700,1515116287676,19
-14701,1515116301750,22
-14702,1515116319212,23
-14703,1515116350594,22
-14704,1515116361492,20
-14705,1515116393069,20
-14706,1515116442205,19
-14707,1515116480669,16
-14708,1515116501349,13
-14709,1515116523797,11
-14710,1515116565525,8
-14711,1515116616983,21
-14712,1515116631038,22
-14713,1515116641854,24
-14714,1515116702387,54
-14715,1515116779994,53
-14716,1515116870283,51
-14717,1515116874508,50
-14718,1515116911816,77
-14719,1515116998811,79
-14720,1515117525028,78
-14721,1515117535981,75
-14722,1515117645104,88
-14723,1515118067016,87
-14724,1515118194692,84
-14725,1515118769935,82
-14726,1515119229755,79
-14727,1515119619342,76
-14728,1515120156926,73
-14729,1515120431028,71
-14730,1515120597928,68
-14731,1515120787336,67
-14732,1515121118660,64
-14733,1515121466393,62
-14734,1515121529055,59
-14735,1515121563178,59
-14736,1515121779560,60
-14737,1515121974666,58
-14738,1515121999501,56
-14739,1515122090770,59
-14740,1515122534267,57
-14741,1515122935482,64
-14742,1515123002906,64
-14743,1515123131396,65
-14744,1515123449534,65
-14745,1515123585885,65
-14746,1515123885701,63
-14747,1515124062200,60
-14748,1515124106841,58
-14749,1515124183084,58
-14750,1515124245096,58
-14751,1515124296800,58
-14752,1515124345793,58
-14753,1515124368360,59
-14754,1515124555906,62
-14755,1515124856503,63
-14756,1515125013236,60
-14757,1515125061384,59
-14758,1515125120843,60
-14759,1515125207063,59
-14760,1515125352772,57
-14761,1515125565520,54
-14762,1515125784103,53
-14763,1515125940817,51
-14764,1515126123772,50
-14765,1515126263358,49
-14766,1515126500005,48
-14767,1515126778673,45
-14768,1515126980863,43
-14769,1515127081338,40
-14770,1515127146875,39
-14771,1515127181560,38
-14772,1515127243600,37
-14773,1515127309435,37
-14774,1515127365212,36
-14775,1515127571670,37
-14776,1515127813202,36
-14777,1515127901538,38
-14778,1515127933856,36
-14779,1515128110510,36
-14780,1515128276380,36
-14781,1515128336621,34
-14782,1515128405681,33
-14783,1515128515345,32
-14784,1515128627624,30
-14785,1515128706854,29
-14786,1515128831313,27
-14787,1515128954446,25
-14788,1515129016737,23
-14789,1515129121981,21
-14790,1515129220970,19
-14791,1515129292358,18
-14792,1515129376788,16
-14793,1515129411534,15
-14794,1515129469178,14
-14795,1515129564789,12
-14796,1515129622946,10
-14797,1515129654499,11
-14798,1515129669804,10
-14799,1515129691266,9
-14800,1515129812409,8
-14801,1515129982316,6
-14802,1515130044642,6
-14803,1515130063326,4
-14804,1515130092161,3
-14805,1515130113991,3
-14806,1515130122875,2
-14807,1515130138933,1
-14808,1515130148165,1
-14809,1515130163883,1
-14810,1515130176008,1
-14811,1515130184447,1
-14812,1515130193062,1
-14813,1515130205047,1
-14814,1515130213376,1
-14815,1515130222365,1
-14816,1515130231516,1
-14817,1515130241058,1
-14818,1515130249785,1
-14819,1515130259101,2
-14820,1515130271246,1
-14821,1515130283699,1
-14822,1515130295701,7
-14823,1515130311176,8
-14824,1515130330203,7
-14825,1515130351643,8
-14826,1515130394251,7
-14827,1515130426704,7
-14828,1515130458211,5
-14829,1515130490763,5
-14830,1515130502810,4
-14831,1515130526197,4
-14832,1515130548386,3
-14833,1515130567507,2
-14834,1515130580465,2
-14835,1515130599434,2
-14836,1515130621354,2
-14837,1515130650929,1
-14838,1515130670647,1
-14839,1515130678762,2
-14840,1515130691480,3
-14841,1515130703424,1
-14842,1515130712126,1
-14843,1515130724316,1
-14844,1515130732937,1
-14845,1515130741928,1
-14846,1515130750570,1
-14847,1515130763207,1
-14848,1515130772070,1
-14849,1515130781168,1
-14850,1515130790095,1
-14851,1515130798666,1
-14852,1515130807576,1
-14853,1515130819772,1
-14854,1515130831971,2
-14855,1515130844284,2
-14856,1515130856267,2
-14857,1515130871460,2
-14858,1515130883519,2
-14859,1515130898840,3
-14860,1515130911289,4
-14861,1515130930243,4
-14862,1515130945758,4
-14863,1515130965264,4
-14864,1515130980340,4
-14865,1515130996247,4
-14866,1515131008036,5
-14867,1515131023654,5
-14868,1515131059295,5
-14869,1515131091566,5
-14870,1515131106876,5
-14871,1515131120097,5
-14872,1515131134937,7
-14873,1515131144147,8
-14874,1515131169755,10
-14875,1515131199877,11
-14876,1515131219309,11
-14877,1515131235345,12
-14878,1515131252115,12
-14879,1515131268043,16
-14880,1515131389692,17
-14881,1515131544827,17
-14882,1515131758401,18
-14883,1515131934236,17
-14884,1515131942808,17
-14885,1515132011024,21
-14886,1515132124016,22
-14887,1515132265104,21
-14888,1515132450977,21
-14889,1515132816843,21
-14890,1515133069408,21
-14891,1515133092338,20
-14892,1515133117797,21
-14893,1515133146469,23
-14894,1515133165373,25
-14895,1515133180708,27
-14896,1515133268204,31
-14897,1515133364131,31
-14898,1515133459664,31
-14899,1515133544130,32
-14900,1515133633979,32
-14901,1515133759787,32
-14902,1515133811633,32
-14903,1515133830235,32
-14904,1515133929193,36
-14905,1515134069051,35
-14906,1515134125059,35
-14907,1515134184425,36
-14908,1515134239965,36
-14909,1515134342160,37
-14910,1515134411111,36
-14911,1515134488638,37
-14912,1515134593809,37
-14913,1515134733843,37
-14914,1515134863428,36
-14915,1515134917128,36
-14916,1515134959004,36
-14917,1515134984711,37
-14918,1515135116311,39
-14919,1515135256760,39
-14920,1515135328897,38
-14921,1515135390842,39
-14922,1515135506687,39
-14923,1515135688298,39
-14924,1515135832911,38
-14925,1515135938046,38
-14926,1515135976863,38
-14927,1515136002128,40
-14928,1515136060635,42
-14929,1515136124622,43
-14930,1515136156467,43
-14931,1515136350577,46
-14932,1515136452080,45
-14933,1515136600823,44
-14934,1515136756130,44
-14935,1515136934836,43
-14936,1515137406500,42
-14937,1515137792229,42
-14938,1515137824558,40
-14939,1515137853300,42
-14940,1515137914578,44
-14941,1515137998981,44
-14942,1515138070947,44
-14943,1515138214576,43
-14944,1515138359989,43
-14945,1515138484247,42
-14946,1515138563614,42
-14947,1515138614073,41
-14948,1515138870519,41
-14949,1515138980012,40
-14950,1515139014382,40
-14951,1515139088318,40
-14952,1515139171391,41
-14953,1515139188885,40
-14954,1515139250481,43
-14955,1515139395183,43
-14956,1515139594677,42
-14957,1515139671494,42
-14958,1515139798752,41
-14959,1515139844369,40
-14960,1515139848777,41
-14961,1515140009936,61
-14962,1515140200299,60
-14963,1515140221214,59
-14964,1515140270009,64
-14965,1515140323532,65
-14966,1515140409362,65
-14967,1515140466778,65
-14968,1515140605302,66
-14969,1515141151804,65
-14970,1515141618782,63
-14971,1515141670853,60
-14972,1515141735897,62
-14973,1515141875227,62
-14974,1515142074117,61
-14975,1515142447124,60
-14976,1515142517906,59
-14977,1515142551742,59
-14978,1515142623057,62
-14979,1515142705976,62
-14980,1515142877574,62
-14981,1515142905398,60
-14982,1515142922883,64
-14983,1515143188735,70
-14984,1515143446171,68
-14985,1515143583697,68
-14986,1515143780083,66
-14987,1515143857565,65
-14988,1515143930029,64
-14989,1515144040341,64
-14990,1515144283011,62
-14991,1515144561609,60
-14992,1515144592997,59
-14993,1515144684738,62
-14994,1515144818601,62
-14995,1515144863845,62
-14996,1515145078631,64
-14997,1515145426056,62
-14998,1515145437187,60
-14999,1515145481600,71
-15000,1515145628331,73
-15001,1515145658922,71
-15002,1515145733147,74
-15003,1515145819015,74
-15004,1515145846818,75
-15005,1515145904994,79
-15006,1515145955644,80
-15007,1515146009911,81
-15008,1515146206898,82
-15009,1515146469313,81
-15010,1515146795862,78
-15011,1515147072087,76
-15012,1515147490408,74
-15013,1515147604262,72
-15014,1515147960131,71
-15015,1515148509930,68
-15016,1515148567865,66
-15017,1515148690091,67
-15018,1515148737516,67
-15019,1515148768322,67
-15020,1515148895567,69
-15021,1515149028389,68
-15022,1515149376633,67
-15023,1515149547110,64
-15024,1515149762836,62
-15025,1515149965734,60
-15026,1515150381792,57
-15027,1515150396021,56
-15028,1515150414438,64
-15029,1515150466443,70
-15030,1515150500315,70
-15031,1515150558918,74
-15032,1515150587283,73
-15033,1515150887684,76
-15034,1515151002067,74
-15035,1515151059660,72
-15036,1515151174624,72
-15037,1515151182481,69
-15038,1515151201308,87
-15039,1515151351372,97
-15040,1515151534475,96
-15041,1515151698236,93
-15042,1515151925441,91
-15043,1515152211936,88
-15044,1515152242473,86
-15045,1515152572768,89
-15046,1515152927986,86
-15047,1515152942915,82
-15048,1515153084649,93
-15049,1515153196896,91
-15050,1515153291331,88
-15051,1515153610069,88
-15052,1515153782299,85
-15053,1515153916439,82
-15054,1515153920673,82
-15055,1515153925090,125
-15056,1515153950373,189
-15057,1515154311535,200
-15058,1515155336162,197
-15059,1515156052459,191
-15060,1515156278041,186
-15061,1515156322953,193
-15062,1515156645502,199
-15063,1515156978282,194
-15064,1515157149971,194
-15065,1515157222705,191
-15066,1515158123982,193
-15067,1515158323685,189
-15068,1515158383021,187
-15069,1515158878771,189
-15070,1515159082838,183
-15071,1515160101662,179
-15072,1515161004728,175
-15073,1515162038994,171
-15074,1515162208999,166
-15075,1515162848558,163
-15076,1515163643009,157
-15077,1515164042990,153
-15078,1515165240013,150
-15079,1515166489692,145
-15080,1515166785325,141
-15081,1515166806394,135
-15082,1515166943441,148
-15083,1515167290734,148
-15084,1515168206591,144
-15085,1515169213019,139
-15086,1515169295770,133
-15087,1515169419294,132
-15088,1515169444040,129
-15089,1515169551891,137
-15090,1515169741932,134
-15091,1515169990846,130
-15092,1515170094991,125
-15093,1515171249895,125
-15094,1515171555559,119
-15095,1515172023233,114
-15096,1515172196463,111
-15097,1515172297488,107
-15098,1515172442479,103
-15099,1515172594410,105
-15100,1515174410226,103
-15101,1515176381630,97
-15102,1515176402551,94
-15103,1515176614079,101
-15104,1515176621877,97
-15105,1515176828712,124
-15106,1515177113581,120
-15107,1515177164300,117
-15108,1515177226361,118
-15109,1515177347613,116
-15110,1515177480059,113
-15111,1515177894593,109
-15112,1515178349978,103
-15113,1515178373984,98
-15114,1515178385164,102
-15115,1515178483723,118
-15116,1515178922606,114
-15117,1515179058739,108
-15118,1515179305853,104
-15119,1515179694861,100
-15120,1515180504982,96
-15121,1515181018743,91
-15122,1515181170225,85
-15123,1515181188173,79
-15124,1515181310709,83
-15125,1515181496918,78
-15126,1515181529186,73
-15127,1515181597388,72
-15128,1515181683627,72
-15129,1515181715194,71
-15130,1515181719489,71
-15131,1515181852717,106
-15132,1515182026129,103
-15133,1515182094991,101
-15134,1515182340379,97
-15135,1515182463531,91
-15136,1515182481345,87
-15137,1515182579532,93
-15138,1515183107449,98
-15139,1515184006297,97
-15140,1515184673757,90
-15141,1515185143045,85
-15142,1515185795941,79
-15143,1515186120917,73
-15144,1515186369263,66
-15145,1515187056812,64
-15146,1515187656180,57
-15147,1515187670551,51
-15148,1515187674709,60
-15149,1515187736168,88
-15150,1515187897593,85
-15151,1515187935565,80
-15152,1515187986189,78
-15153,1515188281755,75
-15154,1515188609654,69
-15155,1515189117774,86
-15156,1515189809719,115
-15157,1515190590041,119
-15158,1515190597645,114
-15159,1515190972498,145
-15160,1515191390094,140
-15161,1515191541252,136
-15162,1515191773660,137
-15163,1515191840506,134
-15164,1515191901861,134
-15165,1515192496226,135
-15166,1515192530595,132
-15167,1515192614583,136
-15168,1515193340272,135
-15169,1515193700206,134
-15170,1515194102293,129
-15171,1515194343171,126
-15172,1515194569073,121
-15173,1515194836931,116
-15174,1515195086201,112
-15175,1515195421068,109
-15176,1515195447437,103
-15177,1515196242375,107
-15178,1515196495652,102
-15179,1515196877045,97
-15180,1515197061401,92
-15181,1515197128844,88
-15182,1515197299221,93
-15183,1515197523897,90
-15184,1515197548497,85
-15185,1515197726092,88
-15186,1515197747318,83
-15187,1515197778785,88
-15188,1515197891514,91
-15189,1515198274226,93
-15190,1515198588019,89
-15191,1515198701752,85
-15192,1515198723033,82
-15193,1515198827207,86
-15194,1515199322973,82
-15195,1515199447302,77
-15196,1515199580851,73
-15197,1515199687926,69
-15198,1515199775254,66
-15199,1515200237305,63
-15200,1515200352259,58
-15201,1515200360076,53
-15202,1515200578316,64
-15203,1515200615418,64
-15204,1515200742345,62
-15205,1515200856882,73
-15206,1515201039478,70
-15207,1515201508938,65
-15208,1515202067235,62
-15209,1515202310816,59
-15210,1515202604018,56
-15211,1515202774598,52
-15212,1515202829006,47
-15213,1515202853649,44
-15214,1515202950031,48
-15215,1515202954321,55
-15216,1515202985319,83
-15217,1515202996714,84
-15218,1515203295282,97
-15219,1515203340249,91
-15220,1515203385772,91
-15221,1515203431123,90
-15222,1515203452122,90
-15223,1515203500103,94
-15224,1515203609113,98
-15225,1515203765804,95
-15226,1515203838844,91
-15227,1515203967102,91
-15228,1515204015772,87
-15229,1515204216820,87
-15230,1515204308626,84
-15231,1515204649171,101
-15232,1515204929308,97
-15233,1515204979212,93
-15234,1515205888758,94
-15235,1515205955041,89
-15236,1515206147011,88
-15237,1515206154848,89
-15238,1515206349109,112
-15239,1515206616361,108
-15240,1515206939264,104
-15241,1515207849150,99
-15242,1515208041237,94
-15243,1515208406204,89
-15244,1515208941660,85
-15245,1515208989707,80
-15246,1515209155900,77
-15247,1515209216246,74
-15248,1515209238061,75
-15249,1515209273276,95
-15250,1515209308403,98
-15251,1515209509443,100
-15252,1515209595081,99
-15253,1515209657549,98
-15254,1515209777817,97
-15255,1515209815768,93
-15256,1515210041221,94
-15257,1515210072564,90
-15258,1515210109914,91
-15259,1515210124286,110
-15260,1515210434013,124
-15261,1515210445009,120
-15262,1515210548450,142
-15263,1515210623021,139
-15264,1515210701226,141
-15265,1515211117194,141
-15266,1515211717727,138
-15267,1515212121330,136
-15268,1515212257709,134
-15269,1515212580555,131
-15270,1515212598262,127
-15271,1515212883398,139
-15272,1515212946375,135
-15273,1515213384000,134
-15274,1515214011741,129
-15275,1515214155537,124
-15276,1515214362261,121
-15277,1515214658934,122
-15278,1515214670193,117
-15279,1515214809892,136
-15280,1515214844530,132
-15281,1515215029178,136
-15282,1515215144326,134
-15283,1515215239347,130
-15284,1515215912513,128
-15285,1515216697009,126
-15286,1515217332320,121
-15287,1515217502555,119
-15288,1515217554587,119
-15289,1515217680840,119
-15290,1515217946358,116
-15291,1515218306236,111
-15292,1515218330377,106
-15293,1515218460492,116
-15294,1515218888177,112
-15295,1515218940281,107
-15296,1515219008873,106
-15297,1515219098402,104
-15298,1515219325303,102
-15299,1515219386532,97
-15300,1515219452174,96
-15301,1515219730815,93
-15302,1515220093216,96
-15303,1515220241835,90
-15304,1515220418223,89
-15305,1515220564086,84
-15306,1515220878475,80
-15307,1515220932381,75
-15308,1515221084922,73
-15309,1515221340872,67
-15310,1515221361582,63
-15311,1515221468961,64
-15312,1515221480163,59
-15313,1515221484957,67
-15314,1515221500256,96
-15315,1515221624092,105
-15316,1515221982233,116
-15317,1515222321410,113
-15318,1515223398917,116
-15319,1515223469659,111
-15320,1515223591524,111
-15321,1515223629279,109
-15322,1515223849677,112
-15323,1515224085077,113
-15324,1515224106162,110
-15325,1515224188798,118
-15326,1515224492053,116
-15327,1515224533713,112
-15328,1515224809986,113
-15329,1515224850992,109
-15330,1515225065117,111
-15331,1515225451549,107
-15332,1515226007635,102
-15333,1515226171930,96
-15334,1515226295483,94
-15335,1515226464771,89
-15336,1515226558536,85
-15337,1515226576334,82
-15338,1515226891144,101
-15339,1515226976965,97
-15340,1515227366459,94
-15341,1515227890241,88
-15342,1515227921712,83
-15343,1515228078207,84
-15344,1515228129461,79
-15345,1515228180113,77
-15346,1515228211897,77
-15347,1515228610727,76
-15348,1515228615373,72
-15349,1515228670766,107
-15350,1515229173638,109
-15351,1515229424742,107
-15352,1515229663498,101
-15353,1515230480731,98
-15354,1515230501434,93
-15355,1515230518707,99
-15356,1515231285911,109
-15357,1515231580642,103
-15358,1515231610938,101
-15359,1515231655109,105
-15360,1515231763284,113
-15361,1515232132606,110
-15362,1515232293492,118
-15363,1515232300977,115
-15364,1515232429725,148
-15365,1515232537471,147
-15366,1515232641640,144
-15367,1515233136412,141
-15368,1515233300273,136
-15369,1515233442615,132
-15370,1515233499918,128
-15371,1515233799417,136
-15372,1515233817166,132
-15373,1515234070556,146
-15374,1515234519459,140
-15375,1515235027448,135
-15376,1515235216917,130
-15377,1515235379683,126
-15378,1515236271582,122
-15379,1515237098603,128
-15380,1515237424188,124
-15381,1515237484420,122
-15382,1515237539188,123
-15383,1515237547782,123
-15384,1515237635430,153
-15385,1515238388017,151
-15386,1515238751358,145
-15387,1515239128153,139
-15388,1515239481632,134
-15389,1515239520103,131
-15390,1515239654994,133
-15391,1515240395427,131
-15392,1515241330344,124
-15393,1515241337844,123
-15394,1515241528273,157
-15395,1515241632812,152
-15396,1515242341559,151
-15397,1515243292901,147
-15398,1515243992319,141
-15399,1515244699805,135
-15400,1515245371632,130
-15401,1515246037868,125
-15402,1515246393770,119
-15403,1515246421235,114
-15404,1515246479591,117
-15405,1515246537470,116
-15406,1515246728657,114
-15407,1515246858251,108
-15408,1515246934832,105
-15409,1515246953201,102
-15410,1515247419955,108
-15411,1515247979739,105
-15412,1515248000987,99
-15413,1515248360369,110
-15414,1515248932384,120
-15415,1515249023957,121
-15416,1515249234352,119
-15417,1515249739813,114
-15418,1515250310990,109
-15419,1515250816877,103
-15420,1515251387320,99
-15421,1515251473536,94
-15422,1515251497845,93
-15423,1515251552131,97
-15424,1515251582593,96
-15425,1515251908012,102
-15426,1515252008305,99
-15427,1515252066054,95
-15428,1515252073740,96
-15429,1515252242124,119
-15430,1515252694883,118
-15431,1515253200313,112
-15432,1515253408418,106
-15433,1515253516638,101
-15434,1515253619011,97
-15435,1515253785717,94
-15436,1515253905571,89
-15437,1515253909959,85
-15438,1515253964429,130
-15439,1515253991619,128
-15440,1515254275787,134
-15441,1515254283426,128
-15442,1515254318048,160
-15443,1515254938484,167
-15444,1515255434754,159
-15445,1515255562170,154
-15446,1515256072163,151
-15447,1515256495635,146
-15448,1515257037945,139
-15449,1515257242373,151
-15450,1515257358040,148
-15451,1515257796527,143
-15452,1515258941791,136
-15453,1515259232011,129
-15454,1515259296665,124
-15455,1515259464806,126
-15456,1515259686858,128
-15457,1515260058169,122
-15458,1515260529474,115
-15459,1515260557742,113
-15460,1515261056776,118
-15461,1515261488354,113
-15462,1515261636731,107
-15463,1515262375939,102
-15464,1515263267770,114
-15465,1515263380674,109
-15466,1515263698639,107
-15467,1515263766549,102
-15468,1515263837123,100
-15469,1515263967296,98
-15470,1515264332369,94
-15471,1515264336749,90
-15472,1515264348113,134
-15473,1515264507412,164
-15474,1515264707243,160
-15475,1515266019432,154
-15476,1515268137579,148
-15477,1515268452965,141
-15478,1515268539861,136
-15479,1515268752889,132
-15480,1515268808192,127
-15481,1515268903093,124
-15482,1515268960515,123
-15483,1515269564325,123
-15484,1515269796345,133
-15485,1515269834578,130
-15486,1515269920058,132
-15487,1515269947526,128
-15488,1515270204813,133
-15489,1515270345291,127
-15490,1515270623917,126
-15491,1515270788291,122
-15492,1515270827274,116
-15493,1515270999393,117
-15494,1515271125312,131
-15495,1515271354424,127
-15496,1515271358725,124
-15497,1515271766528,187
-15498,1515271880506,180
-15499,1515271952050,176
-15500,1515272905937,175
-15501,1515273283756,168
-15502,1515273748535,161
-15503,1515274194642,154
-15504,1515275486884,152
-15505,1515275631320,147
-15506,1515276010187,144
-15507,1515276175843,138
-15508,1515276376799,134
-15509,1515276980403,129
-15510,1515277184646,129
-15511,1515277633099,123
-15512,1515278226696,117
-15513,1515278438899,115
-15514,1515278678558,110
-15515,1515279205897,103
-15516,1515279411875,98
-15517,1515279933967,93
-15518,1515280145662,86
-15519,1515280173363,80
-15520,1515280200753,80
-15521,1515280404347,79
-15522,1515280443349,74
-15523,1515280475498,77
-15524,1515280526724,77
-15525,1515280773129,77
-15526,1515280807245,71
-15527,1515280878127,70
-15528,1515280977891,66
-15529,1515281090161,76
-15530,1515281180843,72
-15531,1515281218707,67
-15532,1515281400701,64
-15533,1515281582951,59
-15534,1515281812700,54
-15535,1515281846879,49
-15536,1515281948051,46
-15537,1515281976782,41
-15538,1515282232841,61
-15539,1515282453356,58
-15540,1515282515140,58
-15541,1515282602656,55
-15542,1515282627537,71
-15543,1515282668881,79
-15544,1515282792186,78
-15545,1515282976124,74
-15546,1515283227791,71
-15547,1515283280618,66
-15548,1515283379680,64
-15549,1515283542255,61
-15550,1515283701979,57
-15551,1515283896348,53
-15552,1515283935459,49
-15553,1515284053270,47
-15554,1515284090514,43
-15555,1515284129730,42
-15556,1515284337966,41
-15557,1515284404785,36
-15558,1515284462760,32
-15559,1515284480635,28
-15560,1515284545374,31
-15561,1515284719968,28
-15562,1515284734195,22
-15563,1515284763021,22
-15564,1515284784233,18
-15565,1515284798641,15
-15566,1515284817484,13
-15567,1515284832098,10
-15568,1515284840065,7
-15569,1515284865085,6
-15570,1515284872444,2
-15571,1515284880141,1
-15572,1515284888229,18
-15573,1515284903404,33
-15574,1515284941571,34
-15575,1515284970406,33
-15576,1515285032575,32
-15577,1515285063218,29
-15578,1515285258046,27
-15579,1515285272270,25
-15580,1515285290184,26
-15581,1515285314568,27
-15582,1515285415924,27
-15583,1515285443564,26
-15584,1515285493885,24
-15585,1515285522000,21
-15586,1515285526355,23
-15587,1515285578628,33
-15588,1515285641906,36
-15589,1515285704668,34
-15590,1515285799284,32
-15591,1515285850675,28
-15592,1515285892805,26
-15593,1515285901015,27
-15594,1515285943668,32
-15595,1515286021906,31
-15596,1515286097717,28
-15597,1515286134640,60
-15598,1515286263606,62
-15599,1515286396888,62
-15600,1515286686943,62
-15601,1515286900858,59
-15602,1515286962073,58
-15603,1515287029491,58
-15604,1515287128894,57
-15605,1515287163538,55
-15606,1515287171307,57
-15607,1515287307535,72
-15608,1515287799897,71
-15609,1515287814023,68
-15610,1515287882668,77
-15611,1515287974325,77
-15612,1515288421177,75
-15613,1515288569633,72
-15614,1515288601249,71
-15615,1515288619105,73
-15616,1515288819987,78
-15617,1515288850940,77
-15618,1515288951321,78
-15619,1515289138355,77
-15620,1515289163479,78
-15621,1515289215000,84
-15622,1515289363106,86
-15623,1515289480756,85
-15624,1515289524828,85
-15625,1515289627832,89
-15626,1515289755950,88
-15627,1515290345885,87
-15628,1515290727204,86
-15629,1515290745430,83
-15630,1515290878931,90
-15631,1515291176014,90
-15632,1515291361503,88
-15633,1515291396719,86
-15634,1515291527331,88
-15635,1515291586658,86
-15636,1515291751049,88
-15637,1515291762365,85
-15638,1515291939432,101
-15639,1515292283511,99
-15640,1515292294438,96
-15641,1515292437462,114
-15642,1515292597833,112
-15643,1515292605645,113
-15644,1515292738582,145
-15645,1515293512820,144
-15646,1515293636662,140
-15647,1515294686966,139
-15648,1515294853049,135
-15649,1515295170715,134
-15650,1515295245953,130
-15651,1515295496656,130
-15652,1515296622047,126
-15653,1515296776907,123
-15654,1515296798466,121
-15655,1515296891801,130
-15656,1515297173644,130
-15657,1515297600535,127
-15658,1515297760705,122
-15659,1515297834880,121
-15660,1515298047666,121
-15661,1515298096279,118
-15662,1515298107341,118
-15663,1515298235287,141
-15664,1515298313500,139
-15665,1515298465158,138
-15666,1515298836654,136
-15667,1515299062433,133
-15668,1515299126567,130
-15669,1515299204591,130
-15670,1515299300878,129
-15671,1515299440539,127
-15672,1515299906878,123
-15673,1515300162385,122
-15674,1515300592143,119
-15675,1515300973200,115
-15676,1515301235843,112
-15677,1515301807563,108
-15678,1515301851588,105
-15679,1515302045692,105
-15680,1515302164458,103
-15681,1515302747857,101
-15682,1515302752157,98
-15683,1515303686549,147
-15684,1515303713919,142
-15685,1515304091238,149
-15686,1515305074808,144
-15687,1515305160962,145
-15688,1515305377681,144
-15689,1515305714398,140
-15690,1515306150876,135
-15691,1515306849201,130
-15692,1515307089386,125
-15693,1515307259641,120
-15694,1515307435392,120
-15695,1515307880198,116
-15696,1515308156504,111
-15697,1515308404229,107
-15698,1515309267778,104
-15699,1515309354206,99
-15700,1515309710497,96
-15701,1515309726582,90
-15702,1515309920939,98
-15703,1515310852458,94
-15704,1515310959126,89
-15705,1515311191913,86
-15706,1515311298481,83
-15707,1515311510920,88
-15708,1515311932985,83
-15709,1515312175041,78
-15710,1515312186172,78
-15711,1515312277506,91
-15712,1515312285030,88
-15713,1515312523445,111
-15714,1515312920177,105
-15715,1515313395066,103
-15716,1515313531029,102
-15717,1515313650020,98
-15718,1515313882935,96
-15719,1515314037946,92
-15720,1515314182619,88
-15721,1515314236479,87
-15722,1515314462716,87
-15723,1515314498178,83
-15724,1515314603850,83
-15725,1515314694281,81
-15726,1515315029800,78
-15727,1515315433606,74
-15728,1515315605036,68
-15729,1515315701059,63
-15730,1515315732929,64
-15731,1515315759106,64
-15732,1515315849812,64
-15733,1515316088070,60
-15734,1515316363844,57
-15735,1515316434226,53
-15736,1515316469499,51
-15737,1515316504695,49
-15738,1515316593020,55
-15739,1515316696959,52
-15740,1515317008534,48
-15741,1515317356499,53
-15742,1515317454994,49
-15743,1515317552286,46
-15744,1515317606645,59
-15745,1515318051131,59
-15746,1515318098856,54
-15747,1515318146369,53
-15748,1515318207519,51
-15749,1515318296460,49
-15750,1515318468184,46
-15751,1515318623733,44
-15752,1515318657729,40
-15753,1515318665509,38
-15754,1515318682825,45
-15755,1515319120234,53
-15756,1515319300974,51
-15757,1515319485870,47
-15758,1515319554386,44
-15759,1515319592271,41
-15760,1515319613801,40
-15761,1515319631167,41
-15762,1515319741761,44
-15763,1515319802711,53
-15764,1515319833754,53
-15765,1515320142160,54
-15766,1515320168513,51
-15767,1515320310799,52
-15768,1515320351570,49
-15769,1515320375521,49
-15770,1515320403794,52
-15771,1515320421541,54
-15772,1515320582521,57
-15773,1515320616586,54
-15774,1515320716409,53
-15775,1515320746771,50
-15776,1515320968849,49
-15777,1515321058709,46
-15778,1515321283678,43
-15779,1515321346435,41
-15780,1515321354136,39
-15781,1515321537716,47
-15782,1515321699165,43
-15783,1515321878543,67
-15784,1515321912534,64
-15785,1515321933793,71
-15786,1515321977950,76
-15787,1515322048377,76
-15788,1515322105083,76
-15789,1515322334409,76
-15790,1515322660086,74
-15791,1515322819106,71
-15792,1515323052436,67
-15793,1515323228670,65
-15794,1515323445335,63
-15795,1515323540103,60
-15796,1515323581934,58
-15797,1515323680346,58
-15798,1515323759146,56
-15799,1515323848333,53
-15800,1515324053222,52
-15801,1515324212553,49
-15802,1515324216772,53
-15803,1515324248203,79
-15804,1515324759347,81
-15805,1515325089734,78
-15806,1515325107187,75
-15807,1515325151540,81
-15808,1515325163083,82
-15809,1515325207464,94
-15810,1515325597846,95
-15811,1515325602245,100
-15812,1515325626552,150
-15813,1515325707233,174
-15814,1515325811658,175
-15815,1515326053692,174
-15816,1515326601332,171
-15817,1515327635973,167
-15818,1515327656959,162
-15819,1515327714519,177
-15820,1515327866959,179
-15821,1515328027147,176
-15822,1515328391302,175
-15823,1515328923914,172
-15824,1515329710649,170
-15825,1515329933062,166
-15826,1515330248744,163
-15827,1515330427233,158
-15828,1515330574788,155
-15829,1515331270121,152
-15830,1515331274563,148
-15831,1515331338427,224
-15832,1515331451533,229
-15833,1515331739953,229
-15834,1515331871243,224
-15835,1515332025178,221
-15836,1515332904669,219
-15837,1515332988925,214
-15838,1515333145710,215
-15839,1515333518976,212
-15840,1515333834050,206
-15841,1515334501689,202
-15842,1515335339711,195
-15843,1515335546424,189
-15844,1515336058283,185
-15845,1515337585070,180
-15846,1515337596307,174
-15847,1515337947521,205
-15848,1515338327095,201
-15849,1515338788829,196
-15850,1515340466539,189
-15851,1515340659066,183
-15852,1515341188324,178
-15853,1515341697952,173
-15854,1515341842317,172
-15855,1515342177222,171
-15856,1515342184829,165
-15857,1515342236557,210
-15858,1515343028694,212
-15859,1515343555071,205
-15860,1515343972885,200
-15861,1515344484195,195
-15862,1515345941671,190
-15863,1515345973370,183
-15864,1515346159339,190
-15865,1515347278914,186
-15866,1515348451876,179
-15867,1515348904686,173
-15868,1515349086109,167
-15869,1515349243759,162
-15870,1515349261189,159
-15871,1515349382151,175
-15872,1515349651813,174
-15873,1515349923189,167
-15874,1515350932130,162
-15875,1515350969211,155
-15876,1515351368424,160
-15877,1515351400486,153
-15878,1515351463134,156
-15879,1515351480872,154
-15880,1515352101302,167
-15881,1515352798942,165
-15882,1515353264704,158
-15883,1515353737175,149
-15884,1515354032294,142
-15885,1515354937233,137
-15886,1515355874524,133
-15887,1515356324632,126
-15888,1515356355574,120
-15889,1515356386896,122
-15890,1515356625363,124
-15891,1515356837810,117
-15892,1515357188355,110
-15893,1515357326827,103
-15894,1515357485117,96
-15895,1515357748631,88
-15896,1515357777134,82
-15897,1515358017484,82
-15898,1515358201156,75
-15899,1515358238882,67
-15900,1515358473817,64
-15901,1515358660418,56
-15902,1515358711270,48
-15903,1515358797805,58
-15904,1515358911668,54
-15905,1515359035131,47
-15906,1515359103702,40
-15907,1515359191246,38
-15908,1515359225670,33
-15909,1515359305814,37
-15910,1515359341682,32
-15911,1515359385517,27
-15912,1515359449457,49
-15913,1515359538969,51
-15914,1515359598476,48
-15915,1515359800130,45
-15916,1515359807791,40
-15917,1515359923251,46
-15918,1515360041456,40
-15919,1515360353484,44
-15920,1515360403292,41
-15921,1515360450137,38
-15922,1515360454629,35
-15923,1515360543278,47
-15924,1515360569222,42
-15925,1515360634252,39
-15926,1515360731567,35
-15927,1515360838463,29
-15928,1515360966650,24
-15929,1515361015529,20
-15930,1515361036646,14
-15931,1515361041283,50
-15932,1515361102412,74
-15933,1515361190466,74
-15934,1515361542374,72
-15935,1515361680222,68
-15936,1515361715263,66
-15937,1515361769680,64
-15938,1515361801382,64
-15939,1515361917868,65
-15940,1515362231839,61
-15941,1515362243181,56
-15942,1515362292916,63
-15943,1515362434323,61
-15944,1515362495262,57
-15945,1515362530242,54
-15946,1515362698932,52
-15947,1515363076603,66
-15948,1515363094236,60
-15949,1515363098676,64
-15950,1515363260162,94
-15951,1515363343366,90
-15952,1515363363888,87
-15953,1515363529546,92
-15954,1515363574274,87
-15955,1515363648963,87
-15956,1515363673947,84
-15957,1515363815206,112
-15958,1515363902205,114
-15959,1515363962899,112
-15960,1515363980079,111
-15961,1515364122568,122
-15962,1515364177230,118
-15963,1515364212056,117
-15964,1515364617225,127
-15965,1515365432937,123
-15966,1515365633715,117
-15967,1515365801851,113
-15968,1515366284869,110
-15969,1515366650030,105
-15970,1515366756382,102
-15971,1515366797900,110
-15972,1515367024275,113
-15973,1515367224484,109
-15974,1515367506773,106
-15975,1515367826403,101
-15976,1515368162811,102
-15977,1515368536032,97
-15978,1515369064729,99
-15979,1515369256772,97
-15980,1515369477569,103
-15981,1515369611981,99
-15982,1515369673278,97
-15983,1515370176283,96
-15984,1515370293990,92
-15985,1515370459551,90
-15986,1515370666611,86
-15987,1515370819867,83
-15988,1515371124499,79
-15989,1515371162969,80
-15990,1515371268383,85
-15991,1515371431848,83
-15992,1515371591091,79
-15993,1515371705111,76
-15994,1515371994440,74
-15995,1515372223570,71
-15996,1515372396178,67
-15997,1515372662230,67
-15998,1515372696646,63
-15999,1515372760958,64
-16000,1515372782596,64
-16001,1515372803899,66
-16002,1515372932897,69
-16003,1515373072625,67
-16004,1515373153639,64
-16005,1515373292595,61
-16006,1515373522623,58
-16007,1515373944720,54
-16008,1515373993379,51
-16009,1515374031923,50
-16010,1515374207395,48
-16011,1515374518479,45
-16012,1515374738025,41
-16013,1515374742494,38
-16014,1515374756972,54
-16015,1515374774570,59
-16016,1515374785442,63
-16017,1515374853603,77
-16018,1515375344030,75
-16019,1515375381645,70
-16020,1515375393031,70
-16021,1515375432424,80
-16022,1515375601314,80
-16023,1515375662596,85
-16024,1515375946584,84
-16025,1515376014202,81
-16026,1515376075671,80
-16027,1515376405820,78
-16028,1515376437158,73
-16029,1515376582580,74
-16030,1515376826924,70
-16031,1515376955162,65
-16032,1515377029420,75
-16033,1515377037058,73
-16034,1515377121531,92
-16035,1515377132606,89
-16036,1515377380422,104
-16037,1515377809594,102
-16038,1515377898565,98
-16039,1515378154799,98
-16040,1515378239871,94
-16041,1515378373364,90
-16042,1515378663124,93
-16043,1515378723255,89
-16044,1515378961526,88
-16045,1515379369701,85
-16046,1515379594245,81
-16047,1515379769599,78
-16048,1515379790693,73
-16049,1515379964641,80
-16050,1515380019625,94
-16051,1515380037288,94
-16052,1515380172344,103
-16053,1515380396769,105
-16054,1515380711752,102
-16055,1515381117964,100
-16056,1515381160028,96
-16057,1515381507319,102
-16058,1515381602520,98
-16059,1515381702058,97
-16060,1515381922484,98
-16061,1515382189390,101
-16062,1515382245144,98
-16063,1515382955061,102
-16064,1515383146162,101
-16065,1515383415608,98
-16066,1515383563376,95
-16067,1515383613632,92
-16068,1515383852116,93
-16069,1515383913066,90
-16070,1515384309011,90
-16071,1515384978916,87
-16072,1515385113658,86
-16073,1515385141137,83
-16074,1515385344407,87
-16075,1515385360369,83
-16076,1515385667642,92
-16077,1515385723190,88
-16078,1515385839507,88
-16079,1515385847215,85
-16080,1515385935909,107
-16081,1515386842669,106
-16082,1515387030885,101
-16083,1515387088381,100
-16084,1515387298299,99
-16085,1515387458414,96
-16086,1515387559043,93
-16087,1515387587182,90
-16088,1515387637313,94
-16089,1515387644797,92
-16090,1515388150895,119
-16091,1515388169060,115
-16092,1515388529541,126
-16093,1515388609262,121
-16094,1515388732177,120
-16095,1515388759739,116
-16096,1515388804909,120
-16097,1515388925702,122
-16098,1515388976423,118
-16099,1515389179148,120
-16100,1515389797731,117
-16101,1515389955721,114
-16102,1515389959971,113
-16103,1515390050390,172
-16104,1515390071208,170
-16105,1515390286027,184
-16106,1515390676205,178
-16107,1515391162720,173
-16108,1515391357910,167
-16109,1515391683497,162
-16110,1515392170040,158
-16111,1515392341866,152
-16112,1515392423445,147
-16113,1515392664611,144
-16114,1515392672352,149
-16115,1515392716664,192
-16116,1515392934808,199
-16117,1515393000826,201
-16118,1515393362345,202
-16119,1515393652372,196
-16120,1515393787608,192
-16121,1515394535886,196
-16122,1515394813429,192
-16123,1515395117290,186
-16124,1515396185551,182
-16125,1515396250358,176
-16126,1515396686168,176
-16127,1515397587734,171
-16128,1515397645208,165
-16129,1515397744957,167
-16130,1515397822525,164
-16131,1515397946269,163
-16132,1515398367959,159
-16133,1515398448957,153
-16134,1515398519577,162
-16135,1515398533557,162
-16136,1515398554769,193
-16137,1515399101795,207
-16138,1515399216216,202
-16139,1515399287081,199
-16140,1515399506435,199
-16141,1515399941917,195
-16142,1515400615805,189
-16143,1515400869734,181
-16144,1515401329814,178
-16145,1515401577705,172
-16146,1515401728285,166
-16147,1515401831943,161
-16148,1515401886311,157
-16149,1515402377739,161
-16150,1515402443979,154
-16151,1515402692279,154
-16152,1515403077520,154
-16153,1515403214833,149
-16154,1515403573690,144
-16155,1515404220897,138
-16156,1515404311228,131
-16157,1515404871030,130
-16158,1515405111854,123
-16159,1515405278999,118
-16160,1515405307008,113
-16161,1515405362989,115
-16162,1515405398845,113
-16163,1515405437724,115
-16164,1515405679541,115
-16165,1515406093153,109
-16166,1515406322996,101
-16167,1515406467780,95
-16168,1515406678377,91
-16169,1515406811812,85
-16170,1515407042131,80
-16171,1515407113149,73
-16172,1515407386171,69
-16173,1515407423841,62
-16174,1515407468326,62
-16175,1515407630955,58
-16176,1515407854059,57
-16177,1515407871810,51
-16178,1515407969886,51
-16179,1515408043128,46
-16180,1515408149653,53
-16181,1515408569818,49
-16182,1515408676742,42
-16183,1515408727767,36
-16184,1515408771184,33
-16185,1515408808541,27
-16186,1515408819280,23
-16187,1515408884032,22
-16188,1515408931379,20
-16189,1515408952785,15
-16190,1515408963548,25
-16191,1515408974989,24
-16192,1515408982862,30
-16193,1515409051069,33
-16194,1515409108423,29
-16195,1515409166526,25
-16196,1515409197832,25
-16197,1515409311489,23
-16198,1515409350434,18
-16199,1515409406534,16
-16200,1515409457454,11
-16201,1515409488331,5
-16202,1515409499565,1
-16203,1515409507356,27
-16204,1515409598411,31
-16205,1515409785556,36
-16206,1515409810419,33
-16207,1515409814788,32
-16208,1515409823258,44
-16209,1515409884773,52
-16210,1515409985746,50
-16211,1515410054151,46
-16212,1515410089431,42
-16213,1515410103713,42
-16214,1515410210446,44
-16215,1515410299340,63
-16216,1515410327752,65
-16217,1515410476459,66
-16218,1515410555023,67
-16219,1515410626031,65
-16220,1515410726312,63
-16221,1515410734194,61
-16222,1515411000320,75
-16223,1515411416254,71
-16224,1515411450738,68
-16225,1515411688971,68
-16226,1515411993053,66
-16227,1515412307834,62
-16228,1515412346775,58
-16229,1515412384597,60
-16230,1515412640778,60
-16231,1515412731452,59
-16232,1515412735766,57
-16233,1515412817535,84
-16234,1515413140941,83
-16235,1515413175186,82
-16236,1515413371443,96
-16237,1515413500035,104
-16238,1515413735534,102
-16239,1515413817398,100
-16240,1515413848654,102
-16241,1515413978031,107
-16242,1515414376350,105
-16243,1515415036258,100
-16244,1515415289936,97
-16245,1515415321065,94
-16246,1515415546722,98
-16247,1515416033272,95
-16248,1515416130997,93
-16249,1515416408307,94
-16250,1515416854502,91
-16251,1515417218429,89
-16252,1515417637516,86
-16253,1515417917209,83
-16254,1515418130505,81
-16255,1515418234112,77
-16256,1515418309086,75
-16257,1515418363767,75
-16258,1515418431163,74
-16259,1515418439447,72
-16260,1515418858661,90
-16261,1515418932764,91
-16262,1515419027849,92
-16263,1515419062205,93
-16264,1515419135192,99
-16265,1515419307510,98
-16266,1515419374037,95
-16267,1515420012139,95
-16268,1515420049893,91
-16269,1515420309634,92
-16270,1515420324453,89
-16271,1515420684354,100
-16272,1515421066195,97
-16273,1515421322426,93
-16274,1515421448338,91
-16275,1515421459188,90
-16276,1515421493463,106
-16277,1515421888257,108
-16278,1515422057360,107
-16279,1515422118700,104
-16280,1515422254900,104
-16281,1515422940750,101
-16282,1515423110798,96
-16283,1515423162062,93
-16284,1515423251704,93
-16285,1515423522679,92
-16286,1515423550573,88
-16287,1515423596565,94
-16288,1515423753200,93
-16289,1515423960538,90
-16290,1515424489559,87
-16291,1515424534214,85
-16292,1515424622193,87
-16293,1515424646281,89
-16294,1515425052158,93
-16295,1515425210134,89
-16296,1515425733298,85
-16297,1515425941062,82
-16298,1515425948880,78
-16299,1515425980542,98
-16300,1515426042567,99
-16301,1515426129565,98
-16302,1515426360877,95
-16303,1515426409024,91
-16304,1515426450701,94
-16305,1515426697434,94
-16306,1515426773887,89
-16307,1515426812082,88
-16308,1515427124119,97
-16309,1515427148719,98
-16310,1515427186238,104
-16311,1515427231280,106
-16312,1515427323126,106
-16313,1515427331797,105
-16314,1515427719182,132
-16315,1515428191723,128
-16316,1515428202894,124
-16317,1515428508059,146
-16318,1515428515731,142
-16319,1515428758417,181
-16320,1515429434955,177
-16321,1515430970488,172
-16322,1515431018213,175
-16323,1515431294091,177
-16324,1515432388273,173
-16325,1515432668902,168
-16326,1515432846639,163
-16327,1515433158961,160
-16328,1515433193453,154
-16329,1515433208732,159
-16330,1515433283238,180
-16331,1515433682805,179
-16332,1515433743782,173
-16333,1515433845915,189
-16334,1515434055703,188
-16335,1515434387370,184
-16336,1515434680275,181
-16337,1515434889999,177
-16338,1515435002108,173
-16339,1515435752076,170
-16340,1515436059463,166
-16341,1515436111429,163
-16342,1515436427806,166
-16343,1515436889482,161
-16344,1515436893889,154
-16345,1515437560570,232
-16346,1515437662542,229
-16347,1515439682163,227
-16348,1515440381082,219
-16349,1515440771294,213
-16350,1515441222130,207
-16351,1515442823267,200
-16352,1515443260192,193
-16353,1515443349007,185
-16354,1515443733224,182
-16355,1515444299610,176
-16356,1515444641225,169
-16357,1515444941920,164
-16358,1515445528549,159
-16359,1515446061452,153
-16360,1515446278199,156
-16361,1515446530084,151
-16362,1515446723570,145
-16363,1515447104668,141
-16364,1515447543911,137
-16365,1515447971211,132
-16366,1515448175927,126
-16367,1515448898311,122
-16368,1515449578045,115
-16369,1515449595587,111
-16370,1515449810272,118
-16371,1515450217530,119
-16372,1515450427749,114
-16373,1515450492354,107
-16374,1515450844783,104
-16375,1515451271887,98
-16376,1515451536948,101
-16377,1515452344996,99
-16378,1515452352830,93
-16379,1515452891273,115
-16380,1515452899262,110
-16381,1515453000647,136
-16382,1515453481937,132
-16383,1515454143441,125
-16384,1515454301628,120
-16385,1515454608055,115
-16386,1515454642605,108
-16387,1515454859569,112
-16388,1515455131036,107
-16389,1515455176168,101
-16390,1515455200596,100
-16391,1515455252290,102
-16392,1515455480109,101
-16393,1515455571981,95
-16394,1515455698599,93
-16395,1515455739636,88
-16396,1515455929606,86
-16397,1515455947468,79
-16398,1515456170477,82
-16399,1515456249894,87
-16400,1515456350816,85
-16401,1515456359166,81
-16402,1515456377161,99
-16403,1515456718838,104
-16404,1515456859282,99
-16405,1515457054924,96
-16406,1515457066715,89
-16407,1515457164311,100
-16408,1515457209067,97
-16409,1515457290249,95
-16410,1515457294840,94
-16411,1515457342013,138
-16412,1515457369517,139
-16413,1515457650153,143
-16414,1515457933680,150
-16415,1515458296319,143
-16416,1515458468253,136
-16417,1515459377345,143
-16418,1515460664550,136
-16419,1515461300524,151
-16420,1515461407825,145
-16421,1515461436890,141
-16422,1515461773706,145
-16423,1515461807813,142
-16424,1515461905894,145
-16425,1515462057058,142
-16426,1515462271261,136
-16427,1515462905914,131
-16428,1515462913570,125
-16429,1515463013859,162
-16430,1515463164743,170
-16431,1515463322525,168
-16432,1515463713430,163
-16433,1515464510955,159
-16434,1515464697863,154
-16435,1515465224264,149
-16436,1515465488751,143
-16437,1515465888651,138
-16438,1515465892993,132
-16439,1515466296364,198
-16440,1515466587246,191
-16441,1515466845399,185
-16442,1515467699902,181
-16443,1515467896515,173
-16444,1515469190252,168
-16445,1515469364919,203
-16446,1515469422034,198
-16447,1515469641461,202
-16448,1515470097687,196
-16449,1515470418436,190
-16450,1515470445941,184
-16451,1515470780211,193
-16452,1515471475866,187
-16453,1515471673891,181
-16454,1515471880856,177
-16455,1515472127488,172
-16456,1515472375878,167
-16457,1515472383759,161
-16458,1515472432218,203
-16459,1515472877344,204
-16460,1515473323439,197
-16461,1515474315850,191
-16462,1515474731062,183
-16463,1515476956536,176
-16464,1515477523137,168
-16465,1515478130315,161
-16466,1515478286245,153
-16467,1515478425979,148
-16468,1515478588804,142
-16469,1515478898888,135
-16470,1515479180592,135
-16471,1515479211899,129
-16472,1515479317210,130
-16473,1515479496764,126
-16474,1515479852691,120
-16475,1515479917495,113
-16476,1515480059268,109
-16477,1515480157414,103
-16478,1515480204766,97
-16479,1515480308691,107
-16480,1515480777206,102
-16481,1515481363351,110
-16482,1515481442124,105
-16483,1515481508147,101
-16484,1515481562086,96
-16485,1515481613931,93
-16486,1515481765109,90
-16487,1515482100355,88
-16488,1515482595766,81
-16489,1515482854514,74
-16490,1515483157768,70
-16491,1515483255606,67
-16492,1515483910990,64
-16493,1515483955711,56
-16494,1515484032919,53
-16495,1515484043926,48
-16496,1515484078231,53
-16497,1515484208764,50
-16498,1515484297295,49
-16499,1515484469055,43
-16500,1515484523582,37
-16501,1515484551413,32
-16502,1515484555838,39
-16503,1515484600788,60
-16504,1515484605158,56
-16505,1515484640326,80
-16506,1515484802440,78
-16507,1515484961316,81
-16508,1515485174535,75
-16509,1515485514204,72
-16510,1515485679674,65
-16511,1515485831496,84
-16512,1515486087906,82
-16513,1515486247873,83
-16514,1515486392564,78
-16515,1515486503874,73
-16516,1515486968632,69
-16517,1515486986142,64
-16518,1515487079422,66
-16519,1515487251597,61
-16520,1515487282544,55
-16521,1515487508522,55
-16522,1515487652540,54
-16523,1515487660469,49
-16524,1515487704892,62
-16525,1515488141239,61
-16526,1515488865251,56
-16527,1515488963562,50
-16528,1515489031907,45
-16529,1515489145678,60
-16530,1515489433883,57
-16531,1515489487582,53
-16532,1515489894583,51
-16533,1515490335591,46
-16534,1515490357468,40
-16535,1515490417160,39
-16536,1515490624954,36
-16537,1515490667456,30
-16538,1515490723092,27
-16539,1515490744189,59
-16540,1515490926765,62
-16541,1515490991347,58
-16542,1515491207973,56
-16543,1515492067399,52
-16544,1515492895350,49
-16545,1515492989805,44
-16546,1515493274891,41
-16547,1515493669620,41
-16548,1515493788839,37
-16549,1515493810153,34
-16550,1515493851642,34
-16551,1515493954778,39
-16552,1515493983045,37
-16553,1515494007767,35
-16554,1515494050486,35
-16555,1515494071966,33
-16556,1515494096525,33
-16557,1515494129716,32
-16558,1515494199255,55
-16559,1515494210592,59
-16560,1515494334554,68
-16561,1515494338898,65
-16562,1515494353504,98
-16563,1515494455024,109
-16564,1515494604505,107
-16565,1515494723195,104
-16566,1515494768051,102
-16567,1515494809365,104
-16568,1515494903215,106
-16569,1515495014384,105
-16570,1515495513419,102
-16571,1515495590940,99
-16572,1515495694101,102
-16573,1515495821632,101
-16574,1515496018313,99
-16575,1515496604708,95
-16576,1515496689491,93
-16577,1515496710274,92
-16578,1515496799407,99
-16579,1515497072186,99
-16580,1515497190702,96
-16581,1515497418094,94
-16582,1515497518028,90
-16583,1515497708904,89
-16584,1515497719704,86
-16585,1515497743771,103
-16586,1515497864394,110
-16587,1515498955767,107
-16588,1515499001499,103
-16589,1515499133045,104
-16590,1515499370713,100
-16591,1515499752337,96
-16592,1515499954943,92
-16593,1515499982381,88
-16594,1515500203987,93
-16595,1515500260115,88
-16596,1515500343722,92
-16597,1515500404153,92
-16598,1515500747603,90
-16599,1515500936770,87
-16600,1515501143095,83
-16601,1515501197220,79
-16602,1515501348073,79
-16603,1515501480897,85
-16604,1515501550284,84
-16605,1515501571175,97
-16606,1515501676392,107
-16607,1515501958792,105
-16608,1515502154761,102
-16609,1515502206810,99
-16610,1515502288578,99
-16611,1515502503006,98
-16612,1515502720905,94
-16613,1515502931694,92
-16614,1515503230793,88
-16615,1515503412283,85
-16616,1515503432974,83
-16617,1515503481875,87
-16618,1515503608366,91
-16619,1515503762990,89
-16620,1515503938500,86
-16621,1515504075946,84
-16622,1515504114478,82
-16623,1515504156105,82
-16624,1515504208798,89
-16625,1515504728613,91
-16626,1515505346284,86
-16627,1515505481636,82
-16628,1515505591567,80
-16629,1515505700408,78
-16630,1515505851490,75
-16631,1515506006212,72
-16632,1515506163938,69
-16633,1515506599208,66
-16634,1515506653294,62
-16635,1515506683857,62
-16636,1515506854559,63
-16637,1515507603375,59
-16638,1515507630836,56
-16639,1515507652551,57
-16640,1515507765687,61
-16641,1515507827298,58
-16642,1515507968516,57
-16643,1515508200379,53
-16644,1515508308300,49
-16645,1515508354600,45
-16646,1515508419474,43
-16647,1515508476967,40
-16648,1515508594221,37
-16649,1515508621639,34
-16650,1515508633022,34
-16651,1515508656942,37
-16652,1515508674854,36
-16653,1515508719268,38
-16654,1515508787137,37
-16655,1515508864735,34
-16656,1515508869498,31
-16657,1515508965359,43
-16658,1515509045383,41
-16659,1515509076400,38
-16660,1515509105970,42
-16661,1515509161645,41
-16662,1515509193029,57
-16663,1515509207520,64
-16664,1515509281169,72
-16665,1515509385850,71
-16666,1515509554268,70
-16667,1515509578982,69
-16668,1515509627571,74
-16669,1515509655812,75
-16670,1515509722600,78
-16671,1515509823603,76
-16672,1515509918957,75
-16673,1515510211893,74
-16674,1515510518917,71
-16675,1515510705116,68
-16676,1515510762389,64
-16677,1515511176587,64
-16678,1515511267549,65
-16679,1515511472703,64
-16680,1515511709841,61
-16681,1515511840122,59
-16682,1515511864923,56
-16683,1515511902036,58
-16684,1515512110290,58
-16685,1515512165396,64
-16686,1515512267522,69
-16687,1515512378346,67
-16688,1515512492893,64
-16689,1515512511312,65
-16690,1515512779338,70
-16691,1515512807268,68
-16692,1515513023580,70
-16693,1515513135027,67
-16694,1515513277114,69
-16695,1515513287710,66
-16696,1515513292348,79
-16697,1515513333765,117
-16698,1515513775301,121
-16699,1515514104489,117
-16700,1515514182983,114
-16701,1515514523084,113
-16702,1515514895709,111
-16703,1515514936364,108
-16704,1515515051323,110
-16705,1515515487696,109
-16706,1515515597515,110
-16707,1515516069384,110
-16708,1515516263410,106
-16709,1515516407628,103
-16710,1515516418454,102
-16711,1515516863201,122
-16712,1515517603813,118
-16713,1515517718995,114
-16714,1515517910226,112
-16715,1515518018406,110
-16716,1515518060071,107
-16717,1515518087586,113
-16718,1515518248700,121
-16719,1515518489607,118
-16720,1515518497221,116
-16721,1515518505020,147
-16722,1515518600587,188
-16723,1515519296705,189
-16724,1515519446924,186
-16725,1515519675084,185
-16726,1515519728614,182
-16727,1515519949598,184
-16728,1515520354216,180
-16729,1515520406087,176
-16730,1515521169986,178
-16731,1515521894992,173
-16732,1515522193491,169
-16733,1515522295500,163
-16734,1515522299771,161
-16735,1515522771139,247
-16736,1515524749880,243
-16737,1515524974676,236
-16738,1515525036937,230
-16739,1515525823441,235
-16740,1515525858140,231
-16741,1515525882829,240
-16742,1515526175282,256
-16743,1515526379336,251
-16744,1515527134651,246
-16745,1515527242574,239
-16746,1515527303887,237
-16747,1515527937223,239
-16748,1515528877811,233
-16749,1515529492882,225
-16750,1515529587208,219
-16751,1515529881930,220
-16752,1515529959817,215
-16753,1515530636064,216
-16754,1515531778801,209
-16755,1515532218783,202
-16756,1515532229767,196
-16757,1515532607814,238
-16758,1515533904712,231
-16759,1515534391272,224
-16760,1515534446581,218
-16761,1515535056411,221
-16762,1515535357206,214
-16763,1515535576875,209
-16764,1515536142526,208
-16765,1515536311386,202
-16766,1515536554476,196
-16767,1515536569126,190
-16768,1515536937416,216
-16769,1515537096755,210
-16770,1515537220379,208
-16771,1515537635124,205
-16772,1515537759188,198
-16773,1515537886502,194
-16774,1515538045197,189
-16775,1515538168822,183
-16776,1515538180657,178
-16777,1515538324341,207
-16778,1515538865301,201
-16779,1515539598494,193
-16780,1515539619787,185
-16781,1515539927599,196
-16782,1515539981596,188
-16783,1515540002596,189
-16784,1515540120639,203
-16785,1515540647072,197
-16786,1515540730684,189
-16787,1515540928230,186
-16788,1515541795464,178
-16789,1515542103177,169
-16790,1515542218853,165
-16791,1515542414188,158
-16792,1515542719415,152
-16793,1515543142090,144
-16794,1515543416664,136
-16795,1515543759871,128
-16796,1515544990108,125
-16797,1515545872268,136
-16798,1515546392093,131
-16799,1515547417406,124
-16800,1515548665517,115
-16801,1515548919271,107
-16802,1515549337904,99
-16803,1515549388068,92
-16804,1515549471618,90
-16805,1515549486161,84
-16806,1515549522127,90
-16807,1515549640485,87
-16808,1515549973930,81
-16809,1515550508020,72
-16810,1515550725655,64
-16811,1515550744386,67
-16812,1515550821379,67
-16813,1515551428473,60
-16814,1515551526862,52
-16815,1515551870584,45
-16816,1515551884876,37
-16817,1515551943581,37
-16818,1515551996747,35
-16819,1515552011216,29
-16820,1515552039138,25
-16821,1515552043623,36
-16822,1515552065371,71
-16823,1515552109667,73
-16824,1515552140483,69
-16825,1515552351517,68
-16826,1515552382781,62
-16827,1515552451628,62
-16828,1515552636365,57
-16829,1515552714295,50
-16830,1515552728756,47
-16831,1515552754352,47
-16832,1515552841953,43
-16833,1515553078539,38
-16834,1515553195156,32
-16835,1515553387278,70
-16836,1515553493037,65
-16837,1515553714639,60
-16838,1515553953572,54
-16839,1515554222933,54
-16840,1515554394651,48
-16841,1515554405686,49
-16842,1515554461179,66
-16843,1515554485432,63
-16844,1515554883392,64
-16845,1515555356795,59
-16846,1515555408179,56
-16847,1515555442142,57
-16848,1515555550256,55
-16849,1515555630013,51
-16850,1515555697662,46
-16851,1515555715445,45
-16852,1515555739131,45
-16853,1515555793157,47
-16854,1515555807360,43
-16855,1515555848545,45
-16856,1515555856356,41
-16857,1515555980717,70
-16858,1515556074429,66
-16859,1515556311256,62
-16860,1515556505590,58
-16861,1515556733254,57
-16862,1515556774140,52
-16863,1515556944248,51
-16864,1515557008214,46
-16865,1515557061854,43
-16866,1515557090072,41
-16867,1515557125159,39
-16868,1515557129544,52
-16869,1515557419132,76
-16870,1515557449692,72
-16871,1515557457305,74
-16872,1515557461718,93
-16873,1515557477658,139
-16874,1515557727552,155
-16875,1515557761717,151
-16876,1515558274668,156
-16877,1515558388233,169
-16878,1515558475613,167
-16879,1515558870722,165
-16880,1515559512658,160
-16881,1515559722650,165
-16882,1515559763995,161
-16883,1515559910740,169
-16884,1515559928208,177
-16885,1515560206306,197
-16886,1515560392552,192
-16887,1515560722115,191
-16888,1515561124667,187
-16889,1515562560861,182
-16890,1515562714397,177
-16891,1515562784905,175
-16892,1515563145261,175
-16893,1515563221369,171
-16894,1515563377307,170
-16895,1515563840365,167
-16896,1515564122385,161
-16897,1515564447893,157
-16898,1515564621267,152
-16899,1515565398612,147
-16900,1515565699879,141
-16901,1515567083386,136
-16902,1515567282962,130
-16903,1515567472244,126
-16904,1515567593610,123
-16905,1515568208431,120
-16906,1515568276240,121
-16907,1515568468854,122
-16908,1515568538853,119
-16909,1515568569391,117
-16910,1515568921018,119
-16911,1515569090253,115
-16912,1515569095320,114
-16913,1515569308266,162
-16914,1515569316346,157
-16915,1515569820582,197
-16916,1515570010324,191
-16917,1515570061866,189
-16918,1515570122115,190
-16919,1515570189934,191
-16920,1515570820082,192
-16921,1515571492997,186
-16922,1515572380514,189
-16923,1515573573666,185
-16924,1515574293700,180
-16925,1515574905730,175
-16926,1515575286561,169
-16927,1515575444900,164
-16928,1515575865502,161
-16929,1515576274430,155
-16930,1515576847531,149
-16931,1515577562092,147
-16932,1515578355055,142
-16933,1515578549495,135
-16934,1515579073427,130
-16935,1515579662353,124
-16936,1515579863538,118
-16937,1515579907201,112
-16938,1515579924601,112
-16939,1515580074039,120
-16940,1515580268328,114
-16941,1515580606912,108
-16942,1515581209164,107
-16943,1515581523677,102
-16944,1515581628883,98
-16945,1515582168480,93
-16946,1515582214164,86
-16947,1515582249475,84
-16948,1515582348704,85
-16949,1515582568558,80
-16950,1515582579316,75
-16951,1515582729879,84
-16952,1515582891253,82
-16953,1515583035487,77
-16954,1515583094686,72
-16955,1515583099010,71
-16956,1515583167062,104
-16957,1515583499849,107
-16958,1515583666663,100
-16959,1515583704174,94
-16960,1515583831343,93
-16961,1515583848783,87
-16962,1515583991228,91
-16963,1515584091586,87
-16964,1515584316097,81
-16965,1515584320731,75
-16966,1515584362789,106
-16967,1515584778079,105
-16968,1515584825557,99
-16969,1515585119193,109
-16970,1515585245440,102
-16971,1515585536346,99
-16972,1515585540707,103
-16973,1515585551960,178
-16974,1515585775511,219
-16975,1515586239314,214
-16976,1515586543847,212
-16977,1515586971294,206
-16978,1515587106239,200
-16979,1515587187126,199
-16980,1515587438154,196
-16981,1515587442500,191
-16982,1515587535115,288
-16983,1515588389618,291
-16984,1515589144918,283
-16985,1515589911132,287
-16986,1515590042451,280
-16987,1515590824935,277
-16988,1515591482035,269
-16989,1515591578881,261
-16990,1515592461878,259
-16991,1515592602083,250
-16992,1515592822856,248
-16993,1515592886724,243
-16994,1515593117965,245
-16995,1515593159647,239
-16996,1515593603063,244
-16997,1515593683743,236
-16998,1515594549014,234
-16999,1515595082085,226
-17000,1515595129322,218
-17001,1515595497317,220
-17002,1515596345694,211
-17003,1515597647281,203
-17004,1515599248546,193
-17005,1515599774014,185
-17006,1515600181139,176
-17007,1515600771649,170
-17008,1515600782633,162
-17009,1515600797036,190
-17010,1515600831237,215
-17011,1515600947177,220
-17012,1515602012171,214
-17013,1515602153755,231
-17014,1515602734451,227
-17015,1515603277281,241
-17016,1515603372855,234
-17017,1515603450682,231
-17018,1515604072844,234
-17019,1515604341966,229
-17020,1515604563936,225
-17021,1515604860379,219
-17022,1515604957375,211
-17023,1515605104680,207
-17024,1515605474697,202
-17025,1515605597295,194
-17026,1515606102863,188
-17027,1515606178477,180
-17028,1515606464744,178
-17029,1515607557311,170
-17030,1515607732073,161
-17031,1515607844344,154
-17032,1515608258094,149
-17033,1515608348917,140
-17034,1515608704602,135
-17035,1515609107962,126
-17036,1515609604234,117
-17037,1515609735081,109
-17038,1515609770008,105
-17039,1515610653339,110
-17040,1515610728438,101
-17041,1515610946865,96
-17042,1515611044722,89
-17043,1515611135055,81
-17044,1515611259001,74
-17045,1515611416022,67
-17046,1515611699947,59
-17047,1515611812713,53
-17048,1515611917314,46
-17049,1515612065944,40
-17050,1515612174104,31
-17051,1515612251470,31
-17052,1515612288818,24
-17053,1515612293090,17
-17054,1515612297442,17
-17055,1515612305338,19
-17056,1515612330100,37
-17057,1515612348150,33
-17058,1515612396603,29
-17059,1515612410745,22
-17060,1515612418539,20
-17061,1515612477171,19
-17062,1515612539011,16
-17063,1515612594065,9
-17064,1515612608739,1
-17065,1515612613052,1
-17066,1515612620889,6
-17067,1515612629826,2
-17068,1515612634046,1
-17069,1515612638445,1
-17070,1515612642802,1
-17071,1515612647389,1
-17072,1515612654755,1
-17073,1515612659116,1
-17074,1515612663503,4
-17075,1515612674686,1
-17076,1515612678885,1
-17077,1515612686535,1
-17078,1515612694526,1
-17079,1515612702943,1
-17080,1515612710634,1
-17081,1515612714783,1
-17082,1515612719832,20
-17083,1515612801941,29
-17084,1515612862603,25
-17085,1515612899865,22
-17086,1515612907746,19
-17087,1515612964865,22
-17088,1515613030887,19
-17089,1515613076352,16
-17090,1515613080669,15
-17091,1515613085052,19
-17092,1515613102613,27
-17093,1515613114314,26
-17094,1515613128449,32
-17095,1515613166657,33
-17096,1515613421680,37
-17097,1515613589657,35
-17098,1515613627286,34
-17099,1515613648328,31
-17100,1515613731698,31
-17101,1515613772806,33
-17102,1515613783996,31
-17103,1515613829537,33
-17104,1515613893295,31
-17105,1515613901303,27
-17106,1515613956588,31
-17107,1515614038293,28
-17108,1515614134368,24
-17109,1515614396085,39
-17110,1515614477848,51
-17111,1515614524469,57
-17112,1515614640493,58
-17113,1515614794717,56
-17114,1515614885606,55
-17115,1515615280373,53
-17116,1515615503200,51
-17117,1515615618299,51
-17118,1515615682039,52
-17119,1515615725930,52
-17120,1515615808278,52
-17121,1515615920242,51
-17122,1515616230706,50
-17123,1515616265896,50
-17124,1515616270290,52
-17125,1515616284944,77
-17126,1515616528869,88
-17127,1515616635039,86
-17128,1515616708615,86
-17129,1515616757008,86
-17130,1515616844773,87
-17131,1515616984844,86
-17132,1515617216496,87
-17133,1515617324127,83
-17134,1515617603154,83
-17135,1515617903918,81
-17136,1515617932033,78
-17137,1515617968038,81
-17138,1515618079490,84
-17139,1515618496224,85
-17140,1515618783568,82
-17141,1515618820889,81
-17142,1515619278447,83
-17143,1515619373002,81
-17144,1515619393626,80
-17145,1515619441684,86
-17146,1515619670028,87
-17147,1515619739914,84
-17148,1515619763998,83
-17149,1515619812262,88
-17150,1515619991245,89
-17151,1515620189535,85
-17152,1515620210715,83
-17153,1515620296232,89
-17154,1515620525840,92
-17155,1515620876312,94
-17156,1515621244277,93
-17157,1515621286550,92
-17158,1515621394996,95
-17159,1515621399365,93
-17160,1515621457381,143
-17161,1515621514141,147
-17162,1515621634502,150
-17163,1515621844212,148
-17164,1515621872330,144
-17165,1515622306437,152
-17166,1515623102291,148
-17167,1515623405673,145
-17168,1515623965884,141
-17169,1515624292329,137
-17170,1515625261807,133
-17171,1515625421519,129
-17172,1515625683660,125
-17173,1515625842451,122
-17174,1515626011729,119
-17175,1515626130478,117
-17176,1515626242165,114
-17177,1515626369397,112
-17178,1515626657641,109
-17179,1515626713450,105
-17180,1515626731128,105
-17181,1515626762530,114
-17182,1515627168987,117
-17183,1515627648962,116
-17184,1515627750604,112
-17185,1515627876763,110
-17186,1515628111320,107
-17187,1515628235963,106
-17188,1515628625240,103
-17189,1515628851470,99
-17190,1515628869210,94
-17191,1515629185149,106
-17192,1515629189822,107
-17193,1515629293711,159
-17194,1515629605343,158
-17195,1515629753884,157
-17196,1515629992606,154
-17197,1515630537126,149
-17198,1515630941880,144
-17199,1515632531036,140
-17200,1515633714535,136
-17201,1515633856626,131
-17202,1515634037803,128
-17203,1515634599632,128
-17204,1515634650621,123
-17205,1515635414531,124
-17206,1515635722930,122
-17207,1515635917954,118
-17208,1515636550464,114
-17209,1515636611748,109
-17210,1515636928017,107
-17211,1515637758176,103
-17212,1515637891957,99
-17213,1515637975474,95
-17214,1515638312445,92
-17215,1515638441301,89
-17216,1515638699293,84
-17217,1515638891864,79
-17218,1515639132843,75
-17219,1515639144938,71
-17220,1515639365296,81
-17221,1515639488645,76
-17222,1515639564040,72
-17223,1515639642400,69
-17224,1515639667241,66
-17225,1515639698432,81
-17226,1515640017417,88
-17227,1515640157652,84
-17228,1515640176763,80
-17229,1515640417191,86
-17230,1515641430493,84
-17231,1515641478526,79
-17232,1515641522567,78
-17233,1515641679731,78
-17234,1515641767371,73
-17235,1515641869334,70
-17236,1515641951546,67
-17237,1515642222696,66
-17238,1515642782613,64
-17239,1515642786932,60
-17240,1515643134436,88
-17241,1515643543625,83
-17242,1515643585061,80
-17243,1515643694672,78
-17244,1515643732253,75
-17245,1515643773289,79
-17246,1515643865664,79
-17247,1515644109595,75
-17248,1515644352015,72
-17249,1515644724885,71
-17250,1515644891578,67
-17251,1515645081854,63
-17252,1515645163687,58
-17253,1515645236136,59
-17254,1515645364976,57
-17255,1515645664819,52
-17256,1515646124975,48
-17257,1515646148832,42
-17258,1515646251896,44
-17259,1515646361523,40
-17260,1515646382741,62
-17261,1515646424298,67
-17262,1515646572961,69
-17263,1515646587897,67
-17264,1515646766227,73
-17265,1515646797673,76
-17266,1515646839681,77
-17267,1515647009763,77
-17268,1515647133683,74
-17269,1515647647471,71
-17270,1515648173614,67
-17271,1515648425930,62
-17272,1515648433916,59
-17273,1515648580643,73
-17274,1515648859592,69
-17275,1515648897082,65
-17276,1515648955809,66
-17277,1515649164986,64
-17278,1515649193144,61
-17279,1515649267388,62
-17280,1515649418952,61
-17281,1515649516504,64
-17282,1515649923409,65
-17283,1515650331656,61
-17284,1515650661578,56
-17285,1515651276377,54
-17286,1515651540117,50
-17287,1515651933562,46
-17288,1515651994870,42
-17289,1515652079085,39
-17290,1515652130483,36
-17291,1515652165265,40
-17292,1515652253245,39
-17293,1515652326399,63
-17294,1515652425740,63
-17295,1515652560209,62
-17296,1515652632889,60
-17297,1515653019925,60
-17298,1515653024307,56
-17299,1515653052321,84
-17300,1515653073427,86
-17301,1515653257856,92
-17302,1515653588121,89
-17303,1515654033283,87
-17304,1515654769836,83
-17305,1515655470969,82
-17306,1515655826598,78
-17307,1515656223791,75
-17308,1515656461723,72
-17309,1515656568514,68
-17310,1515656653899,67
-17311,1515656744208,66
-17312,1515656968117,63
-17313,1515656989828,61
-17314,1515657065045,64
-17315,1515657375880,62
-17316,1515657665865,58
-17317,1515657767716,55
-17318,1515658053190,53
-17319,1515658348727,49
-17320,1515658388656,52
-17321,1515658438470,51
-17322,1515658465785,50
-17323,1515658490408,52
-17324,1515658528846,54
-17325,1515658710751,56
-17326,1515658832317,56
-17327,1515658994519,53
-17328,1515659026379,50
-17329,1515659118275,55
-17330,1515659350010,53
-17331,1515659644241,49
-17332,1515659665589,48
-17333,1515659703717,51
-17334,1515659848632,51
-17335,1515659866448,49
-17336,1515660008094,52
-17337,1515660015855,50
-17338,1515660076074,61
-17339,1515660154903,59
-17340,1515660486047,75
-17341,1515661031382,71
-17342,1515661075172,68
-17343,1515661482137,70
-17344,1515662074787,67
-17345,1515662096259,66
-17346,1515662154486,72
-17347,1515662249265,72
-17348,1515662483697,71
-17349,1515662532685,68
-17350,1515662590587,67
-17351,1515662742406,67
-17352,1515662887900,64
-17353,1515662915240,62
-17354,1515663041517,65
-17355,1515663457896,62
-17356,1515663462237,59
-17357,1515663649682,88
-17358,1515663916335,86
-17359,1515664053592,83
-17360,1515664178001,81
-17361,1515664297898,81
-17362,1515664544432,81
-17363,1515664582843,78
-17364,1515664590528,84
-17365,1515664907415,106
-17366,1515665224334,105
-17367,1515665239104,103
-17368,1515665454247,117
-17369,1515665657893,114
-17370,1515665770582,110
-17371,1515666422667,109
-17372,1515667228955,105
-17373,1515667754056,109
-17374,1515668578538,105
-17375,1515669230211,101
-17376,1515669323181,100
-17377,1515669533109,100
-17378,1515669860246,96
-17379,1515670376812,95
-17380,1515670724470,92
-17381,1515670769991,89
-17382,1515671009591,90
-17383,1515671169930,86
-17384,1515671282663,84
-17385,1515671593099,82
-17386,1515672009595,77
-17387,1515672484547,73
-17388,1515672502290,70
-17389,1515672592618,76
-17390,1515672691428,74
-17391,1515672808703,72
-17392,1515672868970,70
-17393,1515673054559,68
-17394,1515673290418,67
-17395,1515673387808,63
-17396,1515673572890,61
-17397,1515673782370,58
-17398,1515673952097,54
-17399,1515674241456,67
-17400,1515674269441,67
-17401,1515674281488,73
-17402,1515674318209,84
-17403,1515674381625,86
-17404,1515674447837,85
-17405,1515674982864,84
-17406,1515674994122,80
-17407,1515675057786,93
-17408,1515675105575,92
-17409,1515675120632,93
-17410,1515675413372,104
-17411,1515675886419,101
-17412,1515675890741,97
-17413,1515676041004,147
-17414,1515676121790,147
-17415,1515676307631,147
-17416,1515676661486,143
-17417,1515676933811,139
-17418,1515677225523,136
-17419,1515677379422,131
-17420,1515677699291,128
-17421,1515678019740,125
-17422,1515678132877,121
-17423,1515678193835,120
-17424,1515678286441,122
-17425,1515678418918,121
-17426,1515678511951,118
-17427,1515678820705,116
-17428,1515678882498,112
-17429,1515679155422,113
-17430,1515679163269,109
-17431,1515679245126,137
-17432,1515679457332,134
-17433,1515679802977,133
-17434,1515679890642,130
-17435,1515680209336,128
-17436,1515680364868,126
-17437,1515680439257,122
-17438,1515680527693,128
-17439,1515680596294,127
-17440,1515680614645,126
-17441,1515680757481,137
-17442,1515681336313,133
-17443,1515682445265,129
-17444,1515683326525,124
-17445,1515683409459,118
-17446,1515683415009,119
-17447,1515683477109,166
-17448,1515684028879,166
-17449,1515684641178,160
-17450,1515685422898,157
-17451,1515685587752,151
-17452,1515685813974,147
-17453,1515686089694,142
-17454,1515686111277,139
-17455,1515686613413,149
-17456,1515686836940,142
-17457,1515687160204,154
-17458,1515687264871,149
-17459,1515687620365,147
-17460,1515688135194,142
-17461,1515688382742,137
-17462,1515688599868,132
-17463,1515688959887,128
-17464,1515689415100,125
-17465,1515689767029,132
-17466,1515690118051,127
-17467,1515690829267,122
-17468,1515691288706,125
-17469,1515691412302,121
-17470,1515691687818,118
-17471,1515691759561,114
-17472,1515692008823,112
-17473,1515692229504,107
-17474,1515692489139,103
-17475,1515692506972,98
-17476,1515692639294,105
-17477,1515692843360,102
-17478,1515693186908,99
-17479,1515693259239,93
-17480,1515693266956,91
-17481,1515693339667,112
-17482,1515693404459,112
-17483,1515693639020,110
-17484,1515694083651,105
-17485,1515694149227,100
-17486,1515694244833,98
-17487,1515694318694,94
-17488,1515694490909,91
-17489,1515694552653,89
-17490,1515694653735,87
-17491,1515694737471,84
-17492,1515694830332,80
-17493,1515694997812,78
-17494,1515695032964,72
-17495,1515695117441,71
-17496,1515695422007,67
-17497,1515695470276,62
-17498,1515695586512,58
-17499,1515695767253,53
-17500,1515695813605,48
-17501,1515695934760,46
-17502,1515695993499,48
-17503,1515696144530,46
-17504,1515696268866,42
-17505,1515696462185,38
-17506,1515696561736,32
-17507,1515696659408,35
-17508,1515696684240,32
-17509,1515696708983,32
-17510,1515696876518,37
-17511,1515697161060,31
-17512,1515697248526,26
-17513,1515697252833,49
-17514,1515697257235,72
-17515,1515697589711,108
-17516,1515697631631,104
-17517,1515697774806,105
-17518,1515698038957,100
-17519,1515698396577,96
-17520,1515698624029,92
-17521,1515698817521,88
-17522,1515698842136,83
-17523,1515699097870,86
-17524,1515699173366,83
-17525,1515699389165,81
-17526,1515699931348,78
-17527,1515700425743,73
-17528,1515700596095,69
-17529,1515700630697,65
-17530,1515700741315,65
-17531,1515700896450,78
-17532,1515701210190,75
-17533,1515701383351,71
-17534,1515701560415,67
-17535,1515701643146,64
-17536,1515701804730,61
-17537,1515701989485,58
-17538,1515702130224,56
-17539,1515702197186,53
-17540,1515702218667,52
-17541,1515702263897,61
-17542,1515702449707,60
-17543,1515702750668,56
-17544,1515702775714,51
-17545,1515703065697,52
-17546,1515703445880,48
-17547,1515703453885,70
-17548,1515703522052,90
-17549,1515703584311,89
-17550,1515703930352,89
-17551,1515703961344,84
-17552,1515704190502,87
-17553,1515704329928,85
-17554,1515704522876,81
-17555,1515704616282,86
-17556,1515704745425,84
-17557,1515704971052,82
-17558,1515705301982,78
-17559,1515705733694,76
-17560,1515705768161,72
-17561,1515705803489,74
-17562,1515705911057,75
-17563,1515706016660,73
-17564,1515706651471,71
-17565,1515707326821,66
-17566,1515707393582,62
-17567,1515707401727,60
-17568,1515707474587,73
-17569,1515707546802,71
-17570,1515707785776,70
-17571,1515707868196,67
-17572,1515708094366,66
-17573,1515708109250,62
-17574,1515708362333,68
-17575,1515708765752,64
-17576,1515708780537,66
-17577,1515708866178,73
-17578,1515709012680,71
-17579,1515709171694,68
-17580,1515709443810,65
-17581,1515709641108,75
-17582,1515709852655,74
-17583,1515710170216,72
-17584,1515710530420,68
-17585,1515710938514,65
-17586,1515711069558,62
-17587,1515711346941,61
-17588,1515711519378,59
-17589,1515711596288,56
-17590,1515711652236,55
-17591,1515711720687,54
-17592,1515711895386,53
-17593,1515712138248,50
-17594,1515712225896,47
-17595,1515712329146,47
-17596,1515712457505,45
-17597,1515712653228,43
-17598,1515712851334,40
-17599,1515712910153,37
-17600,1515713034610,35
-17601,1515713192498,33
-17602,1515713302293,29
-17603,1515713413938,27
-17604,1515713421573,24
-17605,1515713443567,28
-17606,1515713465039,27
-17607,1515713512969,26
-17608,1515713524570,24
-17609,1515713619518,26
-17610,1515713719612,24
-17611,1515713787817,21
-17612,1515713858229,18
-17613,1515713914585,14
-17614,1515713977457,25
-17615,1515714025719,41
-17616,1515714132625,41
-17617,1515714357676,42
-17618,1515714548854,40
-17619,1515714577751,37
-17620,1515714754193,37
-17621,1515714944808,36
-17622,1515715191758,34
-17623,1515715260604,35
-17624,1515715357793,33
-17625,1515715444515,32
-17626,1515715459342,30
-17627,1515715488824,33
-17628,1515715578497,32
-17629,1515715689349,31
-17630,1515715792992,30
-17631,1515715797350,29
-17632,1515715811831,43
-17633,1515716005812,47
-17634,1515716189360,44
-17635,1515716327839,42
-17636,1515716346140,40
-17637,1515716364005,42
-17638,1515716439766,45
-17639,1515716528855,43
-17640,1515716593681,42
-17641,1515716784179,43
-17642,1515716795831,42
-17643,1515716827873,47
-17644,1515716994770,48
-17645,1515717559231,48
-17646,1515718088342,44
-17647,1515718221913,40
-17648,1515718257298,49
-17649,1515718529855,51
-17650,1515718625425,50
-17651,1515718728801,49
-17652,1515718759931,49
-17653,1515718781435,50
-17654,1515718789308,54
-17655,1515719131233,68
-17656,1515719169935,66
-17657,1515719225607,68
-17658,1515719367277,67
-17659,1515719466658,65
-17660,1515719543056,64
-17661,1515720416986,65
-17662,1515721299433,63
-17663,1515721311591,61
-17664,1515721353013,71
-17665,1515721641792,72
-17666,1515721792372,69
-17667,1515722460250,68
-17668,1515722971370,73
-17669,1515723280270,72
-17670,1515723645808,70
-17671,1515723719278,67
-17672,1515723765479,67
-17673,1515723773198,69
-17674,1515723808939,91
-17675,1515723837485,94
-17676,1515724235238,100
-17677,1515724327586,102
-17678,1515724471996,102
-17679,1515724664924,100
-17680,1515724719484,98
-17681,1515724812302,100
-17682,1515724940980,100
-17683,1515724959777,98
-17684,1515725050911,107
-17685,1515725402950,106
-17686,1515725761734,104
-17687,1515726037892,101
-17688,1515726087820,99
-17689,1515727018856,99
-17690,1515727103730,97
-17691,1515727467046,97
-17692,1515728030079,95
-17693,1515728963199,92
-17694,1515729941796,88
-17695,1515730426602,85
-17696,1515730842679,82
-17697,1515730854595,79
-17698,1515731139042,92
-17699,1515731395977,89
-17700,1515731465729,86
-17701,1515732530260,86
-17702,1515733700357,82
-17703,1515733890191,78
-17704,1515733994586,75
-17705,1515734025219,77
-17706,1515734087426,80
-17707,1515734186145,81
-17708,1515734301159,80
-17709,1515734464772,80
-17710,1515734537810,77
-17711,1515734679131,76
-17712,1515734794021,74
-17713,1515734934158,72
-17714,1515735066699,69
-17715,1515735077554,67
-17716,1515735130606,79
-17717,1515735465687,79
-17718,1515735848640,75
-17719,1515735924963,71
-17720,1515736269691,71
-17721,1515736627978,68
-17722,1515736688787,64
-17723,1515736778028,62
-17724,1515737175252,60
-17725,1515737186549,56
-17726,1515737384231,65
-17727,1515737671083,63
-17728,1515737675837,61
-17729,1515737728544,88
-17730,1515738092655,88
-17731,1515738310848,83
-17732,1515738647388,88
-17733,1515738927002,87
-17734,1515739513780,84
-17735,1515739964649,80
-17736,1515740219982,76
-17737,1515740359826,75
-17738,1515740520706,75
-17739,1515740528395,72
-17740,1515740550573,91
-17741,1515740595262,96
-17742,1515741062079,97
-17743,1515741558330,97
-17744,1515741646840,95
-17745,1515741845146,93
-17746,1515742125586,90
-17747,1515742355036,85
-17748,1515742417920,81
-17749,1515742585746,81
-17750,1515742775236,78
-17751,1515743281372,75
-17752,1515743383197,71
-17753,1515743418888,70
-17754,1515743721909,72
-17755,1515744062644,77
-17756,1515744161366,73
-17757,1515744193864,72
-17758,1515744211958,74
-17759,1515744501218,81
-17760,1515744791825,78
-17761,1515744962668,74
-17762,1515744997119,71
-17763,1515745538193,71
-17764,1515745657431,73
-17765,1515745811255,72
-17766,1515745845863,69
-17767,1515745896855,70
-17768,1515746178245,69
-17769,1515746192378,65
-17770,1515746243480,72
-17771,1515746337569,70
-17772,1515746469057,68
-17773,1515746615971,67
-17774,1515746716397,74
-17775,1515746847872,75
-17776,1515747167759,76
-17777,1515747192017,72
-17778,1515747272142,77
-17779,1515747393046,75
-17780,1515747468021,73
-17781,1515747499258,73
-17782,1515747534748,76
-17783,1515747539172,78
-17784,1515747600898,122
-17785,1515747645524,123
-17786,1515747722290,126
-17787,1515748102777,125
-17788,1515748452849,121
-17789,1515748895585,118
-17790,1515749235143,115
-17791,1515749290151,112
-17792,1515749441935,112
-17793,1515749545478,109
-17794,1515749706627,107
-17795,1515749773651,103
-17796,1515749857738,101
-17797,1515750417834,99
-17798,1515751075019,103
-17799,1515751600739,99
-17800,1515751625210,95
-17801,1515752004702,101
-17802,1515752036165,96
-17803,1515752209941,99
-17804,1515752527262,96
-17805,1515752652660,91
-17806,1515752786729,91
-17807,1515752974269,90
-17808,1515753035664,87
-17809,1515753106853,86
-17810,1515753226726,84
-17811,1515753352671,82
-17812,1515753481228,79
-17813,1515753541868,76
-17814,1515753666244,75
-17815,1515753930769,72
-17816,1515754232381,75
-17817,1515754323285,73
-17818,1515754600609,70
-17819,1515754608556,66
-17820,1515754704087,82
-17821,1515754968223,79
-17822,1515755174748,75
-17823,1515755244722,72
-17824,1515755764083,70
-17825,1515755835589,65
-17826,1515756282091,69
-17827,1515756885272,64
-17828,1515757209457,59
-17829,1515757472670,71
-17830,1515757631135,69
-17831,1515757681804,66
-17832,1515757686121,65
-17833,1515757748365,97
-17834,1515758212964,97
-17835,1515758224208,92
-17836,1515758331555,106
-17837,1515759117453,104
-17838,1515760100296,100
-17839,1515760445598,95
-17840,1515760631180,101
-17841,1515760918740,102
-17842,1515761128433,101
-17843,1515761326063,98
-17844,1515761453687,94
-17845,1515761772639,93
-17846,1515762053173,89
-17847,1515762308615,85
-17848,1515762749091,81
-17849,1515762868213,79
-17850,1515763033898,76
-17851,1515763051798,73
-17852,1515763071251,77
-17853,1515763333692,83
-17854,1515763668760,80
-17855,1515763777162,77
-17856,1515763781562,74
-17857,1515764138233,110
-17858,1515764297728,107
-17859,1515764668692,108
-17860,1515764826297,104
-17861,1515764860385,100
-17862,1515764951432,103
-17863,1515765037424,102
-17864,1515765195602,99
-17865,1515765331988,96
-17866,1515765407232,93
-17867,1515765474970,93
-17868,1515765750483,92
-17869,1515766114582,88
-17870,1515766169472,88
-17871,1515767069762,88
-17872,1515768388035,85
-17873,1515768416017,80
-17874,1515768487876,82
-17875,1515768949610,80
-17876,1515769555685,76
-17877,1515769770432,71
-17878,1515769883069,70
-17879,1515769931010,67
-17880,1515770198478,65
-17881,1515770481702,62
-17882,1515770577521,60
-17883,1515770642746,59
-17884,1515770726844,78
-17885,1515770875705,78
-17886,1515771118895,77
-17887,1515771223425,76
-17888,1515771354161,74
-17889,1515771420744,72
-17890,1515771618352,70
-17891,1515771813733,66
-17892,1515771882528,65
-17893,1515771982204,63
-17894,1515772267977,62
-17895,1515772835732,59
-17896,1515772840579,57
-17897,1515773025747,82
-17898,1515773265054,79
-17899,1515773539350,75
-17900,1515773801128,71
-17901,1515774214699,71
-17902,1515775090374,68
-17903,1515775226710,67
-17904,1515775375984,65
-17905,1515775680682,61
-17906,1515775714930,58
-17907,1515775770946,58
-17908,1515775910704,57
-17909,1515775952269,55
-17910,1515776000733,55
-17911,1515776086169,55
-17912,1515776174269,52
-17913,1515776186736,50
-17914,1515776390498,56
-17915,1515776565084,53
-17916,1515776783729,50
-17917,1515777038971,45
-17918,1515777270157,42
-17919,1515777318828,38
-17920,1515777354101,46
-17921,1515777373884,46
-17922,1515777469536,48
-17923,1515777742453,45
-17924,1515778057811,42
-17925,1515778253298,38
-17926,1515778507351,35
-17927,1515778658310,32
-17928,1515778780487,27
-17929,1515778801591,24
-17930,1515778870577,23
-17931,1515778929605,20
-17932,1515778933956,18
-17933,1515778980234,42
-17934,1515779071910,42
-17935,1515779150517,39
-17936,1515779210716,47
-17937,1515779233363,46
-17938,1515779447355,48
-17939,1515779685873,44
-17940,1515779806864,41
-17941,1515779824697,39
-17942,1515780013242,41
-17943,1515780227911,38
-17944,1515780279088,35
-17945,1515780287686,34
-17946,1515780297065,40
-17947,1515780459657,47
-17948,1515780640618,44
-17949,1515780978023,40
-17950,1515781070015,38
-17951,1515781108042,36
-17952,1515781234677,39
-17953,1515781398074,40
-17954,1515781538879,37
-17955,1515781681326,35
-17956,1515781764363,32
-17957,1515781789158,50
-17958,1515781856228,52
-17959,1515781995998,52
-17960,1515782017319,50
-17961,1515782120943,52
-17962,1515782262926,55
-17963,1515782455740,54
-17964,1515782640208,53
-17965,1515782722230,51
-17966,1515782841323,50
-17967,1515782977293,49
-17968,1515783166559,49
-17969,1515783281004,47
-17970,1515783359848,45
-17971,1515783398600,46
-17972,1515783431294,45
-17973,1515783812124,45
-17974,1515783922501,46
-17975,1515784065341,46
-17976,1515784128989,44
-17977,1515784344367,43
-17978,1515784638393,40
-17979,1515784806172,39
-17980,1515784884936,37
-17981,1515784988031,36
-17982,1515785083172,34
-17983,1515785198339,33
-17984,1515785613632,32
-17985,1515785913821,30
-17986,1515785948519,28
-17987,1515786078250,27
-17988,1515786252424,26
-17989,1515786267527,24
-17990,1515786290077,27
-17991,1515786359669,27
-17992,1515786421721,25
-17993,1515786539761,24
-17994,1515786585415,23
-17995,1515786707713,21
-17996,1515786825326,19
-17997,1515786854196,31
-17998,1515787092013,31
-17999,1515787308759,30
-18000,1515787424232,28
-18001,1515787446651,27
-18002,1515787468938,26
-18003,1515787491136,27
-18004,1515787500761,28
-18005,1515787552328,33
-18006,1515787616271,32
-18007,1515787649391,32
-18008,1515787795480,33
-18009,1515787864071,32
-18010,1515787940994,32
-18011,1515788044452,31
-18012,1515788181416,31
-18013,1515788288613,29
-18014,1515788421953,32
-18015,1515788533981,31
-18016,1515788617445,29
-18017,1515788666556,28
-18018,1515788709349,27
-18019,1515788779332,26
-18020,1515788875920,26
-18021,1515788955305,25
-18022,1515789040043,27
-18023,1515789082390,26
-18024,1515789241645,25
-18025,1515789388712,23
-18026,1515789431113,21
-18027,1515789450447,20
-18028,1515789483074,21
-18029,1515789508918,20
-18030,1515789531022,21
-18031,1515789582890,22
-18032,1515789621490,20
-18033,1515789661004,24
-18034,1515789750429,25
-18035,1515789847170,23
-18036,1515790049507,22
-18037,1515790284965,22
-18038,1515790344139,22
-18039,1515790382993,21
-18040,1515790478539,20
-18041,1515790578006,19
-18042,1515790628321,20
-18043,1515790645066,19
-18044,1515790656936,20
-18045,1515790786511,23
-18046,1515790870042,26
-18047,1515790900017,29
-18048,1515790983827,31
-18049,1515791117016,30
-18050,1515791256719,29
-18051,1515791342767,28
-18052,1515791388234,27
-18053,1515791465571,28
-18054,1515791543432,27
-18055,1515791598887,26
-18056,1515791698866,25
-18057,1515791798161,25
-18058,1515791931086,26
-18059,1515792049361,26
-18060,1515792132762,25
-18061,1515792185365,26
-18062,1515792238870,26
-18063,1515792319556,26
-18064,1515792491929,25
-18065,1515792650740,25
-18066,1515792692933,24
-18067,1515792745517,24
-18068,1515792802445,24
-18069,1515792828999,23
-18070,1515792848617,24
-18071,1515792873935,26
-18072,1515792886201,28
-18073,1515793159249,33
-18074,1515793383546,32
-18075,1515793439471,31
-18076,1515793485061,31
-18077,1515793571695,32
-18078,1515793731977,31
-18079,1515793821066,29
-18080,1515793934376,29
-18081,1515793981674,28
-18082,1515794032058,28
-18083,1515794074454,29
-18084,1515794113405,28
-18085,1515794194796,28
-18086,1515794263887,28
-18087,1515794299537,28
-18088,1515794428863,27
-18089,1515794552693,26
-18090,1515794683858,26
-18091,1515794821034,27
-18092,1515794868564,27
-18093,1515794893839,26
-18094,1515794964364,27
-18095,1515795086175,27
-18096,1515795236806,25
-18097,1515795334042,24
-18098,1515795373251,25
-18099,1515795492711,24
-18100,1515795618081,23
-18101,1515795794160,22
-18102,1515795998544,22
-18103,1515796110550,22
-18104,1515796265788,23
-18105,1515796418944,25
-18106,1515796556183,23
-18107,1515796713384,23
-18108,1515796809879,24
-18109,1515796906059,22
-18110,1515796982335,22
-18111,1515797035323,21
-18112,1515797084798,22
-18113,1515797107545,21
-18114,1515797149872,22
-18115,1515797246960,22
-18116,1515797365534,22
-18117,1515797426444,21
-18118,1515797471487,20
-18119,1515797518517,21
-18120,1515797568471,21
-18121,1515797673517,21
-18122,1515797837257,20
-18123,1515797986204,19
-18124,1515798113556,18
-18125,1515798192884,18
-18126,1515798301024,17
-18127,1515798399987,16
-18128,1515798449413,16
-18129,1515798488564,16
-18130,1515798521029,17
-18131,1515798627468,17
-18132,1515798789454,17
-18133,1515798868769,16
-18134,1515798904581,16
-18135,1515799015885,16
-18136,1515799112725,16
-18137,1515799128922,15
-18138,1515799184765,16
-18139,1515799285736,15
-18140,1515799439389,14
-18141,1515799521005,14
-18142,1515799546886,13
-18143,1515799566023,13
-18144,1515799622273,15
-18145,1515799712573,16
-18146,1515799782351,15
-18147,1515799818250,15
-18148,1515799850226,16
-18149,1515799961116,16
-18150,1515800078873,15
-18151,1515800117866,15
-18152,1515800171546,14
-18153,1515800221410,14
-18154,1515800244861,14
-18155,1515800296899,14
-18156,1515800351244,14
-18157,1515800384308,14
-18158,1515800450634,14
-18159,1515800499858,14
-18160,1515800575289,13
-18161,1515800659248,12
-18162,1515800725185,12
-18163,1515800823076,11
-18164,1515800869500,11
-18165,1515801006234,11
-18166,1515801122109,10
-18167,1515801146975,9
-18168,1515801173083,9
-18169,1515801215780,10
-18170,1515801306887,9
-18171,1515801393648,10
-18172,1515801426226,10
-18173,1515801478729,13
-18174,1515801494593,13
-18175,1515801526817,13
-18176,1515801590720,14
-18177,1515801673139,15
-18178,1515801729273,14
-18179,1515801779375,13
-18180,1515801829771,14
-18181,1515801848748,13
-18182,1515801893968,15
-18183,1515801938622,15
-18184,1515802005231,16
-18185,1515802067366,16
-18186,1515802114815,16
-18187,1515802182106,16
-18188,1515802239448,17
-18189,1515802305516,17
-18190,1515802357769,16
-18191,1515802389468,16
-18192,1515802424934,16
-18193,1515802447310,18
-18194,1515802489575,19
-18195,1515802587691,20
-18196,1515802650870,20
-18197,1515802735836,19
-18198,1515802792747,19
-18199,1515802846380,20
-18200,1515802865656,19
-18201,1515802901347,21
-18202,1515802956814,21
-18203,1515803042568,22
-18204,1515803125589,21
-18205,1515803204968,21
-18206,1515803263503,21
-18207,1515803339353,21
-18208,1515803424112,20
-18209,1515803509443,20
-18210,1515803595814,20
-18211,1515803698180,20
-18212,1515803790635,19
-18213,1515803883611,19
-18214,1515804045084,20
-18215,1515804160036,19
-18216,1515804205660,19
-18217,1515804228462,20
-18218,1515804250596,21
-18219,1515804350631,22
-18220,1515804447179,22
-18221,1515804459703,22
-18222,1515804484807,26
-18223,1515804541052,27
-18224,1515804704675,27
-18225,1515804913009,26
-18226,1515805125239,26
-18227,1515805287450,25
-18228,1515805419827,25
-18229,1515805512310,24
-18230,1515805629090,24
-18231,1515805708597,24
-18232,1515805767777,24
-18233,1515805830301,24
-18234,1515805919800,23
-18235,1515805980316,24
-18236,1515806009160,23
-18237,1515806077738,24
-18238,1515806151895,25
-18239,1515806188334,25
-18240,1515806292511,26
-18241,1515806492313,25
-18242,1515806618301,24
-18243,1515806648089,24
-18244,1515806695582,26
-18245,1515806732528,26
-18246,1515806781923,26
-18247,1515806830772,26
-18248,1515806886773,27
-18249,1515806976892,28
-18250,1515807090247,28
-18251,1515807217405,27
-18252,1515807332284,27
-18253,1515807391287,26
-18254,1515807423882,26
-18255,1515807473605,28
-18256,1515807513287,28
-18257,1515807606372,28
-18258,1515807728662,29
-18259,1515807774248,28
-18260,1515807910720,28
-18261,1515808045585,27
-18262,1515808139513,27
-18263,1515808242779,27
-18264,1515808390781,26
-18265,1515808493758,26
-18266,1515808602179,25
-18267,1515808747989,24
-18268,1515808828862,23
-18269,1515808918527,24
-18270,1515809005654,23
-18271,1515809050605,22
-18272,1515809076199,23
-18273,1515809101891,24
-18274,1515809167926,24
-18275,1515809225434,25
-18276,1515809293148,25
-18277,1515809362956,25
-18278,1515809375168,25
-18279,1515809490239,28
-18280,1515809601645,28
-18281,1515809780021,27
-18282,1515810001291,27
-18283,1515810085106,27
-18284,1515810104364,26
-18285,1515810123156,29
-18286,1515810145173,30
-18287,1515810178031,33
-18288,1515810253486,34
-18289,1515810538713,33
-18290,1515810770655,33
-18291,1515810779352,32
-18292,1515810933263,40
-18293,1515811216956,39
-18294,1515811417492,39
-18295,1515811479583,38
-18296,1515811605383,38
-18297,1515811721142,37
-18298,1515811770570,37
-18299,1515812057337,37
-18300,1515812364523,36
-18301,1515812434707,37
-18302,1515812530540,36
-18303,1515812628039,36
-18304,1515812697445,36
-18305,1515812795706,36
-18306,1515812942423,36
-18307,1515813046000,35
-18308,1515813116871,34
-18309,1515813285622,34
-18310,1515813412796,33
-18311,1515813459120,32
-18312,1515813514896,32
-18313,1515813615214,33
-18314,1515813718353,31
-18315,1515813818602,31
-18316,1515813935530,30
-18317,1515814073079,29
-18318,1515814206220,29
-18319,1515814296218,29
-18320,1515814349592,28
-18321,1515814395092,28
-18322,1515814453699,30
-18323,1515814486187,31
-18324,1515814580246,33
-18325,1515814646486,31
-18326,1515814727315,31
-18327,1515814863301,31
-18328,1515814990400,30
-18329,1515815126814,29
-18330,1515815236024,29
-18331,1515815301918,26
-18332,1515815338698,27
-18333,1515815430405,26
-18334,1515815506185,27
-18335,1515815673047,26
-18336,1515815806221,26
-18337,1515815828684,26
-18338,1515815912324,27
-18339,1515816015907,27
-18340,1515816063969,27
-18341,1515816116983,27
-18342,1515816199391,26
-18343,1515816245311,25
-18344,1515816317476,26
-18345,1515816371565,26
-18346,1515816413436,26
-18347,1515816494682,27
-18348,1515816584268,26
-18349,1515816692093,26
-18350,1515816862950,25
-18351,1515816999774,24
-18352,1515817033066,23
-18353,1515817085149,24
-18354,1515817182045,23
-18355,1515817241177,23
-18356,1515817296848,23
-18357,1515817370264,23
-18358,1515817419393,23
-18359,1515817448321,22
-18360,1515817602911,23
-18361,1515817695662,22
-18362,1515817812068,22
-18363,1515817881757,20
-18364,1515817966389,20
-18365,1515818166125,19
-18366,1515818312281,18
-18367,1515818340964,17
-18368,1515818376887,17
-18369,1515818419545,16
-18370,1515818482848,17
-18371,1515818534805,15
-18372,1515818557484,15
-18373,1515818583781,16
-18374,1515818615749,17
-18375,1515818641355,17
-18376,1515818670173,18
-18377,1515818699171,17
-18378,1515818817968,18
-18379,1515818941532,19
-18380,1515819017430,18
-18381,1515819126717,17
-18382,1515819197520,16
-18383,1515819243149,15
-18384,1515819326640,15
-18385,1515819396506,16
-18386,1515819435846,17
-18387,1515819486349,18
-18388,1515819550037,19
-18389,1515819620095,18
-18390,1515819672927,18
-18391,1515819725192,17
-18392,1515819765518,21
-18393,1515819787812,21
-18394,1515819813843,22
-18395,1515819910301,22
-18396,1515820013051,23
-18397,1515820092199,23
-18398,1515820282197,22
-18399,1515820425722,22
-18400,1515820475362,21
-18401,1515820571317,21
-18402,1515820660635,20
-18403,1515820736442,20
-18404,1515820842590,20
-18405,1515820912708,20
-18406,1515820942158,19
-18407,1515821057416,20
-18408,1515821133420,19
-18409,1515821184525,20
-18410,1515821210356,19
-18411,1515821222406,20
-18412,1515821305173,23
-18413,1515821314206,23
-18414,1515821396749,28
-18415,1515821462629,28
-18416,1515821508487,28
-18417,1515821652798,28
-18418,1515821862585,27
-18419,1515821979915,26
-18420,1515822106882,26
-18421,1515822199584,26
-18422,1515822349922,26
-18423,1515822593615,25
-18424,1515822703594,25
-18425,1515822757979,25
-18426,1515822887800,25
-18427,1515822981585,24
-18428,1515823117041,24
-18429,1515823303786,23
-18430,1515823484821,22
-18431,1515823635309,21
-18432,1515823754673,21
-18433,1515823884598,21
-18434,1515824018977,20
-18435,1515824127013,19
-18436,1515824207214,19
-18437,1515824277697,19
-18438,1515824309725,19
-18439,1515824376493,20
-18440,1515824605434,19
-18441,1515824814689,19
-18442,1515824844679,18
-18443,1515824981804,19
-18444,1515825098535,19
-18445,1515825131552,18
-18446,1515825173200,19
-18447,1515825253018,19
-18448,1515825340105,19
-18449,1515825419200,19
-18450,1515825568908,18
-18451,1515825698001,18
-18452,1515825730096,16
-18453,1515825788729,17
-18454,1515825848161,17
-18455,1515825857061,17
-18456,1515825933557,21
-18457,1515826081439,20
-18458,1515826207656,20
-18459,1515826274990,20
-18460,1515826388056,20
-18461,1515826502436,20
-18462,1515826583374,18
-18463,1515826647244,18
-18464,1515826692709,18
-18465,1515826767455,17
-18466,1515826827387,17
-18467,1515826878453,17
-18468,1515826948720,17
-18469,1515827000942,17
-18470,1515827088371,16
-18471,1515827250897,16
-18472,1515827355079,16
-18473,1515827418859,15
-18474,1515827457813,15
-18475,1515827500929,15
-18476,1515827577770,16
-18477,1515827674188,16
-18478,1515827852110,16
-18479,1515828026925,15
-18480,1515828066877,15
-18481,1515828102500,14
-18482,1515828154969,14
-18483,1515828184457,14
-18484,1515828209719,14
-18485,1515828242000,15
-18486,1515828267740,15
-18487,1515828303678,16
-18488,1515828332120,16
-18489,1515828367908,17
-18490,1515828404411,16
-18491,1515828416503,17
-18492,1515828425935,19
-18493,1515828483595,24
-18494,1515828536399,25
-18495,1515828616144,25
-18496,1515828692642,25
-18497,1515828768918,25
-18498,1515828791487,24
-18499,1515828834329,25
-18500,1515828968655,26
-18501,1515829130481,26
-18502,1515829211555,24
-18503,1515829278143,25
-18504,1515829358306,24
-18505,1515829421411,24
-18506,1515829480564,24
-18507,1515829537135,24
-18508,1515829566148,24
-18509,1515829652444,24
-18510,1515829752049,24
-18511,1515829875635,25
-18512,1515830022118,26
-18513,1515830115534,25
-18514,1515830161020,28
-18515,1515830202004,29
-18516,1515830237283,30
-18517,1515830269137,31
-18518,1515830460499,32
-18519,1515830713200,31
-18520,1515830836162,31
-18521,1515830888910,30
-18522,1515830978259,30
-18523,1515831037920,30
-18524,1515831073055,30
-18525,1515831162831,31
-18526,1515831276453,31
-18527,1515831457559,31
-18528,1515831626075,30
-18529,1515831657764,29
-18530,1515831693538,30
-18531,1515831746850,32
-18532,1515832002331,32
-18533,1515832372000,31
-18534,1515832563762,30
-18535,1515832643860,29
-18536,1515832765762,29
-18537,1515832846448,28
-18538,1515832926861,28
-18539,1515833010529,28
-18540,1515833050612,28
-18541,1515833101038,28
-18542,1515833147639,27
-18543,1515833205026,29
-18544,1515833254159,28
-18545,1515833290647,29
-18546,1515833350563,30
-18547,1515833442043,30
-18548,1515833537966,30
-18549,1515833641265,29
-18550,1515833709625,28
-18551,1515833728205,28
-18552,1515833797696,31
-18553,1515833907608,31
-18554,1515834014019,30
-18555,1515834186407,29
-18556,1515834321908,31
-18557,1515834381486,30
-18558,1515834608281,30
-18559,1515834918197,29
-18560,1515835045705,28
-18561,1515835088722,27
-18562,1515835264913,28
-18563,1515835460129,27
-18564,1515835545323,25
-18565,1515835651115,26
-18566,1515835751280,25
-18567,1515835811388,24
-18568,1515835885138,24
-18569,1515835951013,23
-18570,1515836019693,23
-18571,1515836082852,23
-18572,1515836125935,22
-18573,1515836171493,22
-18574,1515836210415,21
-18575,1515836236590,22
-18576,1515836249667,23
-18577,1515836319331,26
-18578,1515836625188,25
-18579,1515836963118,24
-18580,1515837054830,23
-18581,1515837065357,22
-18582,1515837122024,26
-18583,1515837177876,25
-18584,1515837237601,26
-18585,1515837344541,26
-18586,1515837454284,26
-18587,1515837632965,25
-18588,1515837794667,24
-18589,1515837874147,24
-18590,1515837930073,22
-18591,1515838004409,22
-18592,1515838079979,23
-18593,1515838095910,26
-18594,1515838114816,28
-18595,1515838197798,30
-18596,1515838308844,30
-18597,1515838349415,29
-18598,1515838490672,30
-18599,1515838734332,30
-18600,1515838863298,30
-18601,1515838952601,28
-18602,1515839075625,28
-18603,1515839144414,28
-18604,1515839193354,27
-18605,1515839310758,28
-18606,1515839427826,26
-18607,1515839590581,27
-18608,1515839756397,25
-18609,1515839876667,25
-18610,1515839986970,24
-18611,1515840063248,24
-18612,1515840131841,24
-18613,1515840140851,23
-18614,1515840176634,27
-18615,1515840185186,29
-18616,1515840271503,36
-18617,1515840340486,36
-18618,1515840455109,37
-18619,1515840476871,37
-18620,1515840516416,39
-18621,1515840623812,40
-18622,1515840776728,40
-18623,1515840901536,39
-18624,1515840963922,38
-18625,1515841003249,40
-18626,1515841053241,40
-18627,1515841091734,41
-18628,1515841118460,41
-18629,1515841481035,44
-18630,1515841938600,43
-18631,1515842055224,42
-18632,1515842381770,42
-18633,1515842673134,41
-18634,1515842860362,39
-18635,1515843224946,38
-18636,1515843686852,37
-18637,1515843903974,35
-18638,1515843984571,35
-18639,1515844081312,35
-18640,1515844112849,34
-18641,1515844158824,36
-18642,1515844220130,36
-18643,1515844312097,36
-18644,1515844419989,37
-18645,1515844565503,35
-18646,1515844768843,36
-18647,1515844858450,35
-18648,1515844903503,35
-18649,1515844976425,35
-18650,1515845023291,34
-18651,1515845096965,35
-18652,1515845178832,36
-18653,1515845278891,36
-18654,1515845393802,35
-18655,1515845431190,35
-18656,1515845662677,35
-18657,1515845910969,33
-18658,1515845940268,33
-18659,1515846114504,34
-18660,1515846334787,32
-18661,1515846411474,32
-18662,1515846535299,32
-18663,1515846644354,30
-18664,1515846754266,29
-18665,1515846762339,29
-18666,1515846843821,36
-18667,1515846848147,35
-18668,1515847236424,53
-18669,1515847564845,51
-18670,1515848079388,49
-18671,1515848233993,48
-18672,1515848347106,47
-18673,1515848460724,46
-18674,1515848501877,45
-18675,1515848622507,47
-18676,1515848791282,47
-18677,1515848897997,47
-18678,1515848985867,46
-18679,1515849090287,45
-18680,1515849250187,45
-18681,1515849426720,43
-18682,1515849538041,44
-18683,1515849783197,44
-18684,1515849945760,42
-18685,1515849953618,41
-18686,1515850020381,53
-18687,1515850111026,52
-18688,1515850225590,51
-18689,1515850332056,50
-18690,1515850478392,49
-18691,1515850751341,48
-18692,1515851101942,47
-18693,1515851208612,44
-18694,1515851292144,46
-18695,1515851364864,46
-18696,1515851469758,46
-18697,1515851787862,45
-18698,1515852136832,44
-18699,1515852182461,42
-18700,1515852276767,43
-18701,1515852366582,41
-18702,1515852663280,40
-18703,1515852759048,39
-18704,1515852863492,38
-18705,1515852896223,37
-18706,1515852925421,38
-18707,1515852937611,39
-18708,1515853004070,45
-18709,1515853080713,44
-18710,1515853103235,43
-18711,1515853115743,46
-18712,1515853200211,52
-18713,1515853325823,51
-18714,1515853363902,53
-18715,1515853433821,54
-18716,1515853976263,57
-18717,1515854512981,56
-18718,1515854566701,55
-18719,1515854670150,54
-18720,1515854784293,55
-18721,1515854863455,55
-18722,1515855063786,55
-18723,1515855243155,53
-18724,1515855308004,51
-18725,1515855505286,52
-18726,1515855520044,51
-18727,1515855567002,58
-18728,1515855639015,60
-18729,1515855717179,61
-18730,1515855883099,61
-18731,1515856045376,59
-18732,1515856076709,57
-18733,1515856182807,60
-18734,1515856316836,58
-18735,1515856476530,57
-18736,1515856630954,55
-18737,1515856754686,53
-18738,1515856907566,52
-18739,1515856993296,50
-18740,1515857137029,50
-18741,1515857328572,50
-18742,1515857547311,48
-18743,1515857777497,47
-18744,1515857946617,45
-18745,1515858063255,43
-18746,1515858122045,42
-18747,1515858233218,41
-18748,1515858356112,40
-18749,1515858435233,39
-18750,1515858451175,38
-18751,1515858472132,42
-18752,1515858694863,45
-18753,1515858749614,43
-18754,1515859006848,42
-18755,1515859273872,40
-18756,1515859348120,40
-18757,1515859501195,38
-18758,1515859571093,36
-18759,1515859685158,35
-18760,1515859754479,34
-18761,1515859767370,33
-18762,1515860076933,36
-18763,1515860460541,34
-18764,1515860625555,32
-18765,1515860656675,30
-18766,1515860719525,33
-18767,1515860796601,33
-18768,1515860937790,41
-18769,1515861098764,40
-18770,1515861325909,38
-18771,1515861534323,36
-18772,1515861803911,34
-18773,1515861886255,33
-18774,1515861890479,32
-18775,1515861905013,49
-18776,1515861970315,55
-18777,1515862072394,54
-18778,1515862083428,53
-18779,1515862183458,62
-18780,1515862798032,62
-18781,1515863446811,60
-18782,1515863576439,57
-18783,1515863730874,55
-18784,1515863895716,54
-18785,1515863910235,52
-18786,1515864010251,63
-18787,1515864078748,63
-18788,1515864209984,63
-18789,1515864271554,62
-18790,1515864556964,62
-18791,1515864820346,61
-18792,1515864984356,58
-18793,1515865134864,56
-18794,1515865406089,55
-18795,1515865659789,53
-18796,1515865690658,51
-18797,1515865803001,53
-18798,1515865880636,51
-18799,1515866014657,50
-18800,1515866466850,48
-18801,1515866525848,47
-18802,1515866711600,46
-18803,1515866998032,44
-18804,1515867167562,42
-18805,1515867367193,40
-18806,1515867617797,39
-18807,1515867645751,38
-18808,1515867736712,42
-18809,1515868034454,41
-18810,1515868489708,40
-18811,1515868982990,39
-18812,1515869034773,41
-18813,1515869039516,41
-18814,1515869190119,60
-18815,1515869434925,60
-18816,1515869728253,59
-18817,1515869917600,56
-18818,1515870291890,54
-18819,1515870566229,53
-18820,1515870660539,51
-18821,1515870771959,50
-18822,1515870959660,49
-18823,1515871193583,47
-18824,1515871316853,45
-18825,1515871514690,44
-18826,1515871705085,43
-18827,1515871836311,45
-18828,1515872019483,44
-18829,1515872157450,43
-18830,1515872309307,42
-18831,1515872385641,41
-18832,1515872400751,40
-18833,1515872519578,46
-18834,1515872677475,45
-18835,1515872765561,44
-18836,1515872832992,43
-18837,1515872935851,41
-18838,1515873265532,40
-18839,1515873592353,38
-18840,1515873639925,37
-18841,1515873844324,37
-18842,1515874018469,34
-18843,1515874090977,33
-18844,1515874177188,32
-18845,1515874267165,30
-18846,1515874406126,29
-18847,1515874604879,27
-18848,1515874767363,26
-18849,1515874881970,24
-18850,1515875043645,22
-18851,1515875176396,23
-18852,1515875321224,23
-18853,1515875400914,21
-18854,1515875480402,20
-18855,1515875516635,19
-18856,1515875560088,18
-18857,1515875588638,18
-18858,1515875633629,16
-18859,1515875641353,15
-18860,1515875650615,19
-18861,1515875716334,22
-18862,1515875734540,22
-18863,1515875767490,23
-18864,1515875810465,22
-18865,1515875870734,21
-18866,1515875971019,21
-18867,1515875975295,19
-18868,1515876030440,28
-18869,1515876100109,27
-18870,1515876122148,26
-18871,1515876244390,27
-18872,1515876395150,24
-18873,1515876472465,22
-18874,1515876522143,20
-18875,1515876526744,28
-18876,1515876535141,45
-18877,1515876589587,56
-18878,1515876661803,56
-18879,1515876713126,62
-18880,1515876911183,62
-18881,1515877219478,60
-18882,1515877852382,58
-18883,1515878338877,56
-18884,1515878449152,54
-18885,1515878572390,53
-18886,1515878649344,56
-18887,1515878728249,57
-18888,1515878814944,57
-18889,1515878918066,57
-18890,1515878973708,57
-18891,1515879046363,56
-18892,1515879331008,57
-18893,1515879697278,54
-18894,1515879866360,53
-18895,1515880047998,52
-18896,1515880161224,50
-18897,1515880229599,50
-18898,1515880395113,50
-18899,1515880490173,49
-18900,1515880590148,49
-18901,1515880758993,48
-18902,1515880930992,47
-18903,1515881034842,45
-18904,1515881170451,44
-18905,1515881395027,42
-18906,1515881618595,41
-18907,1515881761228,39
-18908,1515881915154,38
-18909,1515882087720,37
-18910,1515882298932,36
-18911,1515882411971,34
-18912,1515882465197,33
-18913,1515882473114,32
-18914,1515882544888,51
-18915,1515882708314,50
-18916,1515882875803,48
-18917,1515883045739,48
-18918,1515883082055,46
-18919,1515883093604,47
-18920,1515883180604,55
-18921,1515883202019,55
-18922,1515883343604,58
-18923,1515883515755,57
-18924,1515883753055,56
-18925,1515884073522,54
-18926,1515884298564,53
-18927,1515884461388,51
-18928,1515884668794,50
-18929,1515884896538,47
-18930,1515885043492,46
-18931,1515885099118,45
-18932,1515885123298,44
-18933,1515885211644,49
-18934,1515885255924,49
-18935,1515885313118,49
-18936,1515885328881,50
-18937,1515885415874,55
-18938,1515885563487,54
-18939,1515886019264,53
-18940,1515886309756,51
-18941,1515886634946,49
-18942,1515886742119,47
-18943,1515886836605,46
-18944,1515887028606,45
-18945,1515887225755,43
-18946,1515887312640,41
-18947,1515887426034,40
-18948,1515887481669,38
-18949,1515887590908,38
-18950,1515888012306,36
-18951,1515888369905,34
-18952,1515888419945,31
-18953,1515888707731,31
-18954,1515889080771,28
-18955,1515889085251,25
-18956,1515889168037,37
-18957,1515889254670,36
-18958,1515889326485,35
-18959,1515889421629,34
-18960,1515889495311,34
-18961,1515889589123,35
-18962,1515889600407,33
-18963,1515889728325,38
-18964,1515889885321,37
-18965,1515889968728,36
-18966,1515890214431,34
-18967,1515890457636,32
-18968,1515890486621,35
-18969,1515890627535,36
-18970,1515890867161,35
-18971,1515890919942,34
-18972,1515891032646,32
-18973,1515891098179,31
-18974,1515891105841,29
-18975,1515891147009,37
-18976,1515891269339,44
-18977,1515891388358,48
-18978,1515891445514,48
-18979,1515891472759,49
-18980,1515891507916,52
-18981,1515891645329,54
-18982,1515891777419,53
-18983,1515891979935,51
-18984,1515892083325,49
-18985,1515892202135,48
-18986,1515892257227,47
-18987,1515892324384,48
-18988,1515892364105,48
-18989,1515892439971,49
-18990,1515892778806,49
-18991,1515893085597,48
-18992,1515893104668,47
-18993,1515893187110,50
-18994,1515893278857,49
-18995,1515893283243,48
-18996,1515893500126,73
-18997,1515893504562,71
-18998,1515893777046,107
-18999,1515893947698,106
-19000,1515894429990,104
-19001,1515894713527,102
-19002,1515895292383,99
-19003,1515895731894,96
-19004,1515896151075,94
-19005,1515896856488,91
-19006,1515897247650,88
-19007,1515897312591,86
-19008,1515897484646,85
-19009,1515897499817,83
-19010,1515897560115,93
-19011,1515897617418,94
-19012,1515897901667,94
-19013,1515898311159,92
-19014,1515898627003,93
-19015,1515899079430,92
-19016,1515899669208,89
-19017,1515900343729,86
-19018,1515900893785,83
-19019,1515900956676,81
-19020,1515901283817,86
-19021,1515901582054,83
-19022,1515901690848,83
-19023,1515901879310,82
-19024,1515901971027,81
-19025,1515902212162,80
-19026,1515902515031,77
-19027,1515902795037,74
-19028,1515903049828,72
-19029,1515903118814,70
-19030,1515903203106,68
-19031,1515903470331,67
-19032,1515903711407,65
-19033,1515903850314,65
-19034,1515903973227,63
-19035,1515904099868,62
-19036,1515904393439,61
-19037,1515904664166,62
-19038,1515904918395,61
-19039,1515905049615,59
-19040,1515905181079,56
-19041,1515905229760,55
-19042,1515905245552,54
-19043,1515905338333,59
-19044,1515905482380,58
-19045,1515905681977,55
-19046,1515905872048,53
-19047,1515905982698,51
-19048,1515906107778,49
-19049,1515906288250,47
-19050,1515906347075,45
-19051,1515906423177,43
-19052,1515906517601,41
-19053,1515906808175,40
-19054,1515906826132,37
-19055,1515906866118,39
-19056,1515906894950,45
-19057,1515906954759,45
-19058,1515907156157,44
-19059,1515907170602,41
-19060,1515907312211,45
-19061,1515907509391,44
-19062,1515907610524,41
-19063,1515907686949,42
-19064,1515907769225,40
-19065,1515907780585,38
-19066,1515907822301,43
-19067,1515907867782,43
-19068,1515907936953,41
-19069,1515908089526,40
-19070,1515908245955,38
-19071,1515908373576,35
-19072,1515908508487,33
-19073,1515908667789,30
-19074,1515908755514,28
-19075,1515908870443,30
-19076,1515908963286,28
-19077,1515909072330,26
-19078,1515909120619,23
-19079,1515909191343,22
-19080,1515909295856,22
-19081,1515909364835,20
-19082,1515909392689,19
-19083,1515909450435,17
-19084,1515909521461,16
-19085,1515909549818,13
-19086,1515909569580,12
-19087,1515909598720,11
-19088,1515909624730,9
-19089,1515909643959,8
-19090,1515909744040,7
-19091,1515909786836,4
-19092,1515909821866,1
-19093,1515909830656,1
-19094,1515909842591,1
-19095,1515909851914,1
-19096,1515909861186,8
-19097,1515909887268,7
-19098,1515909905811,25
-19099,1515909938647,26
-19100,1515909984246,27
-19101,1515909995331,27
-19102,1515910030123,30
-19103,1515910081478,30
-19104,1515910146909,30
-19105,1515910180242,29
-19106,1515910212386,29
-19107,1515910268957,29
-19108,1515910372854,29
-19109,1515910442120,29
-19110,1515910503361,34
-19111,1515910586649,35
-19112,1515910754080,36
-19113,1515910934187,34
-19114,1515910958833,33
-19115,1515910973333,35
-19116,1515911110972,39
-19117,1515911246420,37
-19118,1515911301551,36
-19119,1515911351103,36
-19120,1515911372402,37
-19121,1515911452281,39
-19122,1515911600721,38
-19123,1515911695361,38
-19124,1515911712844,37
-19125,1515911735328,41
-19126,1515911867623,44
-19127,1515912006998,42
-19128,1515912058956,41
-19129,1515912286483,41
-19130,1515912626116,40
-19131,1515912837625,39
-19132,1515912910262,38
-19133,1515913002964,37
-19134,1515913424284,36
-19135,1515913870088,35
-19136,1515913921614,33
-19137,1515913991780,33
-19138,1515914017533,32
-19139,1515914107611,32
-19140,1515914195681,32
-19141,1515914255356,31
-19142,1515914358145,31
-19143,1515914625027,34
-19144,1515914889530,33
-19145,1515915069557,32
-19146,1515915204461,30
-19147,1515915246922,29
-19148,1515915315934,29
-19149,1515915406193,28
-19150,1515915466839,27
-19151,1515915519464,26
-19152,1515915602713,26
-19153,1515915713769,26
-19154,1515915788988,24
-19155,1515915814475,25
-19156,1515915954939,27
-19157,1515915979247,27
-19158,1515915990244,28
-19159,1515916045382,33
-19160,1515916124527,36
-19161,1515916177726,35
-19162,1515916233654,35
-19163,1515916329571,35
-19164,1515916433094,35
-19165,1515916586219,34
-19166,1515916611363,36
-19167,1515916626421,39
-19168,1515916658784,44
-19169,1515916717824,47
-19170,1515917070300,46
-19171,1515917421008,45
-19172,1515917439425,44
-19173,1515917482030,48
-19174,1515917528108,48
-19175,1515917550614,49
-19176,1515917630127,52
-19177,1515917668718,52
-19178,1515917863921,54
-19179,1515918072075,52
-19180,1515918124880,51
-19181,1515918129210,51
-19182,1515918345254,77
-19183,1515918578728,76
-19184,1515918669267,75
-19185,1515918857981,74
-19186,1515919016344,73
-19187,1515919096084,72
-19188,1515919182433,72
-19189,1515919256256,72
-19190,1515919312448,72
-19191,1515919501496,72
-19192,1515919765819,70
-19193,1515920002299,68
-19194,1515920475399,65
-19195,1515920907983,63
-19196,1515921128520,61
-19197,1515921184412,60
-19198,1515921346938,60
-19199,1515921498985,59
-19200,1515921545486,59
-19201,1515921771189,59
-19202,1515922119024,60
-19203,1515922280787,58
-19204,1515922643853,58
-19205,1515922960144,55
-19206,1515923345601,54
-19207,1515923487298,53
-19208,1515923627194,52
-19209,1515923769940,51
-19210,1515923869604,49
-19211,1515924227781,48
-19212,1515924513763,46
-19213,1515924555386,44
-19214,1515924559956,45
-19215,1515924735829,67
-19216,1515924893515,68
-19217,1515924898113,66
-19218,1515926252447,98
-19219,1515926651605,96
-19220,1515927250222,93
-19221,1515927800647,93
-19222,1515928487528,90
-19223,1515928864249,88
-19224,1515928956888,85
-19225,1515929085444,87
-19226,1515929276439,87
-19227,1515929365438,86
-19228,1515929416185,85
-19229,1515929465878,87
-19230,1515929644304,88
-19231,1515929868870,86
-19232,1515930132508,83
-19233,1515930365459,82
-19234,1515930623164,79
-19235,1515930780845,77
-19236,1515930909034,75
-19237,1515931092500,74
-19238,1515931338450,72
-19239,1515931571656,71
-19240,1515931715230,69
-19241,1515931751067,66
-19242,1515931822285,68
-19243,1515931918134,67
-19244,1515932037178,66
-19245,1515932120767,64
-19246,1515932146898,62
-19247,1515932378971,65
-19248,1515932681822,63
-19249,1515932896210,60
-19250,1515932957888,57
-19251,1515933197165,57
-19252,1515933550105,55
-19253,1515933695982,51
-19254,1515933738396,49
-19255,1515934047656,48
-19256,1515934103983,46
-19257,1515934189573,46
-19258,1515934329074,44
-19259,1515934402586,44
-19260,1515934459492,43
-19261,1515934594204,43
-19262,1515934731913,40
-19263,1515934811302,38
-19264,1515934910003,36
-19265,1515935027169,34
-19266,1515935076646,31
-19267,1515935176545,31
-19268,1515935264489,31
-19269,1515935290224,31
-19270,1515935352244,32
-19271,1515935414717,30
-19272,1515935499808,28
-19273,1515935514487,28
-19274,1515935573789,30
-19275,1515935622352,29
-19276,1515935669339,30
-19277,1515935735937,29
-19278,1515935845553,29
-19279,1515935980346,27
-19280,1515936043097,24
-19281,1515936121656,23
-19282,1515936218951,35
-19283,1515936271144,33
-19284,1515936282452,33
-19285,1515936304864,38
-19286,1515936334188,39
-19287,1515936453808,40
-19288,1515936718311,39
-19289,1515936760335,38
-19290,1515936816052,38
-19291,1515936885933,38
-19292,1515936990596,37
-19293,1515937042774,36
-19294,1515937144662,35
-19295,1515937187978,33
-19296,1515937204252,32
-19297,1515937270065,34
-19298,1515937326515,34
-19299,1515937532600,33
-19300,1515937547357,31
-19301,1515937613629,34
-19302,1515937628205,32
-19303,1515937658071,35
-19304,1515937747403,36
-19305,1515937813358,33
-19306,1515937896846,32
-19307,1515937935499,29
-19308,1515938002208,29
-19309,1515938071215,27
-19310,1515938140961,25
-19311,1515938266143,24
-19312,1515938381480,21
-19313,1515938437977,19
-19314,1515938461301,18
-19315,1515938487462,28
-19316,1515938564902,29
-19317,1515938654743,27
-19318,1515938714910,42
-19319,1515938769732,43
-19320,1515938798754,42
-19321,1515938888618,43
-19322,1515938964189,42
-19323,1515939041979,41
-19324,1515939053256,41
-19325,1515939084004,48
-19326,1515939149158,50
-19327,1515939236970,50
-19328,1515939348649,50
-19329,1515939411018,50
-19330,1515939428756,52
-19331,1515939467550,57
-19332,1515939541003,58
-19333,1515939605242,58
-19334,1515939661959,59
-19335,1515939840596,58
-19336,1515940086478,57
-19337,1515940335912,56
-19338,1515940540065,54
-19339,1515940674593,52
-19340,1515941070844,51
-19341,1515941499780,49
-19342,1515941557739,49
-19343,1515941585752,50
-19344,1515941657382,52
-19345,1515941726281,52
-19346,1515941740411,52
-19347,1515941802803,61
-19348,1515941817307,61
-19349,1515941869637,69
-19350,1515942002962,70
-19351,1515942058153,69
-19352,1515942092545,69
-19353,1515942277302,71
-19354,1515942492255,70
-19355,1515942599748,69
-19356,1515943008243,68
-19357,1515943380043,66
-19358,1515943439621,65
-19359,1515943747960,65
-19360,1515944052761,63
-19361,1515944423664,61
-19362,1515944931272,59
-19363,1515945433088,57
-19364,1515945498887,55
-19365,1515945587790,55
-19366,1515945602759,54
-19367,1515945839188,59
-19368,1515946658339,58
-19369,1515947471137,56
-19370,1515947719629,54
-19371,1515947765997,52
-19372,1515947895062,53
-19373,1515948096424,51
-19374,1515948224195,51
-19375,1515948275017,49
-19376,1515948353929,49
-19377,1515948480043,49
-19378,1515948687332,48
-19379,1515948705212,45
-19380,1515948864021,49
-19381,1515948922049,47
-19382,1515948994398,46
-19383,1515949087970,45
-19384,1515949199703,44
-19385,1515949300089,46
-19386,1515949364996,46
-19387,1515949470451,46
-19388,1515949585958,45
-19389,1515949800482,43
-19390,1515950021254,41
-19391,1515950107271,40
-19392,1515950131871,39
-19393,1515950422884,40
-19394,1515950727961,38
-19395,1515950778317,36
-19396,1515950800647,36
-19397,1515950877688,39
-19398,1515950954742,38
-19399,1515951052432,37
-19400,1515951164024,36
-19401,1515951311501,36
-19402,1515951473436,35
-19403,1515951643499,35
-19404,1515951713102,35
-19405,1515951762187,33
-19406,1515951835087,33
-19407,1515951839359,32
-19408,1515951873878,48
-19409,1515951913316,49
-19410,1515952052098,50
-19411,1515952111289,48
-19412,1515952314023,47
-19413,1515952670893,45
-19414,1515952894229,42
-19415,1515953177528,41
-19416,1515953269938,39
-19417,1515953316377,38
-19418,1515953436931,37
-19419,1515953471299,36
-19420,1515953527516,37
-19421,1515953579751,36
-19422,1515953659788,36
-19423,1515953789261,35
-19424,1515953897577,33
-19425,1515953952814,35
-19426,1515954011093,36
-19427,1515954054066,36
-19428,1515954235275,35
-19429,1515954416165,34
-19430,1515954536224,33
-19431,1515954629990,34
-19432,1515954662373,35
-19433,1515954758374,35
-19434,1515954862354,34
-19435,1515954927847,34
-19436,1515955032885,33
-19437,1515955203350,32
-19438,1515955309969,30
-19439,1515955603917,27
-19440,1515955838821,26
-19441,1515955908324,24
-19442,1515955936403,22
-19443,1515956020585,23
-19444,1515956100248,23
-19445,1515956125646,22
-19446,1515956261685,22
-19447,1515956502983,25
-19448,1515956620559,24
-19449,1515956646941,27
-19450,1515956716745,29
-19451,1515956897886,29
-19452,1515956925437,29
-19453,1515957021532,31
-19454,1515957170543,30
-19455,1515957283394,29
-19456,1515957468592,28
-19457,1515957678547,26
-19458,1515957835493,25
-19459,1515958000076,25
-19460,1515958268460,23
-19461,1515958508729,22
-19462,1515958632723,20
-19463,1515958643705,18
-19464,1515958705385,21
-19465,1515958766602,20
-19466,1515958778672,20
-19467,1515958860901,26
-19468,1515958885507,25
-19469,1515958917665,25
-19470,1515958933930,25
-19471,1515958955368,27
-19472,1515959028826,29
-19473,1515959173275,29
-19474,1515959297363,28
-19475,1515959342581,26
-19476,1515959347063,27
-19477,1515959364723,39
-19478,1515959399042,43
-19479,1515959455011,44
-19480,1515959548798,47
-19481,1515959573541,46
-19482,1515959595099,49
-19483,1515959641000,53
-19484,1515959778051,54
-19485,1515959823451,53
-19486,1515959953643,53
-19487,1515960214997,53
-19488,1515960422224,51
-19489,1515960539750,50
-19490,1515960644589,49
-19491,1515960734235,48
-19492,1515960824660,47
-19493,1515961053696,48
-19494,1515961325318,46
-19495,1515961469724,45
-19496,1515961868549,43
-19497,1515962336952,43
-19498,1515962563088,41
-19499,1515962679053,40
-19500,1515962917969,39
-19501,1515962989760,37
-19502,1515963140569,36
-19503,1515963250484,35
-19504,1515963347657,33
-19505,1515963440903,33
-19506,1515963516417,32
-19507,1515963747876,31
-19508,1515963976881,39
-19509,1515964057638,38
-19510,1515964106704,39
-19511,1515964206428,40
-19512,1515964302799,40
-19513,1515964333804,38
-19514,1515964417469,39
-19515,1515964490544,39
-19516,1515964566958,38
-19517,1515964865050,37
-19518,1515965149136,37
-19519,1515965217265,35
-19520,1515965312086,36
-19521,1515965456360,35
-19522,1515965512930,35
-19523,1515965669491,36
-19524,1515965829542,34
-19525,1515965845960,32
-19526,1515965850710,36
-19527,1515965910518,53
-19528,1515965955794,54
-19529,1515966022560,55
-19530,1515966140764,54
-19531,1515966276580,54
-19532,1515966326244,53
-19533,1515966446202,55
-19534,1515966550448,53
-19535,1515966615007,52
-19536,1515966639806,53
-19537,1515966688633,55
-19538,1515966775119,56
-19539,1515967090975,56
-19540,1515967382338,54
-19541,1515967434701,51
-19542,1515967460377,51
-19543,1515967476966,55
-19544,1515967583949,61
-19545,1515967755631,60
-19546,1515967839476,59
-19547,1515967976404,59
-19548,1515968321952,57
-19549,1515968357211,54
-19550,1515968438803,57
-19551,1515968604578,56
-19552,1515968737458,54
-19553,1515968955085,53
-19554,1515969188036,52
-19555,1515969308672,50
-19556,1515969424242,49
-19557,1515969498634,47
-19558,1515969580892,46
-19559,1515969649739,45
-19560,1515969684166,43
-19561,1515969728816,44
-19562,1515969801132,44
-19563,1515969805622,42
-19564,1515970099450,64
-19565,1515970263340,62
-19566,1515970504478,60
-19567,1515970643399,60
-19568,1515970864549,57
-19569,1515971116079,56
-19570,1515971261965,55
-19571,1515971273088,55
-19572,1515971294331,64
-19573,1515971586052,70
-19574,1515971877002,67
-19575,1515971919416,65
-19576,1515972003761,65
-19577,1515972021920,72
-19578,1515972114633,80
-19579,1515972327411,81
-19580,1515972627109,80
-19581,1515972915205,78
-19582,1515973144215,78
-19583,1515973452806,78
-19584,1515973784612,77
-19585,1515974081581,75
-19586,1515974291773,75
-19587,1515974607922,73
-19588,1515974887954,71
-19589,1515975372737,69
-19590,1515975786709,67
-19591,1515976146864,65
-19592,1515976466526,63
-19593,1515976806973,61
-19594,1515977121681,59
-19595,1515977534369,57
-19596,1515977902384,55
-19597,1515978101912,52
-19598,1515978353576,50
-19599,1515978433742,47
-19600,1515978459448,46
-19601,1515978678961,48
-19602,1515978775760,46
-19603,1515978828604,45
-19604,1515978972737,44
-19605,1515979376773,43
-19606,1515979742930,40
-19607,1515979859259,38
-19608,1515980022674,36
-19609,1515980223166,34
-19610,1515980399049,32
-19611,1515980506881,30
-19612,1515980535986,29
-19613,1515980610693,29
-19614,1515980665102,28
-19615,1515980677204,26
-19616,1515980686327,29
-19617,1515980772896,35
-19618,1515980889374,33
-19619,1515980988036,30
-19620,1515981000696,29
-19621,1515981068872,32
-19622,1515981148340,30
-19623,1515981322527,29
-19624,1515981330889,26
-19625,1515981350084,31
-19626,1515981376084,33
-19627,1515981387223,43
-19628,1515981422139,50
-19629,1515981457143,52
-19630,1515981575066,54
-19631,1515981689643,51
-19632,1515981749456,50
-19633,1515981955062,50
-19634,1515982147867,48
-19635,1515982204143,46
-19636,1515982300837,46
-19637,1515982407825,47
-19638,1515982458756,46
-19639,1515982643977,46
-19640,1515982835424,44
-19641,1515983028601,42
-19642,1515983344428,40
-19643,1515983408499,40
-19644,1515983480781,42
-19645,1515983614286,42
-19646,1515983877617,40
-19647,1515984111551,38
-19648,1515984237070,37
-19649,1515984353858,34
-19650,1515984436744,34
-19651,1515984466098,34
-19652,1515984679817,34
-19653,1515984914109,32
-19654,1515984966435,30
-19655,1515985006039,29
-19656,1515985040859,28
-19657,1515985193955,28
-19658,1515985315609,27
-19659,1515985331332,25
-19660,1515985358881,26
-19661,1515985411277,28
-19662,1515985453433,27
-19663,1515985516819,27
-19664,1515985524850,36
-19665,1515985555775,45
-19666,1515985714878,47
-19667,1515985926769,44
-19668,1515986176336,42
-19669,1515986410410,40
-19670,1515986516043,38
-19671,1515986586016,37
-19672,1515986635094,42
-19673,1515986695042,45
-19674,1515986737452,45
-19675,1515986770940,45
-19676,1515986854121,48
-19677,1515986925710,48
-19678,1515987059198,52
-19679,1515987152059,52
-19680,1515987362751,50
-19681,1515987644936,50
-19682,1515987766953,48
-19683,1515987842885,47
-19684,1515987905808,46
-19685,1515987938776,46
-19686,1515988016600,47
-19687,1515988108723,47
-19688,1515988223936,46
-19689,1515988376278,45
-19690,1515988513478,43
-19691,1515988664871,42
-19692,1515988764436,40
-19693,1515988874230,39
-19694,1515989022957,38
-19695,1515989088089,36
-19696,1515989240228,35
-19697,1515989473509,33
-19698,1515989560146,31
-19699,1515989608736,30
-19700,1515989655795,30
-19701,1515989760874,30
-19702,1515989787185,29
-19703,1515989836951,31
-19704,1515989900205,30
-19705,1515989939715,30
-19706,1515989985265,28
-19707,1515990041106,28
-19708,1515990121424,27
-19709,1515990236674,25
-19710,1515990261191,23
-19711,1515990289724,23
-19712,1515990300574,23
-19713,1515990326566,28
-19714,1515990379536,28
-19715,1515990421823,27
-19716,1515990477383,28
-19717,1515990552625,31
-19718,1515990706295,29
-19719,1515990848683,29
-19720,1515990871059,26
-19721,1515990914275,30
-19722,1515990946979,30
-19723,1515991006768,29
-19724,1515991072523,28
-19725,1515991156852,31
-19726,1515991268489,31
-19727,1515991339746,31
-19728,1515991433887,35
-19729,1515991628696,36
-19730,1515991783870,36
-19731,1515991840664,35
-19732,1515991868409,35
-19733,1515991923754,36
-19734,1515991982421,36
-19735,1515992069505,35
-19736,1515992161624,35
-19737,1515992228635,35
-19738,1515992282359,34
-19739,1515992381351,36
-19740,1515992520229,35
-19741,1515992577966,33
-19742,1515992705833,33
-19743,1515992906833,32
-19744,1515993042607,30
-19745,1515993139329,29
-19746,1515993237753,28
-19747,1515993310677,27
-19748,1515993443292,26
-19749,1515993578731,25
-19750,1515993709065,23
-19751,1515993868313,22
-19752,1515993997654,22
-19753,1515994080850,21
-19754,1515994117615,19
-19755,1515994180036,19
-19756,1515994226982,19
-19757,1515994272965,19
-19758,1515994336554,18
-19759,1515994375301,17
-19760,1515994425423,18
-19761,1515994572150,17
-19762,1515994688909,17
-19763,1515994803345,16
-19764,1515994912990,15
-19765,1515995009847,19
-19766,1515995112652,19
-19767,1515995134785,18
-19768,1515995164459,19
-19769,1515995220031,18
-19770,1515995280894,18
-19771,1515995306767,17
-19772,1515995344439,18
-19773,1515995404933,18
-19774,1515995467803,18
-19775,1515995513948,19
-19776,1515995576076,19
-19777,1515995648772,19
-19778,1515995698983,19
-19779,1515995873638,18
-19780,1515996074006,18
-19781,1515996164086,17
-19782,1515996243687,16
-19783,1515996310371,15
-19784,1515996334576,14
-19785,1515996350924,15
-19786,1515996373722,17
-19787,1515996412664,18
-19788,1515996448419,19
-19789,1515996495436,19
-19790,1515996560842,19
-19791,1515996602932,18
-19792,1515996669209,17
-19793,1515996686893,18
-19794,1515996723318,19
-19795,1515996820503,19
-19796,1515996936879,18
-19797,1515997058958,17
-19798,1515997175532,16
-19799,1515997222149,15
-19800,1515997302129,15
-19801,1515997323365,15
-19802,1515997345926,15
-19803,1515997361550,17
-19804,1515997387647,18
-19805,1515997414456,19
-19806,1515997440790,20
-19807,1515997524664,21
-19808,1515997608553,20
-19809,1515997637477,20
-19810,1515997670031,20
-19811,1515997696015,21
-19812,1515997783187,22
-19813,1515997891256,24
-19814,1515997975894,24
-19815,1515998035193,24
-19816,1515998061437,25
-19817,1515998130832,26
-19818,1515998197081,26
-19819,1515998242976,26
-19820,1515998278691,25
-19821,1515998337805,27
-19822,1515998401140,27
-19823,1515998584675,29
-19824,1515998803544,28
-19825,1515998874775,27
-19826,1515998954405,27
-19827,1515999097101,27
-19828,1515999228157,27
-19829,1515999320930,26
-19830,1515999381250,25
-19831,1515999488159,25
-19832,1515999673578,24
-19833,1515999927150,26
-19834,1516000137113,25
-19835,1516000229297,24
-19836,1516000285348,24
-19837,1516000356106,24
-19838,1516000425681,24
-19839,1516000580090,25
-19840,1516000783374,24
-19841,1516000897762,24
-19842,1516000945298,23
-19843,1516001186158,23
-19844,1516001415888,22
-19845,1516001434936,21
-19846,1516001453952,24
-19847,1516001544376,25
-19848,1516001629135,26
-19849,1516001661363,25
-19850,1516001745175,25
-19851,1516001875525,25
-19852,1516001995155,24
-19853,1516002088776,24
-19854,1516002144708,24
-19855,1516002176905,23
-19856,1516002292750,24
-19857,1516002338274,23
-19858,1516002367022,24
-19859,1516002428644,25
-19860,1516002528691,25
-19861,1516002642212,25
-19862,1516002694461,24
-19863,1516002710306,23
-19864,1516002803018,25
-19865,1516002929443,25
-19866,1516003021110,24
-19867,1516003114816,24
-19868,1516003174044,23
-19869,1516003189823,24
-19870,1516003248959,26
-19871,1516003274261,26
-19872,1516003433962,29
-19873,1516003592219,28
-19874,1516003624227,27
-19875,1516003686820,27
-19876,1516003783041,28
-19877,1516003869695,27
-19878,1516003908880,26
-19879,1516003993892,27
-19880,1516004001852,26
-19881,1516004010521,33
-19882,1516004090062,41
-19883,1516004186470,41
-19884,1516004442059,39
-19885,1516004779903,39
-19886,1516004926003,39
-19887,1516005179531,38
-19888,1516005411723,37
-19889,1516005424485,37
-19890,1516005513950,42
-19891,1516005600018,42
-19892,1516005642559,42
-19893,1516005775615,43
-19894,1516005914654,43
-19895,1516006045959,43
-19896,1516006243637,42
-19897,1516006390911,41
-19898,1516006496929,40
-19899,1516006904852,39
-19900,1516007482181,38
-19901,1516007699455,36
-19902,1516007736469,35
-19903,1516007819699,37
-19904,1516007834468,37
-19905,1516007882476,43
-19906,1516007977561,43
-19907,1516008014500,44
-19908,1516008026604,45
-19909,1516008036062,52
-19910,1516008133086,65
-19911,1516008158648,64
-19912,1516008176164,70
-19913,1516008270118,76
-19914,1516008336860,77
-19915,1516008349165,77
-19916,1516008407967,91
-19917,1516008419797,93
-19918,1516008826341,109
-19919,1516008860056,107
-19920,1516008919723,112
-19921,1516008981663,115
-19922,1516009018567,117
-19923,1516009084408,122
-19924,1516009369302,124
-19925,1516009559141,122
-19926,1516009622341,119
-19927,1516009645623,121
-19928,1516009710030,131
-19929,1516009744002,133
-19930,1516009882409,139
-19931,1516009902924,138
-19932,1516010423790,150
-19933,1516010707692,147
-19934,1516011168782,144
-19935,1516011411733,142
-19936,1516011966541,139
-19937,1516012517111,136
-19938,1516012961019,133
-19939,1516013061559,130
-19940,1516013521641,129
-19941,1516014090570,126
-19942,1516200834598,123
-19943,1516200904328,120
-19944,1516201049783,119
-19945,1516201105151,118
-19946,1516201231809,120
-19947,1516201275152,119
-19948,1516201325844,122
-19949,1516201579927,124
-19950,1516201590747,121
-19951,1516201648346,144
-19952,1516201692677,146
-19953,1516202083936,149
-19954,1516202227186,145
-19955,1516202424599,143
-19956,1516202559782,141
-19957,1516202759780,138
-19958,1516202770724,136
-19959,1516203291946,162
-19960,1516203535584,157
-19961,1516203586059,155
-19962,1516204129484,156
-19963,1516204441298,153
-19964,1516204712788,150
-19965,1516204984244,146
-19966,1516205149630,141
-19967,1516205205005,138
-19968,1516205267672,139
-19969,1516205439552,140
-19970,1516205458162,138
-19971,1516205738749,151
-19972,1516206133755,147
-19973,1516206312203,142
-19974,1516206375017,138
-19975,1516206607750,139
-19976,1516206901997,134
-19977,1516207346206,130
-19978,1516207498289,125
-19979,1516207750491,122
-19980,1516207880469,117
-19981,1516208038928,118
-19982,1516208109220,119
-19983,1516208372325,118
-19984,1516208600659,113
-19985,1516208660937,109
-19986,1516208679097,107
-19987,1516208875412,115
-19988,1516208913566,111
-19989,1516209060525,112
-19990,1516209086046,111
-19991,1516209217819,116
-19992,1516209290480,113
-19993,1516209508277,111
-19994,1516209711378,106
-19995,1516210373766,101
-19996,1516210441355,96
-19997,1516210575619,93
-19998,1516210730918,88
-19999,1516210790930,84
-20000,1516210871044,81
-20001,1516210936246,78
-20002,1516210971857,74
-20003,1516211275824,73
-20004,1516211552360,68
-20005,1516211563326,65
-20006,1516211594256,74
-20007,1516211597810,74
-20008,1516211690027,119
-20009,1516211787445,118
-20010,1516211827869,121
-20011,1516211841323,121
-20012,1516211859696,139
-20013,1516211946529,155
-20014,1516212088040,153
-20015,1516212237205,149
-20016,1516212524421,151
-20017,1516212707897,147
-20018,1516212800589,150
-20019,1516212942160,148
-20020,1516212975219,147
-20021,1516213057705,153
-20022,1516213151938,152
-20023,1516213182928,152
-20024,1516213288032,160
-20025,1516213427057,156
-20026,1516213433345,153
-20027,1516213550325,206
-20028,1516214407101,209
-20029,1516215301471,203
-20030,1516215514963,201
-20031,1516215568257,196
-20032,1516215742002,205
-20033,1516215792222,201
-20034,1516216766545,204
-20035,1516216972180,196
-20036,1516217349010,192
-20037,1516217630961,185
-20038,1516217727735,178
-20039,1516218910432,175
-20040,1516219311981,169
-20041,1516219471509,163
-20042,1516219507733,158
-20043,1516219584813,160
-20044,1516219796090,159
-20045,1516220134530,154
-20046,1516220231919,149
-20047,1516220272342,146
-20048,1516220650444,150
-20049,1516220910978,145
-20050,1516221134577,139
-20051,1516221229439,147
-20052,1516221233001,145
-20053,1516221492918,240
-20054,1516222338429,234
-20055,1516222349708,227
-20056,1516223024843,266
-20057,1516223119477,259
-20058,1516223295208,257
-20059,1516223719741,266
-20060,1516223993575,258
-20061,1516224120216,252
-20062,1516224136245,251
-20063,1516224302148,280
-20064,1516224458514,274
-20065,1516224772606,269
-20066,1516225048426,262
-20067,1516225392809,255
-20068,1516225487339,250
-20069,1516226473988,249
-20070,1516226883479,240
-20071,1516226924434,242
-20072,1516226992022,246
-20073,1516227116287,246
-20074,1516227299553,241
-20075,1516227325466,237
-20076,1516227461431,250
-20077,1516228266937,244
-20078,1516228423856,235
-20079,1516229346289,229
-20080,1516229509606,220
-20081,1516229609131,215
-20082,1516229780540,209
-20083,1516229829363,204
-20084,1516230219714,204
-20085,1516230295660,196
-20086,1516230942104,193
-20087,1516230979822,191
-20088,1516231220205,193
-20089,1516231760559,188
-20090,1516231985938,179
-20091,1516232078117,176
-20092,1516232696256,170
-20093,1516232717251,164
-20094,1516232743006,172
-20095,1516232898968,178
-20096,1516232993847,171
-20097,1516233145017,166
-20098,1516233418962,158
-20099,1516233989397,150
-20100,1516234127223,141
-20101,1516234300225,134
-20102,1516234705531,127
-20103,1516234798033,119
-20104,1516234945937,111
-20105,1516234959275,102
-20106,1516235386520,118
-20107,1516235664241,111
-20108,1516235766827,126
-20109,1516235842439,120
-20110,1516236560729,115
-20111,1516236738502,110
-20112,1516236754377,112
-20113,1516237225221,129
-20114,1516237236261,122
-20115,1516237405012,140
-20116,1516237680667,133
-20117,1516237799847,125
-20118,1516237857768,119
-20119,1516238374762,116
-20120,1516238646378,108
-20121,1516238718948,104
-20122,1516238759563,100
-20123,1516239346179,98
-20124,1516239465334,95
-20125,1516239902359,88
-20126,1516240017119,80
-20127,1516240124605,103
-20128,1516240152889,99
-20129,1516240314300,98
-20130,1516240384367,91
-20131,1516240501510,87
-20132,1516240576784,84
-20133,1516240585437,80
-20134,1516240943693,98
-20135,1516241175973,90
-20136,1516241432589,83
-20137,1516241513086,76
-20138,1516241811349,70
-20139,1516241965045,64
-20140,1516242015575,56
-20141,1516242058411,50
-20142,1516242104076,46
-20143,1516242120210,45
-20144,1516242281627,45
-20145,1516242309785,38
-20146,1516242392435,32
-20147,1516242425720,27
-20148,1516242434319,24
-20149,1516242457633,23
-20150,1516242468583,17
-20151,1516242486752,13
-20152,1516242574283,7
-20153,1516242577794,49
-20154,1516242618624,76
-20155,1516242747762,74
-20156,1516242808059,92
-20157,1516242878363,89
-20158,1516242881908,88
-20159,1516242944838,143
-20160,1516242973096,141
-20161,1516243139579,146
-20162,1516243970251,142
-20163,1516244006358,154
-20164,1516244458240,159
-20165,1516244533182,153
-20166,1516244662438,152
-20167,1516244774981,148
-20168,1516244924777,144
-20169,1516245027182,142
-20170,1516245257211,139
-20171,1516245331905,133
-20172,1516245571239,137
-20173,1516245771034,135
-20174,1516245866149,132
-20175,1516245968538,129
-20176,1516246119657,136
-20177,1516246248983,134
-20178,1516246547277,130
-20179,1516246679215,125
-20180,1516246719536,121
-20181,1516246996838,122
-20182,1516247136225,119
-20183,1516247142203,116
-20184,1516247678685,160
-20185,1516247783331,154
-20186,1516247840813,153
-20187,1516248619902,152
-20188,1516248680252,152
-20189,1516248812241,151
-20190,1516249041068,147
-20191,1516249323557,142
-20192,1516249789225,138
-20193,1516249889434,132
-20194,1516250086822,137
-20195,1516250181521,139
-20196,1516250648217,137
-20197,1516250947339,133
-20198,1516250982768,128
-20199,1516251045570,131
-20200,1516251063907,129
-20201,1516251109643,140
-20202,1516251226467,141
-20203,1516251306784,136
-20204,1516251715931,135
-20205,1516251778807,129
-20206,1516252288991,136
-20207,1516252305256,129
-20208,1516252882824,142
-20209,1516253107549,136
-20210,1516253335474,133
-20211,1516253351119,126
-20212,1516253510121,139
-20213,1516254006065,142
-20214,1516254073539,136
-20215,1516254205336,147
-20216,1516254550647,143
-20217,1516254594745,138
-20218,1516255058837,139
-20219,1516255190511,135
-20220,1516255309531,131
-20221,1516255486731,126
-20222,1516255522437,122
-20223,1516255604498,127
-20224,1516255637688,122
-20225,1516255935545,126
-20226,1516255983372,119
-20227,1516256107950,118
-20228,1516256146305,115
-20229,1516256172182,118
-20230,1516256276646,123
-20231,1516256312401,119
-20232,1516256394933,120
-20233,1516256450477,118
-20234,1516256507659,126
-20235,1516256858581,124
-20236,1516256899501,118
-20237,1516256927554,118
-20238,1516257002166,121
-20239,1516257663039,118
-20240,1516257673015,111
-20241,1516257681609,131
-20242,1516257755335,161
-20243,1516257903072,159
-20244,1516258059454,157
-20245,1516258112484,150
-20246,1516258411801,150
-20247,1516258561046,143
-20248,1516258725582,137
-20249,1516258940733,134
-20250,1516258973958,128
-20251,1516259103702,131
-20252,1516259176186,125
-20253,1516259528432,121
-20254,1516259618300,130
-20255,1516259651234,127
-20256,1516259749080,128
-20257,1516259792624,125
-20258,1516260391213,126
-20259,1516260613752,148
-20260,1516260626488,144
-20261,1516260731517,171
-20262,1516261159953,168
-20263,1516261230230,161
-20264,1516261290812,164
-20265,1516261523349,163
-20266,1516262028319,160
-20267,1516262034505,154
-20268,1516262053333,208
-20269,1516262890494,227
-20270,1516263478345,220
-20271,1516263521382,212
-20272,1516263589158,218
-20273,1516264788193,218
-20274,1516264902650,209
-20275,1516264932967,206
-20276,1516265013210,215
-20277,1516265098370,213
-20278,1516265128973,211
-20279,1516265299742,219
-20280,1516265571030,214
-20281,1516266059824,209
-20282,1516266112776,201
-20283,1516266448775,201
-20284,1516266651822,218
-20285,1516266655576,211
-20286,1516266827867,339
-20287,1516266924679,336
-20288,1516267555490,333
-20289,1516267912003,327
-20290,1516268007144,320
-20291,1516268134226,317
-20292,1516268331057,312
-20293,1516268970784,305
-20294,1516270283459,297
-20295,1516270517883,287
-20296,1516270578598,280
-20297,1516270631885,281
-20298,1516270821879,283
-20299,1516271132448,279
-20300,1516272031642,272
-20301,1516272450160,270
-20302,1516272753906,264
-20303,1516272873168,257
-20304,1516273476435,253
-20305,1516273644455,243
-20306,1516273757155,238
-20307,1516274146766,233
-20308,1516274204684,233
-20309,1516274411194,232
-20310,1516274951098,224
-20311,1516275090543,215
-20312,1516275252397,217
-20313,1516275512819,211
-20314,1516275531337,202
-20315,1516275566819,220
-20316,1516275982265,225
-20317,1516276580857,215
-20318,1516276592058,209
-20319,1516276657745,243
-20320,1516277157262,241
-20321,1516277886828,232
-20322,1516277892956,221
-20323,1516278824302,300
-20324,1516278866997,289
-20325,1516279019419,297
-20326,1516279197118,289
-20327,1516279267952,283
-20328,1516279397962,280
-20329,1516280035298,276
-20330,1516280654620,268
-20331,1516280802226,258
-20332,1516281051269,253
-20333,1516281109087,245
-20334,1516281363181,244
-20335,1516281462978,236
-20336,1516282259131,229
-20337,1516282347719,220
-20338,1516282353647,218
-20339,1516282384897,296
-20340,1516282539560,304
-20341,1516283371496,308
-20342,1516284218693,313
-20343,1516284658460,302
-20344,1516284945329,292
-20345,1516285837900,282
-20346,1516286181703,273
-20347,1516286351319,262
-20348,1516286627373,253
-20349,1516286803509,242
-20350,1516286854794,233
-20351,1516286860929,235
-20352,1516286874605,314
-20353,1516287880696,357
-20354,1516288082202,341
-20355,1516288227438,332
-20356,1516289216078,326
-20357,1516289356521,313
-20358,1516289762223,306
-20359,1516289822202,293
-20360,1516290172842,289
-20361,1516290472732,289
-20362,1516290893692,278
-20363,1516291180389,264
-20364,1516291698229,254
-20365,1516291704476,243
-20366,1516291858093,323
-20367,1516291889056,311
-20368,1516291905209,349
-20369,1516292102762,398
-20370,1516295012917,387
-20371,1516295985068,370
-20372,1516296942668,361
-20373,1516296968071,349
-20374,1516298092474,366
-20375,1516298348196,352
-20376,1516298840063,347
-20377,1516300771374,335
-20378,1516300978214,322
-20379,1516300999054,317
-20380,1516302606845,339
-20381,1516302944804,324
-20382,1516303042190,310
-20383,1516303428027,305
-20384,1516304445668,291
-20385,1516304797203,277
-20386,1516305139484,331
-20387,1516305293222,321
-20388,1516305450987,315
-20389,1516305806051,306
-20390,1516306020444,294
-20391,1516306249018,287
-20392,1516307724948,279
-20393,1516308219075,267
-20394,1516308532732,254
-20395,1516308699636,242
-20396,1516308939441,232
-20397,1516309072431,225
-20398,1516309223537,222
-20399,1516309528204,212
-20400,1516309787577,201
-20401,1516309938201,189
-20402,1516309972569,178
-20403,1516310342013,177
-20404,1516310372915,166
-20405,1516310450399,165
-20406,1516310515003,158
-20407,1516310538092,151
-20408,1516310610847,153
-20409,1516310696954,148
-20410,1516310987860,139
-20411,1516311023967,126
-20412,1516311085415,121
-20413,1516311106626,113
-20414,1516311216587,111
-20415,1516311643382,112
-20416,1516311664680,105
-20417,1516311926646,103
-20418,1516311985762,90
-20419,1516312028774,103
-20420,1516312262507,98
-20421,1516312401937,86
-20422,1516312699683,74
-20423,1516312751196,105
-20424,1516312874223,97
-20425,1516312930095,94
-20426,1516313043363,89
-20427,1516313047338,80
-20428,1516313122584,120
-20429,1516313148115,114
-20430,1516313385118,112
-20431,1516313485663,100
-20432,1516313526265,92
-20433,1516313572759,85
-20434,1516313591489,82
-20435,1516313812656,80
-20436,1516313843841,70
-20437,1516313862612,63
-20438,1516314063550,61
-20439,1516314069637,93
-20440,1516314399151,130
-20441,1516314449589,121
-20442,1516314540918,115
-20443,1516314804517,106
-20444,1516314903295,96
-20445,1516314906695,87
-20446,1516315085299,137
-20447,1516315914034,126
-20448,1516315932523,115
-20449,1516316107432,118
-20450,1516316428601,108
-20451,1516316493000,102
-20452,1516316545847,139
-20453,1516316593829,162
-20454,1516316702013,159
-20455,1516316896709,155
-20456,1516317219547,148
-20457,1516317839118,138
-20458,1516317850116,130
-20459,1516318013847,148
-20460,1516318048127,146
-20461,1516318081404,145
-20462,1516318097373,145
-20463,1516318292056,156
-20464,1516318320965,147
-20465,1516318506065,148
-20466,1516318616870,186
-20467,1516319583648,183
-20468,1516319951795,184
-20469,1516319998973,202
-20470,1516320037220,205
-20471,1516320365160,209
-20472,1516320959547,201
-20473,1516320997760,192
-20474,1516321043621,212
-20475,1516321065759,213
-20476,1516321306818,228
-20477,1516321632113,222
-20478,1516321740773,214
-20479,1516321759751,211
-20480,1516322223039,246
-20481,1516322449909,238
-20482,1516322896955,232
-20483,1516323083417,227
-20484,1516323148676,221
-20485,1516323179623,220
-20486,1516323407734,228
-20487,1516323745827,222
-20488,1516324080877,215
-20489,1516324803507,209
-20490,1516325053605,202
-20491,1516325087160,195
-20492,1516325555186,201
-20493,1516325785241,192
-20494,1516325885024,185
-20495,1516325906212,180
-20496,1516326055995,191
-20497,1516327060307,186
-20498,1516327443476,177
-20499,1516327726634,170
-20500,1516328109559,162
-20501,1516328199943,153
-20502,1516328218401,149
-20503,1516328488643,165
-20504,1516328842263,155
-20505,1516329130073,153
-20506,1516329170953,147
-20507,1516329373960,148
-20508,1516329456138,148
-20509,1516329474316,144
-20510,1516329541986,156
-20511,1516329577401,152
-20512,1516329656558,155
-20513,1516330166433,152
-20514,1516330182818,149
-20515,1516330414537,162
-20516,1516330427938,154
-20517,1516331008278,176
-20518,1516331271926,167
-20519,1516331300208,160
-20520,1516331370859,166
-20521,1516331394304,161
-20522,1516331456850,167
-20523,1516331514878,163
-20524,1516331588049,162
-20525,1516331676722,157
-20526,1516331788548,151
-20527,1516331972494,144
-20528,1516331978751,160
-20529,1516332298519,212
-20530,1516332603942,208
-20531,1516332773342,198
-20532,1516332853645,191
-20533,1516333139500,189
-20534,1516333152827,181
-20535,1516333239952,207
-20536,1516333437695,202
-20537,1516333891365,196
-20538,1516334038815,189
-20539,1516334059721,181
-20540,1516334314086,209
-20541,1516334782669,200
-20542,1516334870158,193
-20543,1516335031835,189
-20544,1516335315853,181
-20545,1516336396892,171
-20546,1516337224301,193
-20547,1516337557808,184
-20548,1516337665417,175
-20549,1516338158959,176
-20550,1516339038946,167
-20551,1516339108508,157
-20552,1516339405789,155
-20553,1516340007573,149
-20554,1516340011730,143
-20555,1516340313926,218
-20556,1516340339941,209
-20557,1516340587997,218
-20558,1516340663025,209
-20559,1516340669102,218
-20560,1516340860009,294
-20561,1516340975205,291
-20562,1516342616898,290
-20563,1516343419151,289
-20564,1516343467621,279
-20565,1516343771603,287
-20566,1516345085067,278
-20567,1516345742413,269
-20568,1516345775778,258
-20569,1516345846188,265
-20570,1516345970210,267
-20571,1516345983675,267
-20572,1516346132628,303
-20573,1516346201285,295
-20574,1516346488161,299
-20575,1516346581030,294
-20576,1516346886603,301
-20577,1516347189351,292
-20578,1516347215226,283
-20579,1516347497284,299
-20580,1516347849268,302
-20581,1516349207711,293
-20582,1516349555799,282
-20583,1516349680468,272
-20584,1516349782454,267
-20585,1516350205091,264
-20586,1516350544257,262
-20587,1516350839751,254
-20588,1516350860725,244
-20589,1516351040349,261
-20590,1516351191756,251
-20591,1516351576986,244
-20592,1516351652173,240
-20593,1516352113743,236
-20594,1516352712132,225
-20595,1516353005733,216
-20596,1516353070727,215
-20597,1516353237871,213
-20598,1516353407588,204
-20599,1516353475872,194
-20600,1516353612672,190
-20601,1516353665965,181
-20602,1516353837988,179
-20603,1516354076619,179
-20604,1516354109821,169
-20605,1516354330352,170
-20606,1516354353856,160
-20607,1516354561471,168
-20608,1516354651218,158
-20609,1516354659707,152
-20610,1516354675767,192
-20611,1516354743726,210
-20612,1516354869973,210
-20613,1516354885796,203
-20614,1516355090036,220
-20615,1516355315048,221
-20616,1516357605384,211
-20617,1516357882462,212
-20618,1516357938008,200
-20619,1516358028089,198
-20620,1516358160036,196
-20621,1516358599899,190
-20622,1516358678154,186
-20623,1516359196982,183
-20624,1516359524127,174
-20625,1516359809540,165
-20626,1516359949774,156
-20627,1516359963319,147
-20628,1516360183858,163
-20629,1516360231483,182
-20630,1516360274773,180
-20631,1516360416605,179
-20632,1516360516060,171
-20633,1516360593150,166
-20634,1516360688051,160
-20635,1516360770566,168
-20636,1516360975458,164
-20637,1516360979143,156
-20638,1516361231902,246
-20639,1516362596515,237
-20640,1516363437590,234
-20641,1516363568241,223
-20642,1516364449986,215
-20643,1516364639834,205
-20644,1516365144954,196
-20645,1516365250717,185
-20646,1516365826873,176
-20647,1516366248142,164
-20648,1516366296155,152
-20649,1516366408587,149
-20650,1516366633732,140
-20651,1516366795064,128
-20652,1516366895957,119
-20653,1516366983261,110
-20654,1516367198275,100
-20655,1516367330388,131
-20656,1516368048933,122
-20657,1516368632828,121
-20658,1516369144420,110
-20659,1516369223331,103
-20660,1516369256710,138
-20661,1516369292469,140
-20662,1516369387852,142
-20663,1516369758894,136
-20664,1516369812127,126
-20665,1516369877540,128
-20666,1516369982472,124
-20667,1516370444345,117
-20668,1516370586798,108
-20669,1516370679164,109
-20670,1516370768939,105
-20671,1516371052481,102
-20672,1516371132435,117
-20673,1516371238193,114
-20674,1516371634854,112
-20675,1516371791511,105
-20676,1516371807247,100
-20677,1516371843013,109
-20678,1516371916081,108
-20679,1516371991413,115
-20680,1516372095582,111
-20681,1516372175567,106
-20682,1516372234217,100
-20683,1516372338037,96
-20684,1516372410355,92
-20685,1516372443801,90
-20686,1516372523944,88
-20687,1516372532565,82
-20688,1516372592919,97
-20689,1516372628910,106
-20690,1516372761219,106
-20691,1516372896213,100
-20692,1516372924173,94
-20693,1516372970509,97
-20694,1516373099691,93
-20695,1516373224459,86
-20696,1516373363410,80
-20697,1516373416332,76
-20698,1516373501487,73
-20699,1516373648385,67
-20700,1516374157287,62
-20701,1516374187716,56
-20702,1516374264229,55
-20703,1516374349030,49
-20704,1516374495646,43
-20705,1516374508237,41
-20706,1516374694386,41
-20707,1516374805079,41
-20708,1516374946552,34
-20709,1516375162522,29
-20710,1516375173411,43
-20711,1516375180779,59
-20712,1516375395660,75
-20713,1516375411609,70
-20714,1516375541452,88
-20715,1516375907563,84
-20716,1516376007631,79
-20717,1516376020821,74
-20718,1516376086231,81
-20719,1516376102278,81
-20720,1516376209768,88
-20721,1516376312580,85
-20722,1516376572631,80
-20723,1516376630232,75
-20724,1516376937244,72
-20725,1516377069630,65
-20726,1516377098057,60
-20727,1516377136338,58
-20728,1516377238978,69
-20729,1516377334019,63
-20730,1516377346745,63
-20731,1516377353676,73
-20732,1516377444816,93
-20733,1516377599022,89
-20734,1516377656981,87
-20735,1516377809256,85
-20736,1516377963584,82
-20737,1516378102311,76
-20738,1516378258162,123
-20739,1516378375520,120
-20740,1516378465990,118
-20741,1516378543761,115
-20742,1516378663818,115
-20743,1516378697361,112
-20744,1516378856039,115
-20745,1516378862058,112
-20746,1516378918607,153
-20747,1516378967217,153
-20748,1516379000122,155
-20749,1516379698593,163
-20750,1516379724234,158
-20751,1516379851243,168
-20752,1516379998542,165
-20753,1516380088252,162
-20754,1516380353810,161
-20755,1516380389729,156
-20756,1516380474615,161
-20757,1516380867926,158
-20758,1516381106181,152
-20759,1516381460546,147
-20760,1516381958452,143
-20761,1516382255706,142
-20762,1516382625781,140
-20763,1516382814617,136
-20764,1517433080252,131
-20765,1517433576736,127
-20766,1517434075014,124
-20767,1517434458470,119
-20768,1517434985610,114
-20769,1517435345939,108
-20770,1517435548379,103
-20771,1517435837345,100
-20772,1517436673221,94
-20773,1517437317281,90
-20774,1517437399052,85
-20775,1517438118935,82
-20776,1517438471890,76
-20777,1517439081656,78
-20778,1517439801736,76
-20779,1517439976475,72
-20780,1517440125190,69
-20781,1517440271641,65
-20782,1517440321361,62
-20783,1517440423408,60
-20784,1517440671984,57
-20785,1517440879405,54
-20786,1517440951916,51
-20787,1517441018206,48
-20788,1517441218012,56
-20789,1517441377374,53
-20790,1517441443814,52
-20791,1517441502692,50
-20792,1517441575499,47
-20793,1517441625883,47
-20794,1517441700145,47
-20795,1517442065188,44
-20796,1517442429521,40
-20797,1517442530322,35
-20798,1517442697889,33
-20799,1517442877933,29
-20800,1517443011009,25
-20801,1517443201815,21
-20802,1517443391493,18
-20803,1517443513398,14
-20804,1517443613425,10
-20805,1517443690311,5
-20806,1517443706515,5
-20807,1517443718914,1
-20808,1517443738628,1
-20809,1517443757857,1
-20810,1517443766923,1
-20811,1517443775970,1
-20812,1517443784712,1
-20813,1517443793714,1
-20814,1517443802715,1
-20815,1517443815158,1
-20816,1517443824389,1
-20817,1517443833388,1
-20818,1517443842289,1
-20819,1517443851638,1
-20820,1517443860560,1
-20821,1517443869637,1
-20822,1517443878558,1
-20823,1517443887578,1
-20824,1517443899996,1
-20825,1517443912391,1
-20826,1517443921164,1
-20827,1517443930227,1
-20828,1517443946010,1
-20829,1517443961939,1
-20830,1517443970874,1
-20831,1517443980019,1
-20832,1517443989271,1
-20833,1517443998327,1
-20834,1517444007371,1
-20835,1517444016273,1
-20836,1517444025148,1
-20837,1517444034121,1
-20838,1517444042914,1
-20839,1517444052044,1
-20840,1517444067546,1
-20841,1517444076286,1
-20842,1517444085407,1
-20843,1517444094364,1
-20844,1517444103354,1
-20845,1517444112375,1
-20846,1517444121107,1
-20847,1517444130000,1
-20848,1517444139331,1
-20849,1517444151747,1
-20850,1517444161029,1
-20851,1517444173286,1
-20852,1517444182274,1
-20853,1517444191217,1
-20854,1517444200324,1
-20855,1517444209437,1
-20856,1517444218299,1
-20857,1517444227463,1
-20858,1517444236710,1
-20859,1517444245698,1
-20860,1517444254604,1
-20861,1517444270597,1
-20862,1517444279249,1
-20863,1517444288185,1
-20864,1517444297062,1
-20865,1517444305953,1
-20866,1517444314935,1
-20867,1517444324322,1
-20868,1517444333525,1
-20869,1517444342392,1
-20870,1517444354826,1
-20871,1517444363870,1
-20872,1517444376358,1
-20873,1517444385456,1
-20874,1517444394367,1
-20875,1517444406791,1
-20876,1517444415582,1
-20877,1517444424496,1
-20878,1517444440038,1
-20879,1517444449036,1
-20880,1517444458126,1
-20881,1517444467285,1
-20882,1517444476087,1
-20883,1517444488699,1
-20884,1517444501473,1
-20885,1517444510188,1
-20886,1517444522328,1
-20887,1517444531163,1
-20888,1517444543512,1
-20889,1517444552463,1
-20890,1517444561338,1
-20891,1517444570452,2
-20892,1517444579932,3
-20893,1517444592257,4
-20894,1517444601015,5
-20895,1517444617030,7
-20896,1517444673353,8
-20897,1517444723211,8
-20898,1517444790235,9
-20899,1517444812857,8
-20900,1517444863032,9
-20901,1517444905632,9
-20902,1517444938512,10
-20903,1517444974525,10
-20904,1517445034634,10
-20905,1517445084911,10
-20906,1517445100711,10
-20907,1517445139947,12
-20908,1517445206417,12
-20909,1517445263230,13
-20910,1517445292668,13
-20911,1517445305241,13
-20912,1517445317561,15
-20913,1517445329709,18
-20914,1517445345535,21
-20915,1517445418794,23
-20916,1517445537290,24
-20917,1517445718816,24
-20918,1517445890479,24
-20919,1517445960549,23
-20920,1517446023514,24
-20921,1517446076742,24
-20922,1517446102821,25
-20923,1517446199519,26
-20924,1517446290041,27
-20925,1517446400311,26
-20926,1517446487063,26
-20927,1517446526901,26
-20928,1517446579871,27
-20929,1517446666763,28
-20930,1517446767054,28
-20931,1517446904657,28
-20932,1517447027655,28
-20933,1517447080351,28
-20934,1517447204043,27
-20935,1517447334799,28
-20936,1517447404068,27
-20937,1517447477034,27
-20938,1517447536697,28
-20939,1517447599514,28
-20940,1517447706399,28
-20941,1517448115940,28
-20942,1517448459491,28
-20943,1517448621024,27
-20944,1517448697559,27
-20945,1517448709520,27
-20946,1517448826583,32
-20947,1517448957975,31
-20948,1517449062541,31
-20949,1517449204754,31
-20950,1517449387381,31
-20951,1517449612535,30
-20952,1517449760313,30
-20953,1517449809732,29
-20954,1517449913327,29
-20955,1517449977221,30
-20956,1517450131380,30
-20957,1517450167051,29
-20958,1517450185958,30
-20959,1517450231870,33
-20960,1517450274255,34
-20961,1517450330959,34
-20962,1517450421381,35
-20963,1517450497687,34
-20964,1517450679125,35
-20965,1517450854714,34
-20966,1517450891230,34
-20967,1517450940970,35
-20968,1517451170645,35
-20969,1517451572901,34
-20970,1517451816875,33
-20971,1517451901011,33
-20972,1517452177316,32
-20973,1517452447900,31
-20974,1517452681626,30
-20975,1517452926605,29
-20976,1517453007998,29
-20977,1517453080480,29
-20978,1517453227909,28
-20979,1517453339880,27
-20980,1517453418936,26
-20981,1517453563524,26
-20982,1517453731577,26
-20983,1517453927012,25
-20984,1517454054405,23
-20985,1517454089979,23
-20986,1517454257906,23
-20987,1517454475998,22
-20988,1517454560898,22
-20989,1517454592868,20
-20990,1517454625175,20
-20991,1517454640790,21
-20992,1517454693129,23
-20993,1517454748236,24
-20994,1517454763503,23
-20995,1517454835679,26
-20996,1517454924250,26
-20997,1517455073093,25
-20998,1517455308857,25
-20999,1517455622954,23
-21000,1517455787050,23
-21001,1517455812512,21
-21002,1517455854622,22
-21003,1517455909569,22
-21004,1517456064945,22
-21005,1517456209915,21
-21006,1517456268661,20
-21007,1517456324230,20
-21008,1517456336144,20
-21009,1517456502553,23
-21010,1517456628361,21
-21011,1517456727085,22
-21012,1517456894196,22
-21013,1517457125280,22
-21014,1517457289558,22
-21015,1517457351043,23
-21016,1517457425932,22
-21017,1517457494552,22
-21018,1517457526868,22
-21019,1517457638976,23
-21020,1517457767149,22
-21021,1517457846471,21
-21022,1517457912031,21
-21023,1517458036459,22
-21024,1517458172033,21
-21025,1517458194343,20
-21026,1517458289988,21
-21027,1517458378342,20
-21028,1517458463675,20
-21029,1517458532494,20
-21030,1517458594980,20
-21031,1517458640077,20
-21032,1517458655389,20
-21033,1517458667604,21
-21034,1517458749870,25
-21035,1517458825025,24
-21036,1517458894996,24
-21037,1517458957463,24
-21038,1517459112842,24
-21039,1517459241066,24
-21040,1517459279872,23
-21041,1517459328083,23
-21042,1517459360122,23
-21043,1517459448592,23
-21044,1517459537124,23
-21045,1517459549035,22
-21046,1517459604054,28
-21047,1517459672344,28
-21048,1517459728437,28
-21049,1517459940742,28
-21050,1517460151940,27
-21051,1517460304122,26
-21052,1517460489058,25
-21053,1517460551125,25
-21054,1517460593686,24
-21055,1517460688958,24
-21056,1517460774594,24
-21057,1517460833354,24
-21058,1517461030766,23
-21059,1517461235708,25
-21060,1517461307311,25
-21061,1517461394115,25
-21062,1517461459589,26
-21063,1517461488273,25
-21064,1517461520508,27
-21065,1517461579683,27
-21066,1517461635170,27
-21067,1517461699871,28
-21068,1517461777700,28
-21069,1517461898619,28
-21070,1517462024208,27
-21071,1517462174587,26
-21072,1517462428903,26
-21073,1517462576519,25
-21074,1517462704392,24
-21075,1517462845900,23
-21076,1517462951430,22
-21077,1517463039755,22
-21078,1517463115069,22
-21079,1517463236700,21
-21080,1517463311735,21
-21081,1517463380511,20
-21082,1517463442582,19
-21083,1517463507344,19
-21084,1517463582151,18
-21085,1517463640666,18
-21086,1517463708906,18
-21087,1517463747833,18
-21088,1517463774212,17
-21089,1517463800269,17
-21090,1517463855243,18
-21091,1517463903636,19
-21092,1517464015176,20
-21093,1517464136944,20
-21094,1517464169306,19
-21095,1517464197641,21
-21096,1517464213141,22
-21097,1517464228412,24
-21098,1517464336138,27
-21099,1517464480291,26
-21100,1517464558534,26
-21101,1517464594092,25
-21102,1517464612860,26
-21103,1517464652046,28
-21104,1517464876289,29
-21105,1517465269113,28
-21106,1517465490164,27
-21107,1517465684872,26
-21108,1517465875252,25
-21109,1517465904307,26
-21110,1517465959397,28
-21111,1517466054248,27
-21112,1517466260935,27
-21113,1517466490593,26
-21114,1517466585173,24
-21115,1517466620152,24
-21116,1517466718583,24
-21117,1517466846547,24
-21118,1517466918726,23
-21119,1517467007560,24
-21120,1517467105399,23
-21121,1517467209927,22
-21122,1517467324986,21
-21123,1517467413331,21
-21124,1517467455176,20
-21125,1517467589935,20
-21126,1517467725099,20
-21127,1517467859968,20
-21128,1517468014169,19
-21129,1517468062909,17
-21130,1517468071767,17
-21131,1517468156238,21
-21132,1517468211688,21
-21133,1517468251084,21
-21134,1517468322737,24
-21135,1517468414668,23
-21136,1517468608916,23
-21137,1517468804160,22
-21138,1517468859020,22
-21139,1517468897402,21
-21140,1517468922514,21
-21141,1517468991347,22
-21142,1517469124665,22
-21143,1517469240707,22
-21144,1517469380375,22
-21145,1517469517457,21
-21146,1517469573923,22
-21147,1517469648787,22
-21148,1517469723781,22
-21149,1517469813227,22
-21150,1517469979261,22
-21151,1517470129325,21
-21152,1517470245037,20
-21153,1517470350897,20
-21154,1517470398040,19
-21155,1517470414164,19
-21156,1517470459628,21
-21157,1517470509545,21
-21158,1517470549966,21
-21159,1517470568786,21
-21160,1517470593399,23
-21161,1517470618774,25
-21162,1517481727679,26
-21163,1517481809129,25
-21164,1517481858798,25
-21165,1517481931700,26
-21166,1517481994445,26
-21167,1517482026091,26
-21168,1517482271372,27
-21169,1517482375304,27
-21170,1517482406237,26
-21171,1517482532414,27
-21172,1517482772210,26
-21173,1517482879181,25
-21174,1517482958152,24
-21175,1517482990638,24
-21176,1517483012733,24
-21177,1517483187452,26
-21178,1517483363191,25
-21179,1517483398434,25
-21180,1517483467402,25
-21181,1517483522531,24
-21182,1517483571813,24
-21183,1517483627261,24
-21184,1517483720091,24
-21185,1517483801699,23
-21186,1517483852219,23
-21187,1517483903533,23
-21188,1517483921759,23
-21189,1517483993308,26
-21190,1517484045192,26
-21191,1517484062288,25
-21192,1517484079397,28
-21193,1517484124908,31
-21194,1517484208092,31
-21195,1517484329432,30
-21196,1517484583965,31
-21197,1517484816442,31
-21198,1517484864727,31
-21199,1517484916199,32
-21200,1517484963984,32
-21201,1517485012341,32
-21202,1517485063468,34
-21203,1517485122141,35
-21204,1517485304749,36
-21205,1517485467588,35
-21206,1517485548340,34
-21207,1517485632315,34
-21208,1517485678117,33
-21209,1517485745114,34
-21210,1517485827349,34
-21211,1517485869385,35
-21212,1517486031495,35
-21213,1517486166559,34
-21214,1517486248152,34
-21215,1517486324436,34
-21216,1517486585473,34
-21217,1517486836999,32
-21218,1517486874757,32
-21219,1517486939789,32
-21220,1517487000672,33
-21221,1517487061575,32
-21222,1517487212624,32
-21223,1517487334569,31
-21224,1517487353693,31
-21225,1517487461722,33
-21226,1517487660010,33
-21227,1517488000611,31
-21228,1517488416467,30
-21229,1517488587929,29
-21230,1517488730358,28
-21231,1517488812869,29
-21232,1517488856395,29
-21233,1517488906062,29
-21234,1517488983783,30
-21235,1517489198740,29
-21236,1517489203367,29
-21237,1517489312770,42
-21238,1517489442398,41
-21239,1517489577512,40
-21240,1517489644846,40
-21241,1517489745909,40
-21242,1517490162979,40
-21243,1517490612988,38
-21244,1517490781816,38
-21245,1517490806258,37
-21246,1517490837131,38
-21247,1517491003000,39
-21248,1517491149619,38
-21249,1517491186760,38
-21250,1517491314333,39
-21251,1517491668003,37
-21252,1517491996486,36
-21253,1517492058632,34
-21254,1517492266287,34
-21255,1517492371619,33
-21256,1517492619726,34
-21257,1517492956481,32
-21258,1517493126041,31
-21259,1517493194241,31
-21260,1517493266746,31
-21261,1517493397656,31
-21262,1517493468652,31
-21263,1517493612848,31
-21264,1517493733827,29
-21265,1517493851344,28
-21266,1517493935936,28
-21267,1517494103614,27
-21268,1517494235058,27
-21269,1517494311630,26
-21270,1517494427161,25
-21271,1517494547602,25
-21272,1517494608015,24
-21273,1517494675058,23
-21274,1517494712816,23
-21275,1517494923444,23
-21276,1517495043958,22
-21277,1517495231333,22
-21278,1517495297824,21
-21279,1517495331692,20
-21280,1517495410934,20
-21281,1517495473676,20
-21282,1517495492388,19
-21283,1517495586930,21
-21284,1517495685713,20
-21285,1517495706931,19
-21286,1517495716063,20
-21287,1517495775620,24
-21288,1517495851924,23
-21289,1517495926333,24
-21290,1517495988575,23
-21291,1517495999230,23
-21292,1517496057888,28
-21293,1517496122894,29
-21294,1517496176793,30
-21295,1517496306396,30
-21296,1517496413232,29
-21297,1517496436672,28
-21298,1517496517630,30
-21299,1517496593347,29
-21300,1517496648564,29
-21301,1517496680512,30
-21302,1517496721393,30
-21303,1517496853168,31
-21304,1517497022278,31
-21305,1517497137860,30
-21306,1517497197479,29
-21307,1517497307027,29
-21308,1517497408874,28
-21309,1517497488510,28
-21310,1517497617794,28
-21311,1517497784448,27
-21312,1517497879680,27
-21313,1517497913135,26
-21314,1517497959582,26
-21315,1517498058594,26
-21316,1517498119008,26
-21317,1517498131955,25
-21318,1517498378232,28
-21319,1517498511303,27
-21320,1517498621718,27
-21321,1517498678546,26
-21322,1517498735885,26
-21323,1517498836123,26
-21324,1517498926681,25
-21325,1517498971503,26
-21326,1517499153746,26
-21327,1517499281053,25
-21328,1517499327859,24
-21329,1517499365043,23
-21330,1517499426343,23
-21331,1517499480105,22
-21332,1517499713643,22
-21333,1517499931193,21
-21334,1517499939291,20
-21335,1517499950643,25
-21336,1517500014514,29
-21337,1517500074434,36
-21338,1517500152533,36
-21339,1517500200225,36
-21340,1517500231674,36
-21341,1517500378921,38
-21342,1517500737639,37
-21343,1517501005432,36
-21344,1517501329347,35
-21345,1517501686975,33
-21346,1517501760328,34
-21347,1517501875135,35
-21348,1517501966218,34
-21349,1517501984443,34
-21350,1517502061480,37
-21351,1517502134129,38
-21352,1517511077024,37
-21353,1517511145894,36
-21354,1517511225250,35
-21355,1517511413461,35
-21356,1517511548315,34
-21357,1517512379756,34
-21358,1517512479264,33
-21359,1517512618100,32
-21360,1517512836313,31
-21361,1517512984867,30
-21362,1517513018871,29
-21363,1517513129034,30
-21364,1517513261931,29
-21365,1517513305286,28
-21366,1517513333270,29
-21367,1517513458899,30
-21368,1517513730288,29
-21369,1517513894725,27
-21370,1517513988893,26
-21371,1517514003718,26
-21372,1517514066174,28
-21373,1517514134585,28
-21374,1517514158811,28
-21375,1517514208513,29
-21376,1517514290289,29
-21377,1517514374893,28
-21378,1517514601592,27
-21379,1517514800756,26
-21380,1517514856979,25
-21381,1517514903497,25
-21382,1517515010356,24
-21383,1517515101117,25
-21384,1517515150482,23
-21385,1517515269379,24
-21386,1517515366618,23
-21387,1517515461011,24
-21388,1517515571517,23
-21389,1517515614858,23
-21390,1517515635735,22
-21391,1517515659835,24
-21392,1517515705829,27
-21393,1517515816125,28
-21394,1517515926298,27
-21395,1517515960366,27
-21396,1517516013677,27
-21397,1517516100864,27
-21398,1517516233141,27
-21399,1517516355465,26
-21400,1517516427809,26
-21401,1517516575739,26
-21402,1517516701709,26
-21403,1517516726088,25
-21404,1517516776051,26
-21405,1517516857739,26
-21406,1517516914071,25
-21407,1517516932078,26
-21408,1517516950039,27
-21409,1517517171205,30
-21410,1517517398684,29
-21411,1517517803961,28
-21412,1517518212875,26
-21413,1517518237022,25
-21414,1517518355926,27
-21415,1517518434197,27
-21416,1517518589431,26
-21417,1517518847974,25
-21418,1517519005699,26
-21419,1517519033032,24
-21420,1517519070235,25
-21421,1517519166726,26
-21422,1517519238039,25
-21423,1517519253008,25
-21424,1517519270678,28
-21425,1517519314816,30
-21426,1517519339508,30
-21427,1517519385933,31
-21428,1517519454378,32
-21429,1517519529273,31
-21430,1517519581555,32
-21431,1517519680457,31
-21432,1517519830357,31
-21433,1517519954931,29
-21434,1517520026456,28
-21435,1517520056825,30
-21436,1517520104487,34
-21437,1517520109240,34
-21438,1517520176939,51
-21439,1517520285977,50
-21440,1517520372854,51
-21441,1517520432428,52
-21442,1517520481483,52
-21443,1517520540613,52
-21444,1517520624933,52
-21445,1517520755528,52
-21446,1517521154652,52
-21447,1517521458003,50
-21448,1517521504606,49
-21449,1517521682331,50
-21450,1517521860732,51
-21451,1517521903561,50
-21452,1517522158033,51
-21453,1517522226382,50
-21454,1517522278367,50
-21455,1517522506550,51
-21456,1517522899667,49
-21457,1517523187259,48
-21458,1517523336832,46
-21459,1517523445945,46
-21460,1517523551645,45
-21461,1517523587970,43
-21462,1517523615245,45
-21463,1517523649093,48
-21464,1517523761519,50
-21465,1517523988469,48
-21466,1517524124005,47
-21467,1517524191788,47
-21468,1517524418708,47
-21469,1517524619939,46
-21470,1517524691753,44
-21471,1517524728385,44
-21472,1517524793186,47
-21473,1517525097990,47
-21474,1517525428317,46
-21475,1517525559742,45
-21476,1517525631629,44
-21477,1517525662430,44
-21478,1517525856721,46
-21479,1517526116708,44
-21480,1517526191328,42
-21481,1517526413574,42
-21482,1517526589583,41
-21483,1517526948034,39
-21484,1517527314568,38
-21485,1517527345451,36
-21486,1517527436015,37
-21487,1517527554727,37
-21488,1517527645447,35
-21489,1517527794082,34
-21490,1517527891039,34
-21491,1517527953261,33
-21492,1517528115990,34
-21493,1517528240906,32
-21494,1517528252464,32
-21495,1517528323723,36
-21496,1517528559959,36
-21497,1517528741778,35
-21498,1517528766610,34
-21499,1517528799726,35
-21500,1517528845994,36
-21501,1517528895748,35
-21502,1517529018479,35
-21503,1517529185174,34
-21504,1517529272751,33
-21505,1517529303240,32
-21506,1517529334033,33
-21507,1517529513067,34
-21508,1517529704560,34
-21509,1517529756797,33
-21510,1517529797179,33
-21511,1517529878264,33
-21512,1517529969088,32
-21513,1517530018779,30
-21514,1517530074470,31
-21515,1517530158791,30
-21516,1517530287439,29
-21517,1517530397305,28
-21518,1517530471953,26
-21519,1517530546615,25
-21520,1517530649357,24
-21521,1517530743010,23
-21522,1517530811335,22
-21523,1517530857753,21
-21524,1517530885297,22
-21525,1517530915830,23
-21526,1517531032165,24
-21527,1517531177008,23
-21528,1517531238878,23
-21529,1517531269404,22
-21530,1517531335769,22
-21531,1517531398443,22
-21532,1517531416225,20
-21533,1517531472245,21
-21534,1517531528068,20
-21535,1517531618707,19
-21536,1517531709232,19
-21537,1517531762046,18
-21538,1517531833616,25
-21539,1517531876482,25
-21540,1517531894602,25
-21541,1517531937845,28
-21542,1517531990371,28
-21543,1517532017915,29
-21544,1517532035928,30
-21545,1517532139882,34
-21546,1517532312676,33
-21547,1517532425519,31
-21548,1517532525219,30
-21549,1517532741520,30
-21550,1517533009489,29
-21551,1517533129029,27
-21552,1517533204057,28
-21553,1517533285128,27
-21554,1517533337399,27
-21555,1517533396782,27
-21556,1517533456256,27
-21557,1517533568698,26
-21558,1517533650057,25
-21559,1517533705729,25
-21560,1517533783351,24
-21561,1517533861361,24
-21562,1517533932948,24
-21563,1517533991328,25
-21564,1517534082573,26
-21565,1517534148333,25
-21566,1517534302978,24
-21567,1517534494752,24
-21568,1517534551743,23
-21569,1517534569023,22
-21570,1517534628672,24
-21571,1517534697015,24
-21572,1517534743605,25
-21573,1517534805354,25
-21574,1517534886458,24
-21575,1517534964311,24
-21576,1517535107824,23
-21577,1517535220842,23
-21578,1517535260976,23
-21579,1517535317054,23
-21580,1517535341174,23
-21581,1517535444646,24
-21582,1517535522639,23
-21583,1517535578726,22
-21584,1517535635144,21
-21585,1517535687726,21
-21586,1517535852061,22
-21587,1517535993434,21
-21588,1517536027832,19
-21589,1517536045918,19
-21590,1517536149763,21
-21591,1517536281409,20
-21592,1517536353549,20
-21593,1517536432515,18
-21594,1517536524055,18
-21595,1517536564396,20
-21596,1517536626879,20
-21597,1517536679861,19
-21598,1517536713881,18
-21599,1517536744158,20
-21600,1517536781055,22
-21601,1517536811386,22
-21602,1517536848096,23
-21603,1517536920246,24
-21604,1517537036168,23
-21605,1517537120388,22
-21606,1517537154139,22
-21607,1517537266682,24
-21608,1517537350486,23
-21609,1517537444277,23
-21610,1517537499907,22
-21611,1517537530277,23
-21612,1517537605140,24
-21613,1517537707875,24
-21614,1517537776042,23
-21615,1517537794060,23
-21616,1517537957016,25
-21617,1517538114014,24
-21618,1517538131971,24
-21619,1517538168631,25
-21620,1517538259711,26
-21621,1517538325766,25
-21622,1517538460914,25
-21623,1517538605866,24
-21624,1517538655582,23
-21625,1517538717770,24
-21626,1517538913108,24
-21627,1517539060862,23
-21628,1517539088581,22
-21629,1517539157372,23
-21630,1517539239576,23
-21631,1517539308634,23
-21632,1517539446319,22
-21633,1517539558626,23
-21634,1517539576673,22
-21635,1517539585122,24
-21636,1517539631601,29
-21637,1517539725275,29
-21638,1517539831547,29
-21639,1517539893533,29
-21640,1517539980549,28
-21641,1517540061219,30
-21642,1517540161131,29
-21643,1517540298371,29
-21644,1517540385545,30
-21645,1517540409730,30
-21646,1517540427745,33
-21647,1517540477740,36
-21648,1517540590975,37
-21649,1517540712734,36
-21650,1517540850004,35
-21651,1517541067947,34
-21652,1517541196611,33
-21653,1517541300325,33
-21654,1517541441524,32
-21655,1517541539453,32
-21656,1517541556746,31
-21657,1517541612404,34
-21658,1517541718504,35
-21659,1517541789986,35
-21660,1517541810984,34
-21661,1517541870069,37
-21662,1517542046793,37
-21663,1517542258088,36
-21664,1517542380642,35
-21665,1517542449000,35
-21666,1517542492024,35
-21667,1517542513400,35
-21668,1517542622296,37
-21669,1517542744472,37
-21670,1517542775035,37
-21671,1517542986876,39
-21672,1517543204253,39
-21673,1517543288151,37
-21674,1517543448270,37
-21675,1517543666060,36
-21676,1517543807577,35
-21677,1517543891730,34
-21678,1517543995022,33
-21679,1517544034939,34
-21680,1517544059307,34
-21681,1517544099863,37
-21682,1517544187773,38
-21683,1517544354810,37
-21684,1517544566328,36
-21685,1517544748823,36
-21686,1517544839882,35
-21687,1517544899080,34
-21688,1517544964619,34
-21689,1517545084377,34
-21690,1517545184771,34
-21691,1517545348377,33
-21692,1517545518754,33
-21693,1517545575723,31
-21694,1517545631747,31
-21695,1517545659049,31
-21696,1517545733851,32
-21697,1517545888193,32
-21698,1517545995047,31
-21699,1517546022414,30
-21700,1517546053189,31
-21701,1517546153881,33
-21702,1517546473531,33
-21703,1517546746378,32
-21704,1517546833763,31
-21705,1517546911913,30
-21706,1517546955350,30
-21707,1517547115954,30
-21708,1517547330256,29
-21709,1517547417994,28
-21710,1517547454898,27
-21711,1517547529802,28
-21712,1517547627727,28
-21713,1517547696799,27
-21714,1517547739894,26
-21715,1517547903184,26
-21716,1517548054708,26
-21717,1517548107521,25
-21718,1517548216795,25
-21719,1517548298344,25
-21720,1517548322832,25
-21721,1517548413482,26
-21722,1517548555309,25
-21723,1517548693300,24
-21724,1517548837127,23
-21725,1517548971830,22
-21726,1517549087896,21
-21727,1517549206243,20
-21728,1517549321731,19
-21729,1517549377914,18
-21730,1517549437192,17
-21731,1517549505748,17
-21732,1517549548923,17
-21733,1517549596211,16
-21734,1517549632974,15
-21735,1517549654095,15
-21736,1517549703586,19
-21737,1517549791144,19
-21738,1517549901027,18
-21739,1517549966177,17
-21740,1517549977722,17
-21741,1517549992558,19
-21742,1517550004098,21
-21743,1517550018961,24
-21744,1517550030390,27
-21745,1517550064469,31
-21746,1517550123858,32
-21747,1517550198344,34
-21748,1517550297973,34
-21749,1517550410318,34
-21750,1517550545561,33
-21751,1517550724598,32
-21752,1517550876267,31
-21753,1517550953518,30
-21754,1517550984066,30
-21755,1517551068272,31
-21756,1517551277603,29
-21757,1517551438027,30
-21758,1517551513191,30
-21759,1517551594315,29
-21760,1517551665884,28
-21761,1517551797894,30
-21762,1517551954694,29
-21763,1517552070549,29
-21764,1517552136426,28
-21765,1517552163551,27
-21766,1517552190761,29
-21767,1517552246667,31
-21768,1517552309551,32
-21769,1517552358688,32
-21770,1517552494061,32
-21771,1517552776987,32
-21772,1517552984926,31
-21773,1517553062685,30
-21774,1517553159715,30
-21775,1517553243301,30
-21776,1517553326914,28
-21777,1517553360377,28
-21778,1517553388164,29
-21779,1517553512434,30
-21780,1517553766042,30
-21781,1517553996623,30
-21782,1517554093111,30
-21783,1517554167845,30
-21784,1517554230168,30
-21785,1517554292825,29
-21786,1517554399738,28
-21787,1517554561509,28
-21788,1517554715590,28
-21789,1517554796957,27
-21790,1517554848341,26
-21791,1517554951168,27
-21792,1517555036029,25
-21793,1517555085135,25
-21794,1517555103611,26
-21795,1517555123530,28
-21796,1517555216181,31
-21797,1517555293919,30
-21798,1517555419961,30
-21799,1517555522518,29
-21800,1517555615187,30
-21801,1517555700773,30
-21802,1517555781236,29
-21803,1517555918600,29
-21804,1517556028392,28
-21805,1517556146738,27
-21806,1517556303675,27
-21807,1517556418247,26
-21808,1517556478858,25
-21809,1517556510398,25
-21810,1517556721779,25
-21811,1517557114622,25
-21812,1517557277423,24
-21813,1517557352734,23
-21814,1517557416402,23
-21815,1517557469797,23
-21816,1517557559446,22
-21817,1517557630562,21
-21818,1517557669133,21
-21819,1517557722297,21
-21820,1517557754369,21
-21821,1517557792742,22
-21822,1517557840887,22
-21823,1517557878707,21
-21824,1517557907981,22
-21825,1517557931004,22
-21826,1517557972015,23
-21827,1517558036972,23
-21828,1517558096325,22
-21829,1517558122493,22
-21830,1517558255714,22
-21831,1517558329724,21
-21832,1517558419719,21
-21833,1517558513762,20
-21834,1517558552100,19
-21835,1517558626501,19
-21836,1517558710296,18
-21837,1517558802798,18
-21838,1517558877319,17
-21839,1517558912113,16
-21840,1517559183441,16
-21841,1517559206565,16
-21842,1517559258136,17
-21843,1517559309506,18
-21844,1517564007393,20
-21845,1517564093132,22
-21846,1517564145826,21
-21847,1517564206761,22
-21848,1517564244311,22
-21849,1517564333941,22
-21850,1517564395040,21
-21851,1517564596675,21
-21852,1517564627903,20
-21853,1517564707517,21
-21854,1517564803786,21
-21855,1517564820613,21
-21856,1517564877162,23
-21857,1517564904882,23
-21858,1517564930230,23
-21859,1517564977050,25
-21860,1517565134592,25
-21861,1517565146555,24
-21862,1517565235907,28
-21863,1517565305846,27
-21864,1517565328058,26
-21865,1517565366718,28
-21866,1517565402529,30
-21867,1517565422246,32
-21868,1517565431061,35
-21869,1517565447883,43
-21870,1517565525115,48
-21871,1517565565883,48
-21872,1517565652386,50
-21873,1517565716278,50
-21874,1517565779933,49
-21875,1517565789181,50
-21876,1517565795600,61
-21877,1517565915442,82
-21878,1517565954408,83
-21879,1517566011603,87
-21880,1517566142319,89
-21881,1517566489596,87
-21882,1517566570036,86
-21883,1517566584540,86
-21884,1517566911836,99
-21885,1517567164013,97
-21886,1517567319247,96
-21887,1517567384079,95
-21888,1517567409663,95
-21889,1517567468793,102
-21890,1517567592219,104
-21891,1517567806935,103
-21892,1517567981008,102
-21893,1517568030530,101
-21894,1517568336521,103
-21895,1517568357211,102
-21896,1517568559111,113
-21897,1517568574099,112
-21898,1517568601733,127
-21899,1517569038501,134
-21900,1517569072659,132
-21901,1517569262001,138
-21902,1517569325682,137
-21903,1517569431276,138
-21904,1517569446146,138
-21905,1517569901865,156
-21906,1517570125471,154
-21907,1517570574373,151
-21908,1517570594376,149
-21909,1517570608979,162
-21910,1517570626089,185
-21911,1517571187910,207
-21912,1517571323217,203
-21913,1517571456375,201
-21914,1517571701473,200
-21915,1517571859906,196
-21916,1517572173301,195
-21917,1517572389874,192
-21918,1517572393665,189
-21919,1517572649270,304
-21920,1517572910042,300
-21921,1517573126201,296
-21922,1517574120473,293
-21923,1517574689769,287
-21924,1517574962557,281
-21925,1517575138731,277
-21926,1517576050401,275
-21927,1517576134411,269
-21928,1517576652182,271
-21929,1517577418755,265
-21930,1517577785397,259
-21931,1517577932149,253
-21932,1517578258604,250
-21933,1517578876413,245
-21934,1517578885608,239
-21935,1517579154750,295
-21936,1517579789371,289
-21937,1517581326849,282
-21938,1517581909890,275
-21939,1517582051011,267
-21940,1517582356807,264
-21941,1517583047423,258
-21942,1517583271007,250
-21943,1517583433575,245
-21944,1517584892389,241
-21945,1517585163525,232
-21946,1517585440802,226
-21947,1517585568031,220
-21948,1517586042745,216
-21949,1517586970894,209
-21950,1517587269893,201
-21951,1517587335554,195
-21952,1517587466794,193
-21953,1517587727220,189
-21954,1517587944512,182
-21955,1517588177650,175
-21956,1517588186938,170
-21957,1517588234667,205
-21958,1517588268367,207
-21959,1517588808836,213
-21960,1517589158102,206
-21961,1517589216728,197
-21962,1517589785762,198
-21963,1517590114535,189
-21964,1517590118427,181
-21965,1517590212065,284
-21966,1517590480207,281
-21967,1517590539767,272
-21968,1517590887002,274
-21969,1517591264837,269
-21970,1517591349363,263
-21971,1517591943138,259
-21972,1517592325802,250
-21973,1517592406292,241
-21974,1517592777015,237
-21975,1517593000819,228
-21976,1517593423647,226
-21977,1517593750223,227
-21978,1517593843590,218
-21979,1517594551522,215
-21980,1517594670689,206
-21981,1517594741098,201
-21982,1517594966410,197
-21983,1517595107336,189
-21984,1517595148727,188
-21985,1517595344498,188
-21986,1517595374730,179
-21987,1517595643218,183
-21988,1517596109003,175
-21989,1517596739209,169
-21990,1517596780849,161
-21991,1517596961151,160
-21992,1517597150732,151
-21993,1517597178194,142
-21994,1517597350040,146
-21995,1517597367141,136
-21996,1517597763862,151
-21997,1517597818735,140
-21998,1517597825269,143
-21999,1517597944037,190
-22000,1517598020704,183
-22001,1517598271747,181
-22002,1517598295306,172
-22003,1517598488858,180
-22004,1517598777145,171
-22005,1517599206699,171
-22006,1517599262753,162
-22007,1517599489857,157
-22008,1517599510126,147
-22009,1517599546818,162
-22010,1517599703446,174
-22011,1517600148559,178
-22012,1517600702662,168
-22013,1517600824632,159
-22014,1517600844473,153
-22015,1517600932494,160
-22016,1517600990740,155
-22017,1517601111359,151
-22018,1517601586689,143
-22019,1517601838137,194
-22020,1517601900660,187
-22021,1517602589256,186
-22022,1517603184088,177
-22023,1517604225238,169
-22024,1517604291002,160
-22025,1517604467843,157
-22026,1517604834795,152
-22027,1517605203354,143
-22028,1517605518435,137
-22029,1517605652946,129
-22030,1517605921861,122
-22031,1517606450934,114
-22032,1517606666394,107
-22033,1517606770757,99
-22034,1517606947878,92
-22035,1517607093325,116
-22036,1517607246157,110
-22037,1517607682237,103
-22038,1517607713563,95
-22039,1517607747179,94
-22040,1517608051626,94
-22041,1517608250469,86
-22042,1517608394665,80
-22043,1517608482556,73
-22044,1517608550444,68
-22045,1517608581716,62
-22046,1517608794862,58
-22047,1517608812142,50
-22048,1517608824463,51
-22049,1517608844191,52
-22050,1517608858798,50
-22051,1517608879218,49
-22052,1517608891012,49
-22053,1517608943173,52
-22054,1517609014490,46
-22055,1517609072011,38
-22056,1517609270293,31
-22057,1517609285141,46
-22058,1517609391103,49
-22059,1517609443415,49
-22060,1517609473790,43
-22061,1517609506911,39
-22062,1517609546163,37
-22063,1517609716391,31
-22064,1517609741732,23
-22065,1517609761158,75
-22066,1517609767680,81
-22067,1517609985445,105
-22068,1517609997517,104
-22069,1517610046771,119
-22070,1517610370609,118
-22071,1517610600134,116
-22072,1517610638644,110
-22073,1517610645406,110
-22074,1517610657356,145
-22075,1517610922204,167
-22076,1517611101640,161
-22077,1517611809229,156
-22078,1517612157447,149
-22079,1517612164021,145
-22080,1517612170606,190
-22081,1517612471232,252
-22082,1517613187006,247
-22083,1517613547321,239
-22084,1517613896379,232
-22085,1517613916341,230
-22086,1517614032870,248
-22087,1517614581342,250
-22088,1517614730080,242
-22089,1517615628697,236
-22090,1517616252889,227
-22091,1517616256531,223
-22092,1517616735730,361
-22093,1517617156705,351
-22094,1517618337203,348
-22095,1517618720885,337
-22096,1517619349467,338
-22097,1517621231142,327
-22098,1517621285881,319
-22099,1517621300063,349
-22100,1517621762293,399
-22101,1517623078211,391
-22102,1517623262835,381
-22103,1517624058649,384
-22104,1517625642490,374
-22105,1517626130272,364
-22106,1517626428632,354
-22107,1517626766686,349
-22108,1517627067330,341
-22109,1517627468954,341
-22110,1517627595715,338
-22111,1517628504111,334
-22112,1517628582067,323
-22113,1517628785419,323
-22114,1517628875975,317
-22115,1517629530953,323
-22116,1517630234829,316
-22117,1517630506129,308
-22118,1517630770815,302
-22119,1517631095277,294
-22120,1517631920367,285
-22121,1517632924291,279
-22122,1517633203335,269
-22123,1517633434838,260
-22124,1517633516221,252
-22125,1517634002562,251
-22126,1517634214058,242
-22127,1517634590493,234
-22128,1517634950440,225
-22129,1517635134690,216
-22130,1517635537287,209
-22131,1517635826605,200
-22132,1517635949094,190
-22133,1517636188708,183
-22134,1517636507435,175
-22135,1517636716747,165
-22136,1517636748353,157
-22137,1517636789797,158
-22138,1517637245004,156
-22139,1517637391516,149
-22140,1517637627073,143
-22141,1517637707548,134
-22142,1517637850872,128
-22143,1517638041859,119
-22144,1517638600432,110
-22145,1517638647357,100
-22146,1517638786406,96
-22147,1517638973387,87
-22148,1517638993061,80
-22149,1517639152065,84
-22150,1517639204283,77
-22151,1517639248934,74
-22152,1517639412086,69
-22153,1517639542934,63
-22154,1517639546661,55
-22155,1517639561365,80
-22156,1517639733534,83
-22157,1517639771395,72
-22158,1517639929720,69
-22159,1517640076887,59
-22160,1517640091663,49
-22161,1517640095804,48
-22162,1517640147303,65
-22163,1517640248640,57
-22164,1517640371095,46
-22165,1517640385676,36
-22166,1517640461302,35
-22167,1517640484043,39
-22168,1517640711075,32
-22169,1517640750235,31
-22170,1517640789232,25
-22171,1517640806035,16
-22172,1517640812809,7
-22173,1517640822111,2
-22174,1517640826208,11
-22175,1517640838375,22
-22176,1517640849998,17
-22177,1517640856471,11
-22178,1517640877137,4
-22179,1517640889036,1
-22180,1517640893094,13
-22181,1517640940857,46
-22182,1517640993059,41
-22183,1517641035067,34
-22184,1517641279602,28
-22185,1517641291358,20
-22186,1517641303088,31
-22187,1517641366478,31
-22188,1517641375348,25
-22189,1517641384216,25
-22190,1517641464979,23
-22191,1517641479328,15
-22192,1517641482955,86
-22193,1517641518730,137
-22194,1517641652301,140
-22195,1517641944887,136
-22196,1517642265588,130
-22197,1517642431704,125
-22198,1517642515086,120
-22199,1517643135123,123
-22200,1517643214497,147
-22201,1517643221094,146
-22202,1517643607560,193
-22203,1517643974740,189
-22204,1517644053993,185
-22205,1517644350229,183
-22206,1517644498974,178
-22207,1517644585427,176
-22208,1517644774693,175
-22209,1517644837176,171
-22210,1517644917274,171
-22211,1517644929492,173
-22212,1517645581858,201
-22213,1517645845761,199
-22214,1517645863106,195
-22215,1517646228084,218
-22216,1517646689336,212
-22217,1517646754141,207
-22218,1517647101099,208
-22219,1517647909677,203
-22220,1517647922116,197
-22221,1517648300755,227
-22222,1517648799212,221
-22223,1517649558957,214
-22224,1517649944341,208
-22225,1517650213614,205
-22226,1517651046581,199
-22227,1517651218684,192
-22228,1517651270814,188
-22229,1517651559829,189
-22230,1517652036313,183
-22231,1517652199224,176
-22232,1517652235182,172
-22233,1517653300390,177
-22234,1517653362304,170
-22235,1517653531688,168
-22236,1517653647568,163
-22237,1517653715102,165
-22238,1517654399796,166
-22239,1517654661007,159
-22240,1517654836396,154
-22241,1517654928330,148
-22242,1517654999294,146
-22243,1517655598645,143
-22244,1517655647547,136
-22245,1517655746984,135
-22246,1517655829754,132
-22247,1517655916483,128
-22248,1517656073899,124
-22249,1517656181329,123
-22250,1517656341613,117
-22251,1517656526037,113
-22252,1517656704218,108
-22253,1517656726992,101
-22254,1517656733671,105
-22255,1517656751298,151
-22256,1517657053533,170
-22257,1517657102194,164
-22258,1517657471929,165
-22259,1517657491722,158
-22260,1517657509198,169
-22261,1517657699271,188
-22262,1517658375106,195
-22263,1517658460278,189
-22264,1517658783095,186
-22265,1517658818302,179
-22266,1517658846393,185
-22267,1517659408018,192
-22268,1517659572565,186
-22269,1517659705771,180
-22270,1517659753054,174
-22271,1517659897667,176
-22272,1517660233224,170
-22273,1517660433749,163
-22274,1517660566984,156
-22275,1517660807522,153
-22276,1517660841461,147
-22277,1517660966150,151
-22278,1517661350440,146
-22279,1517661950360,138
-22280,1517662395643,129
-22281,1517663209223,125
-22282,1517663265317,117
-22283,1517663589054,114
-22284,1517663608962,106
-22285,1517663642853,110
-22286,1517663729648,111
-22287,1517664077372,107
-22288,1517664111299,100
-22289,1517664821407,100
-22290,1517665021194,95
-22291,1517665457504,87
-22292,1517665579250,80
-22293,1517665612425,101
-22294,1517665619068,105
-22295,1517665718574,136
-22296,1517665860168,131
-22297,1517665902258,124
-22298,1517665993738,123
-22299,1517666421380,120
-22300,1517666519547,111
-22301,1517666739359,107
-22302,1517666761745,127
-22303,1517666787001,132
-22304,1517666923151,137
-22305,1517667034029,134
-22306,1517667224651,128
-22307,1517667528566,123
-22308,1517667804071,118
-22309,1517668132919,112
-22310,1517668264462,107
-22311,1517668399585,104
-22312,1517668593325,114
-22313,1517668691674,109
-22314,1517668720271,104
-22315,1517668811191,119
-22316,1517669088306,115
-22317,1517669391911,109
-22318,1517669566941,106
-22319,1517669694300,101
-22320,1517669746906,96
-22321,1517670085568,112
-22322,1517670142053,106
-22323,1517670370074,104
-22324,1517670406780,98
-22325,1517670668559,99
-22326,1517670759862,93
-22327,1517670928298,89
-22328,1517671048287,84
-22329,1517671084880,83
-22330,1517671145754,82
-22331,1517671171164,79
-22332,1517671251617,80
-22333,1517671440910,81
-22334,1517671659909,76
-22335,1517671724805,73
-22336,1517671904447,70
-22337,1517672041837,65
-22338,1517672119749,63
-22339,1517672188602,58
-22340,1517672311469,54
-22341,1517672368133,49
-22342,1517672377260,46
-22343,1517672428086,54
-22344,1517672622997,50
-22345,1517672658903,47
-22346,1517672725240,44
-22347,1517672739680,41
-22348,1517672819673,43
-22349,1517672956025,38
-22350,1517673022560,33
-22351,1517673123187,28
-22352,1517673200179,23
-22353,1517673279144,17
-22354,1517673296997,17
-22355,1517673371075,32
-22356,1517673445369,37
-22357,1517673557839,33
-22358,1517673648437,31
-22359,1517673660389,27
-22360,1517673672428,37
-22361,1517673735700,51
-22362,1517674034917,48
-22363,1517674142598,44
-22364,1517674350846,42
-22365,1517674463330,38
-22366,1517674596372,40
-22367,1517674667121,44
-22368,1517674671098,41
-22369,1517674710234,62
-22370,1517674759711,62
-22371,1517674801308,65
-22372,1517674886309,65
-22373,1517674895198,62
-22374,1517674918262,74
-22375,1517674995739,78
-22376,1517675084018,76
-22377,1517675208951,78
-22378,1517675512621,76
-22379,1517675543180,72
-22380,1517675549895,72
-22381,1517675553471,93
-22382,1517675989565,150
-22383,1517676039018,146
-22384,1517676081473,148
-22385,1517676541853,155
-22386,1517676746941,154
-22387,1517676934975,150
-22388,1517677052567,147
-22389,1517677238626,146
-22390,1517678690856,142
-22391,1517678801708,136
-22392,1517678893121,132
-22393,1517679038269,130
-22394,1517679073530,130
-22395,1517679360704,151
-22396,1517679435371,149
-22397,1517679632836,148
-22398,1517679812145,148
-22399,1517679893757,146
-22400,1517680219898,145
-22401,1517680772202,140
-22402,1517680864963,136
-22403,1517681458065,141
-22404,1517681621055,141
-22405,1517681681972,139
-22406,1517681829239,141
-22407,1517681846563,138
-22408,1517681906406,152
-22409,1517681963706,152
-22410,1517682102893,154
-22411,1517682188401,151
-22412,1517682381424,150
-22413,1517682438835,146
-22414,1517682852618,148
-22415,1517682886395,147
-22416,1517683261308,152
-22417,1517683360988,148
-22418,1517683397239,146
-22419,1517683877493,150
-22420,1517683970651,145
-22421,1517684001619,145
-22422,1517684322679,150
-22423,1517684367225,147
-22424,1517684718184,149
-22425,1517684848977,147
-22426,1517684923376,144
-22427,1517685000053,143
-22428,1517685149352,141
-22429,1517685223103,138
-22430,1517685393198,138
-22431,1517685658827,135
-22432,1517685673194,135
-22433,1517685903709,151
-22434,1517685981973,147
-22435,1517686014452,145
-22436,1517686020858,150
-22437,1517686673350,200
-22438,1517686714675,194
-22439,1517686802956,197
-22440,1517686826688,196
-22441,1517686961204,209
-22442,1517687729954,205
-22443,1517687796281,204
-22444,1517687989680,204
-22445,1517688356935,199
-22446,1517688602899,193
-22447,1517688846724,188
-22448,1517689638792,185
-22449,1517689800758,178
-22450,1517690082930,173
-22451,1517690348994,167
-22452,1517690520520,161
-22453,1517690615740,155
-22454,1517690637678,151
-22455,1517690769198,160
-22456,1517691167350,155
-22457,1517691460595,148
-22458,1517691576793,141
-22459,1517691831716,136
-22460,1517692100667,132
-22461,1517692104455,129
-22462,1517692284463,203
-22463,1517693101090,197
-22464,1517693121356,188
-22465,1517693948861,201
-22466,1517694075954,192
-22467,1517694501637,186
-22468,1517694676915,178
-22469,1517694773065,183
-22470,1517694816956,179
-22471,1517695576036,181
-22472,1517695744370,174
-22473,1517695840931,168
-22474,1517695938300,171
-22475,1517696004274,170
-22476,1517696029382,167
-22477,1517696424433,175
-22478,1517696446787,167
-22479,1517696469767,176
-22480,1517696546582,187
-22481,1517696655216,196
-22482,1517696702416,223
-22483,1517696722590,226
-22484,1517697128122,247
-22485,1517697595256,243
-22486,1517697697945,235
-22487,1517698024295,232
-22488,1517698219114,226
-22489,1517698574388,221
-22490,1517698697635,213
-22491,1517698718003,209
-22492,1517700034565,225
-22493,1517701426555,217
-22494,1517701543686,209
-22495,1517702039920,208
-22496,1517702718792,200
-22497,1517703128232,194
-22498,1517703363638,186
-22499,1517704123639,179
-22500,1517704817528,173
-22501,1517705047855,165
-22502,1517705176324,156
-22503,1517706305138,152
-22504,1517706438952,143
-22505,1517706462211,137
-22506,1517706858246,145
-22507,1517707663994,137
-22508,1517707886931,138
-22509,1517708131309,134
-22510,1517708515501,128
-22511,1517708737847,122
-22512,1517709053008,115
-22513,1517709118998,108
-22514,1517709225798,106
-22515,1517709345511,100
-22516,1517709352423,99
-22517,1517709386758,124
-22518,1517709406298,126
-22519,1517709671259,136
-22520,1517709994903,128
-22521,1517710046797,122
-22522,1517710160682,123
-22523,1517710186794,117
-22524,1517710286422,122
-22525,1517710300536,116
-22526,1517711342152,127
-22527,1517711588197,120
-22528,1517711876955,114
-22529,1517711888882,106
-22530,1517712233709,120
-22531,1517712261844,112
-22532,1517712352549,112
-22533,1517712665977,116
-22534,1517712716043,108
-22535,1517712768787,106
-22536,1517712861067,107
-22537,1517713089519,129
-22538,1517713169968,121
-22539,1517713295160,122
-22540,1517713387753,118
-22541,1517713880489,123
-22542,1517714115717,117
-22543,1517714387643,110
-22544,1517714472854,106
-22545,1517714659964,102
-22546,1517714668682,96
-22547,1517714710269,114
-22548,1517714782875,114
-22549,1517714900071,108
-22550,1517714961255,103
-22551,1517715173793,99
-22552,1517715519250,92
-22553,1517715710319,85
-22554,1517715743966,79
-22555,1517715828313,85
-22556,1517715937211,80
-22557,1517715954520,74
-22558,1517716025334,76
-22559,1517716145172,71
-22560,1517716292321,64
-22561,1517716484324,57
-22562,1517716605415,91
-22563,1517717079974,87
-22564,1517717134012,80
-22565,1517717419882,87
-22566,1517717573268,81
-22567,1517717734795,77
-22568,1517718043265,71
-22569,1517718058126,66
-22570,1517718176584,72
-22571,1517718232764,71
-22572,1517718456398,67
-22573,1517718595541,61
-22574,1517718609736,58
-22575,1517718663506,63
-22576,1517718745450,61
-22577,1517718813315,65
-22578,1517718997738,60
-22579,1517719022825,63
-22580,1517719215266,72
-22581,1517719241012,70
-22582,1517719306139,72
-22583,1517719382014,73
-22584,1517719420909,84
-22585,1517719488179,83
-22586,1517719525235,81
-22587,1517719540069,83
-22588,1517719746734,91
-22589,1517720342403,88
-22590,1517720421490,83
-22591,1517720501309,81
-22592,1517720529236,89
-22593,1517720557508,92
-22594,1517720561237,94
-22595,1517720614130,151
-22596,1517720799610,151
-22597,1517721603803,147
-22598,1517721909006,140
-22599,1517722147175,135
-22600,1517722217171,130
-22601,1517722372997,127
-22602,1517722395989,124
-22603,1517722473336,131
-22604,1517722598844,128
-22605,1517722640409,124
-22606,1517722968186,132
-22607,1517723133057,126
-22608,1517723498375,121
-22609,1517723663702,115
-22610,1517723776578,110
-22611,1517723880645,105
-22612,1517723903371,101
-22613,1517723912714,105
-22614,1517723946266,127
-22615,1517723963450,129
-22616,1517724135119,141
-22617,1517724411551,152
-22618,1517724543976,151
-22619,1517725038225,153
-22620,1517725294616,147
-22621,1517725366191,142
-22622,1517725434976,142
-22623,1517725693994,141
-22624,1517725800849,141
-22625,1517726438440,139
-22626,1517727200709,142
-22627,1517727315656,137
-22628,1517727410491,133
-22629,1517727515938,130
-22630,1517727594273,137
-22631,1517727829841,135
-22632,1517727945670,134
-22633,1517728086297,132
-22634,1517728383349,128
-22635,1517729120385,125
-22636,1517729276341,122
-22637,1517729385278,119
-22638,1517729482906,116
-22639,1517729960794,114
-22640,1517730189566,109
-22641,1517730307358,105
-22642,1517730464366,101
-22643,1517730536239,97
-22644,1517730578791,94
-22645,1517730861555,94
-22646,1517730969251,89
-22647,1517731142992,98
-22648,1517731201897,97
-22649,1517731761131,97
-22650,1517731951081,92
-22651,1517732080318,89
-22652,1517732179220,86
-22653,1517732224157,82
-22654,1517732266367,82
-22655,1517732299346,82
-22656,1517732390672,84
-22657,1517732456653,81
-22658,1517732501596,83
-22659,1517732711419,83
-22660,1517732747450,78
-22661,1517732832470,78
-22662,1517732973417,75
-22663,1517733020283,71
-22664,1517733040495,68
-22665,1517733138934,72
-22666,1517733246135,69
-22667,1517733279555,65
-22668,1517733762502,64
-22669,1517733857160,58
-22670,1517733885528,58
-22671,1517733900311,58
-22672,1517733957739,62
-22673,1517733974892,59
-22674,1517734118680,62
-22675,1517734247228,61
-22676,1517734397984,57
-22677,1517734466759,53
-22678,1517734502478,50
-22679,1517734514208,47
-22680,1517734548208,53
-22681,1517734595176,51
-22682,1517734628006,52
-22683,1517734747583,51
-22684,1517734809008,45
-22685,1517734861014,44
-22686,1517734916379,41
-22687,1517734954166,40
-22688,1517734985309,43
-22689,1517735172373,40
-22690,1517735308029,35
-22691,1517735346603,31
-22692,1517735369467,28
-22693,1517735395358,29
-22694,1517735466884,30
-22695,1517735478349,56
-22696,1517735593602,66
-22697,1517735657592,63
-22698,1517735774072,62
-22699,1517735777985,58
-22700,1517735818885,89
-22701,1517736050688,91
-22702,1517736062627,88
-22703,1517736195957,106
-22704,1517736317179,104
-22705,1517736529002,102
-22706,1517736650822,101
-22707,1517737048138,98
-22708,1517737057361,94
-22709,1517737377678,113
-22710,1517737411325,109
-22711,1517737534261,112
-22712,1517737864756,110
-22713,1517738128776,110
-22714,1517738445149,119
-22715,1517738545151,120
-22716,1517738678933,126
-22717,1517738816951,124
-22718,1517738909363,122
-22719,1517738989839,122
-22720,1517739130489,121
-22721,1517739393503,118
-22722,1517739521935,117
-22723,1517739607695,116
-22724,1517739820833,115
-22725,1517739827235,113
-22726,1517739844537,151
-22727,1517740078953,166
-22728,1517740353215,163
-22729,1517740357389,160
-22730,1517740461806,248
-22731,1517741376972,249
-22732,1517741441784,242
-22733,1517741871957,246
-22734,1517742209446,241
-22735,1517742249151,236
-22736,1517742260784,243
-22737,1517743762017,286
-22738,1517744140361,279
-22739,1517744147074,274
-22740,1517744201059,364
-22741,1517744557632,371
-22742,1517745224158,365
-22743,1517745751488,357
-22744,1517745844868,350
-22745,1517746301876,352
-22746,1517746356752,345
-22747,1517747619861,350
-22748,1517747665175,341
-22749,1517748250499,351
-22750,1517748375013,343
-22751,1517748854296,339
-22752,1517749099443,331
-22753,1517749907466,326
-22754,1517750088457,318
-22755,1517750314197,314
-22756,1517750789293,310
-22757,1517751869342,302
-22758,1517752205397,294
-22759,1517753574484,288
-22760,1517755137405,279
-22761,1517755220266,271
-22762,1517756473289,269
-22763,1517756788381,261
-22764,1517757134178,254
-22765,1517757376701,249
-22766,1517757427636,243
-22767,1517757541112,245
-22768,1517757877612,242
-22769,1517758240718,233
-22770,1517758269142,225
-22771,1517758297490,236
-22772,1517758470653,250
-22773,1517758485023,244
-22774,1517758658025,279
-22775,1517758721928,271
-22776,1517759038151,271
-22777,1517760019573,262
-22778,1517760031237,252
-22779,1517760071092,294
-22780,1517760384840,304
-22781,1517760779308,296
-22782,1517761291611,287
-22783,1517761350977,278
-22784,1517761927751,278
-22785,1517762125001,267
-22786,1517762888543,259
-22787,1517763216354,248
-22788,1517763325422,239
-22789,1517763612499,233
-22790,1517763932956,223
-22791,1517763986557,213
-22792,1517764039800,211
-22793,1517764255350,209
-22794,1517764566967,200
-22795,1517764611666,189
-22796,1517764710893,193
-22797,1517765221312,185
-22798,1517765687845,175
-22799,1517766102714,164
-22800,1517766109307,171
-22801,1517766544298,223
-22802,1517766599843,212
-22803,1517767004780,217
-22804,1517767013895,206
-22805,1517767144959,249
-22806,1517767240095,240
-22807,1517767315223,233
-22808,1517767333043,227
-22809,1517767428309,257
-22810,1517767619199,250
-22811,1517767657785,242
-22812,1517768795280,245
-22813,1517769123787,232
-22814,1517769838278,220
-22815,1517769877738,207
-22816,1517769915389,206
-22817,1517770475781,206
-22818,1517770512249,194
-22819,1517770555484,193
-22820,1517770722060,191
-22821,1517771290173,181
-22822,1517771391604,167
-22823,1517771471189,157
-22824,1517772055042,148
-22825,1517772366978,135
-22826,1517772621451,143
-22827,1517773295952,141
-22828,1517773463559,129
-22829,1517773549194,117
-22830,1517773930554,154
-22831,1517773963998,145
-22832,1517774165768,144
-22833,1517774235764,137
-22834,1517774384304,131
-22835,1517774555969,120
-22836,1517774569885,117
-22837,1517774957568,151
-22838,1517775121125,140
-22839,1517775447784,131
-22840,1517775485187,171
-22841,1517775499633,179
-22842,1517775901682,199
-22843,1517776225380,191
-22844,1517776509673,183
-22845,1517776685448,177
-22846,1517777599470,171
-22847,1517777703503,168
-22848,1517778296668,161
-22849,1517778434751,161
-22850,1517778523160,154
-22851,1517778764525,152
-22852,1517779050700,144
-22853,1517779794353,137
-22854,1517779806195,127
-22855,1517780463441,145
-22856,1517780531058,137
-22857,1517781227244,132
-22858,1517781403899,122
-22859,1517781429810,114
-22860,1517781490713,114
-22861,1517781519137,109
-22862,1517781708894,112
-22863,1517781726464,102
-22864,1517781902200,106
-22865,1517782107337,98
-22866,1517782349266,90
-22867,1517782465757,85
-22868,1517782608602,78
-22869,1517782778607,70
-22870,1517782796194,62
-22871,1517782833395,69
-22872,1517782837609,73
-22873,1517782841324,106
-22874,1517782907291,184
-22875,1517783037313,182
-22876,1517783041225,179
-22877,1517783540621,279
-22878,1517783655964,268
-22879,1517783744748,287
-22880,1517784084762,291
-22881,1517784283513,283
-22882,1517784519374,275
-22883,1517784922187,267
-22884,1517785103593,262
-22885,1517785523570,254
-22886,1517785535725,245
-22887,1517785610421,282
-22888,1517785981349,280
-22889,1517786158929,271
-22890,1517786396640,263
-22891,1517786613795,254
-22892,1517786718421,249
-22893,1517787049124,247
-22894,1517787218892,238
-22895,1517788402228,229
-22896,1517788922772,222
-22897,1517789090806,213
-22898,1517789236385,204
-22899,1517789765529,196
-22900,1517790084829,184
-22901,1517790166628,206
-22902,1517790263364,200
-22903,1517790281306,199
-22904,1517790365366,214
-22905,1517790454346,236
-22906,1517790512802,234
-22907,1517790729249,236
-22908,1517790795948,230
-22909,1517791221511,243
-22910,1517791249868,237
-22911,1517791671930,248
-22912,1517791744481,246
-22913,1517792295170,244
-22914,1517792563125,234
-22915,1517792611208,225
-22916,1517793108509,233
-22917,1517793234165,229
-22918,1517793420696,223
-22919,1517793637486,222
-22920,1517793641240,219
-22921,1517794413846,351
-22922,1517795209158,339
-22923,1517795649286,329
-22924,1517796446571,321
-22925,1517796544458,310
-22926,1517796948868,305
-22927,1517797023910,296
-22928,1517797256135,292
-22929,1517798353595,283
-22930,1517798570717,273
-22931,1517798653147,263
-22932,1517798994775,264
-22933,1517799217071,253
-22934,1517799305620,246
-22935,1517799318256,242
-22936,1517799516816,275
-22937,1517799635960,275
-22938,1517799723883,268
-22939,1517800881619,263
-22940,1517801315168,250
-22941,1517802135699,244
-22942,1517802416983,247
-22943,1517802650761,237
-22944,1517802825529,227
-22945,1517803115571,218
-22946,1517803290857,209
-22947,1517803370781,199
-22948,1517803402534,195
-22949,1517803480764,197
-22950,1517803536049,191
-22951,1517803991738,188
-22952,1517804203651,177
-22953,1517804415074,166
-22954,1517804517745,154
-22955,1517805026990,158
-22956,1517805031049,146
-22957,1517805180253,222
-22958,1517805521350,212
-22959,1517806497219,200
-22960,1517806553439,192
-22961,1517806584940,188
-22962,1517807526648,193
-22963,1517807775037,180
-22964,1517808105519,175
-22965,1517808137199,163
-22966,1517808228395,162
-22967,1517808457294,153
-22968,1517808494867,141
-22969,1517808598961,136
-22970,1517808901519,126
-22971,1517809001197,117
-22972,1517809045941,107
-22973,1517809057908,120
-22974,1517809163117,166
-22975,1517809275538,161
-22976,1517809610502,153
-22977,1517810122340,197
-22978,1517810252709,188
-22979,1517810686673,183
-22980,1517810942101,177
-22981,1517810956947,168
-22982,1517810997112,186
-22983,1517811030981,187
-22984,1517811597309,189
-22985,1517812019506,180
-22986,1517812364339,169
-22987,1517812428405,184
-22988,1517812872032,185
-22989,1517813128590,175
-22990,1517813289885,168
-22991,1517813703138,161
-22992,1517813736807,152
-22993,1517813878611,156
-22994,1517813887812,148
-22995,1517814028296,177
-22996,1517814255702,168
-22997,1517814558912,159
-22998,1517814878281,151
-22999,1517814948335,142
-23000,1517814999306,135
-23001,1517815425427,131
-23002,1517815689207,123
-23003,1517815941960,115
-23004,1517815950836,119
-23005,1517816105538,143
-23006,1517816267347,136
-23007,1517816630931,132
-23008,1517816796047,123
-23009,1517817058806,117
-23010,1517817131906,108
-23011,1517817300830,110
-23012,1517817621141,102
-23013,1517817659836,95
-23014,1517817767408,92
-23015,1517817874825,83
-23016,1517818069131,80
-23017,1517818109425,70
-23018,1517818201143,66
-23019,1517818405616,58
-23020,1517818585448,49
-23021,1517818613693,112
-23022,1517818848134,113
-23023,1517818917784,106
-23024,1517820159938,101
-23025,1517820337154,94
-23026,1517820370624,90
-23027,1517820524268,89
-23028,1517820685729,86
-23029,1517820903784,80
-23030,1517820934627,73
-23031,1517821039758,72
-23032,1517821063006,68
-23033,1517821183373,68
-23034,1517821253587,62
-23035,1517821318136,58
-23036,1517821365528,75
-23037,1517821407929,74
-23038,1517821475059,72
-23039,1517821514335,71
-23040,1517821518395,67
-23041,1517821530770,100
-23042,1517821878745,111
-23043,1517822008571,105
-23044,1517822053696,99
-23045,1517822943578,98
-23046,1517822955700,89
-23047,1517823074428,100
-23048,1517823691305,96
-23049,1517823761164,95
-23050,1517823777902,93
-23051,1517823975554,102
-23052,1517824022662,95
-23053,1517824045883,92
-23054,1517824436049,93
-23055,1517824634394,87
-23056,1517824721149,79
-23057,1517824838984,118
-23058,1517824914358,114
-23059,1517824943514,111
-23060,1517824966680,113
-23061,1517824980957,121
-23062,1517825438205,141
-23063,1517825450433,134
-23064,1517825560187,154
-23065,1517825756462,150
-23066,1517825848479,150
-23067,1517825910745,147
-23068,1517826177942,146
-23069,1517826257494,144
-23070,1517826280346,141
-23071,1517826664051,149
-23072,1517827982245,142
-23073,1517828145787,137
-23074,1517828449702,144
-23075,1517828582807,139
-23076,1517828586468,136
-23077,1517828642941,217
-23078,1517828946434,218
-23079,1517829075946,212
-23080,1517829491405,207
-23081,1517829519716,200
-23082,1517829679781,222
-23083,1517829953637,222
-23084,1517830014760,222
-23085,1517830200551,222
-23086,1517830522022,217
-23087,1517831703013,210
-23088,1517831715254,205
-23089,1517832010639,237
-23090,1517832684523,230
-23091,1517832769925,222
-23092,1517833310660,220
-23093,1517833700295,217
-23094,1517834423677,210
-23095,1517834987260,221
-23096,1517835064952,215
-23097,1517835279645,214
-23098,1517835296586,209
-23099,1517835342437,230
-23100,1517836110743,235
-23101,1517837041462,230
-23102,1517837516519,221
-23103,1517838889065,213
-23104,1517839169854,206
-23105,1517839643478,214
-23106,1517839741015,208
-23107,1517839871778,205
-23108,1517839916672,201
-23109,1517839931227,204
-23110,1517840250995,228
-23111,1517840602496,223
-23112,1517840788184,215
-23113,1517840948679,210
-23114,1517841131845,206
-23115,1517841279061,200
-23116,1517841461416,195
-23117,1517841517722,189
-23118,1517841737968,189
-23119,1517842079425,182
-23120,1517842428122,175
-23121,1517843179912,167
-23122,1517843186269,162
-23123,1517843313419,215
-23124,1517843623460,210
-23125,1517843671105,202
-23126,1517843864211,202
-23127,1517844063799,197
-23128,1517844148374,190
-23129,1517844162805,185
-23130,1517845089877,206
-23131,1517845879947,199
-23132,1517845889442,189
-23133,1517845948041,229
-23134,1517846217768,228
-23135,1517846305555,219
-23136,1517846583304,215
-23137,1517846677007,207
-23138,1517846958214,202
-23139,1517847619696,194
-23140,1517847717751,186
-23141,1517847779071,198
-23142,1517848131111,205
-23143,1517848230826,196
-23144,1517848262082,191
-23145,1517848748115,197
-23146,1517849758503,187
-23147,1517849987893,186
-23148,1517850391819,177
-23149,1517850564963,168
-23150,1517850579632,162
-23151,1517850791309,184
-23152,1517851055781,176
-23153,1517851313660,169
-23154,1517851570300,163
-23155,1517851582137,155
-23156,1517851648358,176
-23157,1517851660216,172
-23158,1517851909288,196
-23159,1517852003040,189
-23160,1517852157332,186
-23161,1517852340069,183
-23162,1517852386886,184
-23163,1517852556004,183
-23164,1517852679377,187
-23165,1517852921990,181
-23166,1517852944904,173
-23167,1517853049046,182
-23168,1517853525439,177
-23169,1517853620936,168
-23170,1517853978862,163
-23171,1517854682181,160
-23172,1517854711009,150
-23173,1517855045798,151
-23174,1517855266335,142
-23175,1517855507539,132
-23176,1517855585270,123
-23177,1517855594294,162
-23178,1517855625935,200
-23179,1517855911074,205
-23180,1517856045844,198
-23181,1517856438112,192
-23182,1517856655245,191
-23183,1517856725117,184
-23184,1517856748131,181
-23185,1517856834494,194
-23186,1517857485863,190
-23187,1517858332645,181
-23188,1517858769691,170
-23189,1517858959917,181
-23190,1517859960172,174
-23191,1517860221013,165
-23192,1517860257609,160
-23193,1517860421864,161
-23194,1517860586962,153
-23195,1517860673656,146
-23196,1517860867855,140
-23197,1517861194744,135
-23198,1517861334394,127
-23199,1517861784857,134
-23200,1517861871220,131
-23201,1517862401809,125
-23202,1517862515150,117
-23203,1517862813126,110
-23204,1517863379788,101
-23205,1517863448717,93
-23206,1517863634413,87
-23207,1517863663000,81
-23208,1517863743020,81
-23209,1517863768865,78
-23210,1517863908644,93
-23211,1517863936759,87
-23212,1517863992360,86
-23213,1517864106472,82
-23214,1517864134227,75
-23215,1517864329698,74
-23216,1517864516652,68
-23217,1517864528795,61
-23218,1517864572549,67
-23219,1517864590438,63
-23220,1517864594575,63
-23221,1517864636941,90
-23222,1517864753268,86
-23223,1517865017242,109
-23224,1517865084874,103
-23225,1517865388445,98
-23226,1517865550625,95
-23227,1517865767280,89
-23228,1517865855244,82
-23229,1517865864580,78
-23230,1517866104543,105
-23231,1517866121323,98
-23232,1517866254016,103
-23233,1517866649773,120
-23234,1517867311647,118
-23235,1517868341869,111
-23236,1517868400245,107
-23237,1517868500034,104
-23238,1517868711486,101
-23239,1517868886552,95
-23240,1517869023547,89
-23241,1517869163248,85
-23242,1517869406077,82
-23243,1517869433539,76
-23244,1517869470675,76
-23245,1517869644067,82
-23246,1517869829640,75
-23247,1517870001716,68
-23248,1517870156394,63
-23249,1517870168319,57
-23250,1517870256946,62
-23251,1517870271966,69
-23252,1517870281363,74
-23253,1517870304053,85
-23254,1517870485323,88
-23255,1517870582296,82
-23256,1517870960257,92
-23257,1517871100278,88
-23258,1517871255094,100
-23259,1517871288226,95
-23260,1517871298023,98
-23261,1517871315028,116
-23262,1517871387745,127
-23263,1517871440394,128
-23264,1517871711433,128
-23265,1517871979761,123
-23266,1517872162929,118
-23267,1517872254207,122
-23268,1517872523348,119
-23269,1517873008831,114
-23270,1517873330513,110
-23271,1517873389044,104
-23272,1517873477250,101
-23273,1517873971354,103
-23274,1517874010803,97
-23275,1517874110852,96
-23276,1517874119998,93
-23277,1517874510026,112
-23278,1517874642558,127
-23279,1517874933942,130
-23280,1517875060821,126
-23281,1517875102251,123
-23282,1517875219900,125
-23283,1517875526516,121
-23284,1517875865150,119
-23285,1517876162549,123
-23286,1517876385667,121
-23287,1517876569911,116
-23288,1517877184907,112
-23289,1517877224937,106
-23290,1517877310601,107
-23291,1517877345241,104
-23292,1517877395020,105
-23293,1517877416107,110
-23294,1517877436985,118
-23295,1517877501051,126
-23296,1517877927572,126
-23297,1517878002598,120
-23298,1517878078679,118
-23299,1517878115231,116
-23300,1517878277766,117
-23301,1517878556383,114
-23302,1517878741672,109
-23303,1517879127640,104
-23304,1517879207288,99
-23305,1517879423529,95
-23306,1517879457667,91
-23307,1517879519453,91
-23308,1517879737783,91
-23309,1517879741420,87
-23310,1517879988180,141
-23311,1517880407480,136
-23312,1517880540345,133
-23313,1517880642549,129
-23314,1517880660938,126
-23315,1517880752063,138
-23316,1517881461520,135
-23317,1517881904989,128
-23318,1517882866507,128
-23319,1517882892286,122
-23320,1517883044181,130
-23321,1517883165633,144
-23322,1517883314526,143
-23323,1517883405330,138
-23324,1517883513186,136
-23325,1517883976425,133
-23326,1517884160420,128
-23327,1517884710619,123
-23328,1517884858652,117
-23329,1517884943236,113
-23330,1517884949914,120
-23331,1517884964695,157
-23332,1517885457091,182
-23333,1517885505797,176
-23334,1517885556529,179
-23335,1517885869835,179
-23336,1517885881736,172
-23337,1517885924430,202
-23338,1517886026710,207
-23339,1517886353631,204
-23340,1517886991294,198
-23341,1517887125715,190
-23342,1517887543182,186
-23343,1517888029160,179
-23344,1517888802209,175
-23345,1517890282643,170
-23346,1517890432169,163
-23347,1517890558442,157
-23348,1517890979147,152
-23349,1517891031681,145
-23350,1517891220067,150
-23351,1517891660261,144
-23352,1517892033278,142
-23353,1517892137146,145
-23354,1517892792282,145
-23355,1517892843140,139
-23356,1517893020002,138
-23357,1517893119325,133
-23358,1517893144904,128
-23359,1517893239020,134
-23360,1517893366041,133
-23361,1517893618702,140
-23362,1517893951098,142
-23363,1517894036200,138
-23364,1517894505066,137
-23365,1517894572972,131
-23366,1517894636765,129
-23367,1517894654207,127
-23368,1517894868431,139
-23369,1517895000388,134
-23370,1517895164559,128
-23371,1517895227898,123
-23372,1517895292969,123
-23373,1517895394037,121
-23374,1517895597619,115
-23375,1517895758187,112
-23376,1517896001077,108
-23377,1517896114872,114
-23378,1517896181105,109
-23379,1517896224251,107
-23380,1517896323381,106
-23381,1517896349198,102
-23382,1517896496305,108
-23383,1517896617958,103
-23384,1517896626780,98
-23385,1517896756488,118
-23386,1517896864109,113
-23387,1517896876124,108
-23388,1517896936280,123
-23389,1517897114924,119
-23390,1517897254444,116
-23391,1517897737606,112
-23392,1517897978909,107
-23393,1517898021477,104
-23394,1517898289116,108
-23395,1517898602807,108
-23396,1517898796443,103
-23397,1517899052845,97
-23398,1517899188007,92
-23399,1517899254050,88
-23400,1517899282419,88
-23401,1517899387336,89
-23402,1517899486412,83
-23403,1517899523519,78
-23404,1517899622642,76
-23405,1517899719152,72
-23406,1517899922420,66
-23407,1517899995780,62
-23408,1517900187655,58
-23409,1517900252008,52
-23410,1517900286752,77
-23411,1517900476596,76
-23412,1517900513170,70
-23413,1517900584539,69
-23414,1517900734202,66
-23415,1517900746488,69
-23416,1517900870896,78
-23417,1517900982419,72
-23418,1517901148711,67
-23419,1517901155162,62
-23420,1517901203013,84
-23421,1517901206728,82
-23422,1517901302994,130
-23423,1517901885892,127
-23424,1517902010520,121
-23425,1517902178008,117
-23426,1517902372415,112
-23427,1517902662158,106
-23428,1517902674147,99
-23429,1517902957836,112
-23430,1517903093116,107
-23431,1517903523931,123
-23432,1517903634102,130
-23433,1517903717188,126
-23434,1517903732334,127
-23435,1517903946787,144
-23436,1517903950534,139
-23437,1517903967455,240
-23438,1517903993042,272
-23439,1517904180636,291
-23440,1517904784171,287
-23441,1517905074293,280
-23442,1517905325607,276
-23443,1517905630462,270
-23444,1517906314638,264
-23445,1517908116647,256
-23446,1517909081777,248
-23447,1517909150542,242
-23448,1517909342685,243
-23449,1517909605174,238
-23450,1517909637141,234
-23451,1517910096240,244
-23452,1517910144366,237
-23453,1517910262212,240
-23454,1517910857940,238
-23455,1517911423122,230
-23456,1517911981826,225
-23457,1517912181536,218
-23458,1517912232301,213
-23459,1517912404245,221
-23460,1517912907184,216
-23461,1517913128215,210
-23462,1517913951231,204
-23463,1517914479915,196
-23464,1517915007747,190
-23465,1517915686439,182
-23466,1517915837312,176
-23467,1517916899740,172
-23468,1517918083013,173
-23469,1517919062232,166
-23470,1517919411117,159
-23471,1517919626816,152
-23472,1517919671878,147
-23473,1517920172083,149
-23474,1517920667645,143
-23475,1517920953024,136
-23476,1517920956922,130
-23477,1517921360428,202
-23478,1517921394353,195
-23479,1517921621810,200
-23480,1517921892691,196
-23481,1517922049662,189
-23482,1517922748285,187
-23483,1517922911820,179
-23484,1517923099058,173
-23485,1517923544309,179
-23486,1517923935456,172
-23487,1517924258041,165
-23488,1517924775780,168
-23489,1517925216584,163
-23490,1517925834712,156
-23491,1517926266799,149
-23492,1517926335119,141
-23493,1517926883343,138
-23494,1517927406607,133
-23495,1517928637098,125
-23496,1517930697204,117
-23497,1517931552728,108
-23498,1517931700640,100
-23499,1517932292001,95
-23500,1517932973803,88
-23501,1517933496095,83
-23502,1517933973366,76
-23503,1517934329805,68
-23504,1517934512742,63
-23505,1517934663860,56
-23506,1517935001444,49
-23507,1517935264314,42
-23508,1517935336586,35
-23509,1517935418826,28
-23510,1517935690870,21
-23511,1517935914991,16
-23512,1517935960126,9
-23513,1517935990215,3
-23514,1517936011464,1
-23515,1517936027399,1
-23516,1517936038379,1
-23517,1517936054728,1
-23518,1517936070834,1
-23519,1517936082392,1
-23520,1517936094400,1
-23521,1517936105365,1
-23522,1517936120723,1
-23523,1517936132821,1
-23524,1517936144323,1
-23525,1517936155615,1
-23526,1517936167451,1
-23527,1517936179026,1
-23528,1517936191129,1
-23529,1517936202798,1
-23530,1517936214961,1
-23531,1517936225664,1
-23532,1517936237662,1
-23533,1517936249410,1
-23534,1517936266395,1
-23535,1517936278168,1
-23536,1517936289883,1
-23537,1517936301170,1
-23538,1517936312918,1
-23539,1517936329954,1
-23540,1517936342190,1
-23541,1517936353915,1
-23542,1517936365762,1
-23543,1517936382382,1
-23544,1517936393839,1
-23545,1517936405826,1
-23546,1517936416835,1
-23547,1517936428505,1
-23548,1517936440595,1
-23549,1517936452607,1
-23550,1517936464008,1
-23551,1517936480238,1
-23552,1517936492152,1
-23553,1517936503751,1
-23554,1517936515478,1
-23555,1517936531193,1
-23556,1517936547612,1
-23557,1517936558991,1
-23558,1517936575417,1
-23559,1517936587299,1
-23560,1517936604272,1
-23561,1517936616104,1
-23562,1517936627727,1
-23563,1517936638685,1
-23564,1517936650125,1
-23565,1517936661747,1
-23566,1517936679031,1
-23567,1517936698636,1
-23568,1517936715410,1
-23569,1517936726767,1
-23570,1517936743247,1
-23571,1517936760453,1
-23572,1517936777245,1
-23573,1517936789593,1
-23574,1517936801250,1
-23575,1517936821840,1
-23576,1517936838082,1
-23577,1517936848993,1
-23578,1517936865600,1
-23579,1517936876417,1
-23580,1517936892600,1
-23581,1517936903881,1
-23582,1517936915594,1
-23583,1517936926610,1
-23584,1517936938689,1
-23585,1517936950389,1
-23586,1517936961866,1
-23587,1517936973783,1
-23588,1517936984801,1
-23589,1517936996683,1
-23590,1517937012959,1
-23591,1517937024042,1
-23592,1517937040197,1
-23593,1517937051763,2
-23594,1517937063733,2
-23595,1517937075177,2
-23596,1517937086587,3
-23597,1517937107708,3
-23598,1517937124035,3
-23599,1517937144029,4
-23600,1517937173675,4
-23601,1517937208166,4
-23602,1517937223202,5
-23603,1517937235011,5
-23604,1517937269509,6
-23605,1517937281382,6
-23606,1517937292606,7
-23607,1517937339043,9
-23608,1517937360202,9
-23609,1517937371662,10
-23610,1517937447778,13
-23611,1517937514457,13
-23612,1517937658048,13
-23613,1517937898557,13
-23614,1517938036361,12
-23615,1517938080427,12
-23616,1517938166884,13
-23617,1517938244696,12
-23618,1517938286798,12
-23619,1517938335792,13
-23620,1517938371044,13
-23621,1517938455050,14
-23622,1517938571356,13
-23623,1517938697583,14
-23624,1517938825032,13
-23625,1517938900140,14
-23626,1517938972424,14
-23627,1517939026969,13
-23628,1517939143681,13
-23629,1517939254739,13
-23630,1517939341358,14
-23631,1517939352357,14
-23632,1517939396390,16
-23633,1517939448130,17
-23634,1517939531902,18
-23635,1517939590395,17
-23636,1517939639538,17
-23637,1517939712119,18
-23638,1517939804497,18
-23639,1517939927098,18
-23640,1517940045790,18
-23641,1517940113405,18
-23642,1517940301419,18
-23643,1517940627131,18
-23644,1517940808687,17
-23645,1517940853667,16
-23646,1517940917256,17
-23647,1517940991058,18
-23648,1517941035305,17
-23649,1517941056860,18
-23650,1517941068477,19
-23651,1517941192992,23
-23652,1517941257576,22
-23653,1517941326635,22
-23654,1517941404287,23
-23655,1517941472944,23
-23656,1517941527189,23
-23657,1517941548201,23
-23658,1517941780285,25
-23659,1517942017991,25
-23660,1517942048643,25
-23661,1517942112771,26
-23662,1517942286585,26
-23663,1517942485759,25
-23664,1517942581255,25
-23665,1517942611008,25
-23666,1517942637044,26
-23667,1517942668126,28
-23668,1517942917499,29
-23669,1517943238868,28
-23670,1517943336333,28
-23671,1517943347798,27
-23672,1517943564326,32
-23673,1517943668123,32
-23674,1517943712178,32
-23675,1517943809164,33
-23676,1517943984570,32
-23677,1517944191063,31
-23678,1517944337272,31
-23679,1517944371915,31
-23680,1517944449290,32
-23681,1517944691663,31
-23682,1517944884338,30
-23683,1517945122652,30
-23684,1517945432910,29
-23685,1517945728182,29
-23686,1517946065118,28
-23687,1517946240011,27
-23688,1517946306827,26
-23689,1517946463624,26
-23690,1517946705080,25
-23691,1517946820653,25
-23692,1517946911466,24
-23693,1517947029337,23
-23694,1517947139909,23
-23695,1517947197807,22
-23696,1517947242283,23
-23697,1517947258032,23
-23698,1517947298384,25
-23699,1517947332908,26
-23700,1517947530141,27
-23701,1517947875246,26
-23702,1517948039723,25
-23703,1517948227533,24
-23704,1517948314834,25
-23705,1517948377564,23
-23706,1517948468434,24
-23707,1517948706412,24
-23708,1517948911532,24
-23709,1517949013234,23
-23710,1517949162989,24
-23711,1517949279272,22
-23712,1517949342969,23
-23713,1517949421322,22
-23714,1517949591330,22
-23715,1517949753744,20
-23716,1517949820757,20
-23717,1517950032167,20
-23718,1517950262957,19
-23719,1517950423504,19
-23720,1517950596198,18
-23721,1517950674463,18
-23722,1517950704719,17
-23723,1517950720325,17
-23724,1517950736876,19
-23725,1517950753904,20
-23726,1517950773846,22
-23727,1517950938444,23
-23728,1517951117206,22
-23729,1517951170709,22
-23730,1517951210545,22
-23731,1517951358951,22
-23732,1517951573832,22
-23733,1517951662245,22
-23734,1517951702789,21
-23735,1517951871224,22
-23736,1517952053647,21
-23737,1517952162256,20
-23738,1517952321428,20
-23739,1517952505017,18
-23740,1517952629730,18
-23741,1517952684311,17
-23742,1517952728178,16
-23743,1517952785850,17
-23744,1517952939428,16
-23745,1517953106676,15
-23746,1517953164626,15
-23747,1517953199173,13
-23748,1517953287280,13
-23749,1517953431283,13
-23750,1517953631501,13
-23751,1517953783069,14
-23752,1517953858785,13
-23753,1517953940846,13
-23754,1517953997391,12
-23755,1517954055402,12
-23756,1517954091568,12
-23757,1517954117850,12
-23758,1517954134290,13
-23759,1517954202609,13
-23760,1517954456195,13
-23761,1517954651432,13
-23762,1517954704063,13
-23763,1517954744551,13
-23764,1517954755916,12
-23765,1517954810392,13
-23766,1517954901919,14
-23767,1517955089823,14
-23768,1517955223028,14
-23769,1517955304963,14
-23770,1517955431429,14
-23771,1517955593530,13
-23772,1517955699400,14
-23773,1517955908321,14
-23774,1517956054847,14
-23775,1517956102642,14
-23776,1517956147304,14
-23777,1517956191764,14
-23778,1517956321705,14
-23779,1517956444611,13
-23780,1517956466062,13
-23781,1517956593726,14
-23782,1517956684508,14
-23783,1517956762365,14
-23784,1517956811694,12
-23785,1517956850205,13
-23786,1517956903663,13
-23787,1517956952885,12
-23788,1517957007299,12
-23789,1517957103647,12
-23790,1517957222318,11
-23791,1517957288509,11
-23792,1517957331794,10
-23793,1517957381927,10
-23794,1517957427933,10
-23795,1517957532730,10
-23796,1517957642942,9
-23797,1517957672399,10
-23798,1517957742869,11
-23799,1517957795323,10
-23800,1517957825141,12
-23801,1517957837208,12
-23802,1517957921581,13
-23803,1517958071588,13
-23804,1517958216579,12
-23805,1517958246207,11
-23806,1517958262853,12
-23807,1517958283643,14
-23808,1517958342193,14
-23809,1517958420243,13
-23810,1517958456096,14
-23811,1517958477158,13
-23812,1517958492475,15
-23813,1517958533097,16
-23814,1517958642118,16
-23815,1517958746374,16
-23816,1517958902670,15
-23817,1517959064227,15
-23818,1517959104249,14
-23819,1517959145226,14
-23820,1517959233025,14
-23821,1517959291991,13
-23822,1517959313602,13
-23823,1517959376045,14
-23824,1517959438981,15
-23825,1517959502288,16
-23826,1517959538814,17
-23827,1517959661773,19
-23828,1517959777069,18
-23829,1517959863243,18
-23830,1517959942838,18
-23831,1517960024247,18
-23832,1517960136629,18
-23833,1517960235457,18
-23834,1517960270486,17
-23835,1517960327989,19
-23836,1517960386258,18
-23837,1517960450622,18
-23838,1517960472043,18
-23839,1517960693414,20
-23840,1517960910172,19
-23841,1517961032644,18
-23842,1517961062740,18
-23843,1517961152928,19
-23844,1517961257119,19
-23845,1517961282637,18
-23846,1517961437915,19
-23847,1517961526591,19
-23848,1517961593848,19
-23849,1517961742958,19
-23850,1517961856502,18
-23851,1517961910289,18
-23852,1517961963422,18
-23853,1517962056664,18
-23854,1517962161752,17
-23855,1517962197684,17
-23856,1517962223385,18
-23857,1517962254023,19
-23858,1517962302767,19
-23859,1517962421823,21
-23860,1517962530515,20
-23861,1517962602784,20
-23862,1517962676383,20
-23863,1517962743106,20
-23864,1517962945027,19
-23865,1517963163410,20
-23866,1517963323178,20
-23867,1517963445823,19
-23868,1517963472868,19
-23869,1517963585579,19
-23870,1517963656587,19
-23871,1517963766613,18
-23872,1517963874374,18
-23873,1517963909564,18
-23874,1517963944584,18
-23875,1517963998627,18
-23876,1517964038858,18
-23877,1517964102193,19
-23878,1517964177204,19
-23879,1517964215618,19
-23880,1517964260880,19
-23881,1517964337973,20
-23882,1517964391137,19
-23883,1517964426647,19
-23884,1517964525980,19
-23885,1517964621067,20
-23886,1517964651793,19
-23887,1517964700472,20
-23888,1517964744421,20
-23889,1517964779129,20
-23890,1517964961575,21
-23891,1517965113639,20
-23892,1517965230132,20
-23893,1517965379161,19
-23894,1517965476310,19
-23895,1517965530565,18
-23896,1517965583879,18
-23897,1517965660089,18
-23898,1517965737229,17
-23899,1517965867385,17
-23900,1517966028890,16
-23901,1517966134826,16
-23902,1517966207667,17
-23903,1517966233560,16
-23904,1517966321549,17
-23905,1517966337617,16
-23906,1517966372566,18
-23907,1517966454342,19
-23908,1517966554751,19
-23909,1517966623120,18
-23910,1517966710336,18
-23911,1517966829449,18
-23912,1517966943649,18
-23913,1517967016642,19
-23914,1517967057422,19
-23915,1517967103057,19
-23916,1517967124738,19
-23917,1517967210665,20
-23918,1517967291853,20
-23919,1517967384666,20
-23920,1517967420631,20
-23921,1517967497791,20
-23922,1517967533572,19
-23923,1517967612130,20
-23924,1517967712465,20
-23925,1517967847309,19
-23926,1517967974293,20
-23927,1517968047248,19
-23928,1517968248023,19
-23929,1517968421716,18
-23930,1517968456388,18
-23931,1517968472776,18
-23932,1517968575314,20
-23933,1517968726977,19
-23934,1517968878672,19
-23935,1517968969925,19
-23936,1517969000275,19
-23937,1517969054154,19
-23938,1517969099270,19
-23939,1517969114959,20
-23940,1517969126351,22
-23941,1517969217538,26
-23942,1517969329286,26
-23943,1517969424502,26
-23944,1517969529400,25
-23945,1517969629901,25
-23946,1517969763589,24
-23947,1517969950571,25
-23948,1517970070832,24
-23949,1517970147506,23
-23950,1517970271213,22
-23951,1517970395437,22
-23952,1517970465266,21
-23953,1517970506600,21
-23954,1517970545639,22
-23955,1517970586782,22
-23956,1517970631522,22
-23957,1517970835826,23
-23958,1517971113171,23
-23959,1517971238322,23
-23960,1517971273607,22
-23961,1517971318764,23
-23962,1517971364006,23
-23963,1517971476898,23
-23964,1517971585676,24
-23965,1517971617191,22
-23966,1517971642565,23
-23967,1517971767263,24
-23968,1517971888355,23
-23969,1517971909114,23
-23970,1517972004865,25
-23971,1517972141449,25
-23972,1517972186203,24
-23973,1517972245032,25
-23974,1517972331602,25
-23975,1517972443060,25
-23976,1517972682689,24
-23977,1517972921115,23
-23978,1517973007906,23
-23979,1517973109237,23
-23980,1517973391447,23
-23981,1517973611088,22
-23982,1517973659894,21
-23983,1517973699150,22
-23984,1517973950474,23
-23985,1517974286390,21
-23986,1517974465062,21
-23987,1517974546925,20
-23988,1517974712111,20
-23989,1517974816877,20
-23990,1517975003527,20
-23991,1517975163297,19
-23992,1517975193524,18
-23993,1517975270747,19
-23994,1517975494821,19
-23995,1517975721156,18
-23996,1517975813044,16
-23997,1517975919965,17
-23998,1517975992675,16
-23999,1517976023914,16
-24000,1517976197497,16
-24001,1517976340177,15
-24002,1517976397114,15
-24003,1517976464953,14
-24004,1517976523402,13
-24005,1517976563193,14
-24006,1517976608811,14
-24007,1517976669545,15
-24008,1517976764667,14
-24009,1517976914203,14
-24010,1517977208729,13
-24011,1517977432273,12
-24012,1517977540991,11
-24013,1517977711045,10
-24014,1517977799646,10
-24015,1517977908050,10
-24016,1517978032624,9
-24017,1517978133511,10
-24018,1517978256318,9
-24019,1517978314037,8
-24020,1517978366939,8
-24021,1517978429569,8
-24022,1517978474386,7
-24023,1517978500468,7
-24024,1517978543341,8
-24025,1517978578067,7
-24026,1517978603631,7
-24027,1517978619835,6
-24028,1517978645333,7
-24029,1517978684606,7
-24030,1517978710338,6
-24031,1517978764542,6
-24032,1517978804025,7
-24033,1517978819556,6
-24034,1517978835881,6
-24035,1517978885106,6
-24036,1517978947392,6
-24037,1517978972907,5
-24038,1517979041287,5
-24039,1517979096240,5
-24040,1517979141743,6
-24041,1517979167598,8
-24042,1517979206461,8
-24043,1517979240431,8
-24044,1517979263142,8
-24045,1517979275164,9
-24046,1517979296687,9
-24047,1517979318262,10
-24048,1517979364159,11
-24049,1517979405117,10
-24050,1517979478585,10
-24051,1517979583517,10
-24052,1517979648739,10
-24053,1517979679653,9
-24054,1517979714873,10
-24055,1517979731077,10
-24056,1517979806536,11
-24057,1517979869215,11
-24058,1517979952575,11
-24059,1517979996521,10
-24060,1517980050369,11
-24061,1517980099579,10
-24062,1517980139276,11
-24063,1517980169388,11
-24064,1517980190425,11
-24065,1517980207558,13
-24066,1517980248123,14
-24067,1517980328357,15
-24068,1517980396824,15
-24069,1517980441270,15
-24070,1517980477509,16
-24071,1517980499618,17
-24072,1517980568158,18
-24073,1517980635890,18
-24074,1517980730137,18
-24075,1517980840252,19
-24076,1517980873712,19
-24077,1517980894150,19
-24078,1517980956635,21
-24079,1517981052678,21
-24080,1517981140386,21
-24081,1517981194758,21
-24082,1517981211493,21
-24083,1517981615148,23
-24084,1517982033364,23
-24085,1517982069512,22
-24086,1517982197961,24
-24087,1517982356170,23
-24088,1517982514161,22
-24089,1517982673218,22
-24090,1517982992718,22
-24091,1517983350355,21
-24092,1517983550438,20
-24093,1517983675172,20
-24094,1517983710168,21
-24095,1517983763877,21
-24096,1517983803538,21
-24097,1517983835046,22
-24098,1517983851839,23
-24099,1517984341277,25
-24100,1517984658860,25
-24101,1517984724235,24
-24102,1517984777855,25
-24103,1517984921132,25
-24104,1517985058658,25
-24105,1517985180857,24
-24106,1517985307503,23
-24107,1517985425266,24
-24108,1517985507941,23
-24109,1517985555104,23
-24110,1517985718539,24
-24111,1517985904078,23
-24112,1517986116509,22
-24113,1517986453870,21
-24114,1517986668238,21
-24115,1517986707169,20
-24116,1517986781496,21
-24117,1517986894108,20
-24118,1517987063084,19
-24119,1517987226017,19
-24120,1517987271778,18
-24121,1517987384673,19
-24122,1517987453453,18
-24123,1517987479094,18
-24124,1517987542642,19
-24125,1517987606633,19
-24126,1517987657127,18
-24127,1517987733425,19
-24128,1517987871314,19
-24129,1517988064667,18
-24130,1517988506570,17
-24131,1517988845509,16
-24132,1517988866556,16
-24133,1517988888176,17
-24134,1517988941582,18
-24135,1517988996514,19
-24136,1517989021613,18
-24137,1517989104215,19
-24138,1517989308243,19
-24139,1517989471405,18
-24140,1517989501540,17
-24141,1517989591484,17
-24142,1517989693329,17
-24143,1517989735348,16
-24144,1517989775161,17
-24145,1517989833782,18
-24146,1517989882801,17
-24147,1517989993701,18
-24148,1517990104936,18
-24149,1517990122549,17
-24150,1517990133417,18
-24151,1517990146397,22
-24152,1517990779213,24
-24153,1517991477701,23
-24154,1517991586497,23
-24155,1517991743697,22
-24156,1517991878636,22
-24157,1517991932447,21
-24158,1517992034652,21
-24159,1517992113773,21
-24160,1517992191568,21
-24161,1517992264555,20
-24162,1517992403074,19
-24163,1517992538268,19
-24164,1517992553920,19
-24165,1517992584539,21
-24166,1517992668647,22
-24167,1517992778187,22
-24168,1517992826783,22
-24169,1517992924764,22
-24170,1517993034033,22
-24171,1517993073629,22
-24172,1517993100358,22
-24173,1517993126782,24
-24174,1517993181475,25
-24175,1517993244804,25
-24176,1517993326814,24
-24177,1517993394604,25
-24178,1517993606840,25
-24179,1517993753122,25
-24180,1517993792921,24
-24181,1517993828504,25
-24182,1517993857991,26
-24183,1517993912069,29
-24184,1517993952087,29
-24185,1517994029108,29
-24186,1517994059814,29
-24187,1517994094239,31
-24188,1517994123506,31
-24189,1517994225539,33
-24190,1517994342281,33
-24191,1517994502791,32
-24192,1517994691810,31
-24193,1517994759302,30
-24194,1517994801872,30
-24195,1517994859564,31
-24196,1517995073634,32
-24197,1517995276495,31
-24198,1517995374334,30
-24199,1517995635891,31
-24200,1517996039645,31
-24201,1517996352486,30
-24202,1517996469210,29
-24203,1517996580543,29
-24204,1517996809724,28
-24205,1517997040350,27
-24206,1517997145080,27
-24207,1517997216003,26
-24208,1517997312275,26
-24209,1517997498673,25
-24210,1517997659244,25
-24211,1517997700189,24
-24212,1517997791312,24
-24213,1517997937030,24
-24214,1517998158086,23
-24215,1517998389977,21
-24216,1517998476059,22
-24217,1517998575958,21
-24218,1517998723391,21
-24219,1517998812781,20
-24220,1517998885310,19
-24221,1517998934266,19
-24222,1517999030430,19
-24223,1517999113331,18
-24224,1517999166571,18
-24225,1517999252155,18
-24226,1517999319581,17
-24227,1517999346052,17
-24228,1517999504448,17
-24229,1517999667368,17
-24230,1517999744184,16
-24231,1517999955698,15
-24232,1518000106906,13
-24233,1518000165108,14
-24234,1518000214179,14
-24235,1518000279936,14
-24236,1518000408939,13
-24237,1518000499368,13
-24238,1518000704147,13
-24239,1518000907344,11
-24240,1518000924364,10
-24241,1518000968248,11
-24242,1518001031649,11
-24243,1518001099102,10
-24244,1518001128978,9
-24245,1518001202280,10
-24246,1518001331420,9
-24247,1518001419675,8
-24248,1518001454503,7
-24249,1518001483924,7
-24250,1518001537764,7
-24251,1518001591597,9
-24252,1518001641277,10
-24253,1518001685661,10
-24254,1518001707083,9
-24255,1518001752131,9
-24256,1518001835823,8
-24257,1518001908179,8
-24258,1518001967901,7
-24259,1518002013187,6
-24260,1518002030648,6
-24261,1518002042380,7
-24262,1518002077470,7
-24263,1518002112994,7
-24264,1518002134222,6
-24265,1518002150651,7
-24266,1518002180547,8
-24267,1518002214965,8
-24268,1518002264160,8
-24269,1518002303568,7
-24270,1518002339372,6
-24271,1518002370091,7
-24272,1518002387325,7
-24273,1518002423361,8
-24274,1518002464305,8
-24275,1518002499346,8
-24276,1518002574241,9
-24277,1518002639860,8
-24278,1518002670215,8
-24279,1518002700455,7
-24280,1518002727359,7
-24281,1518002753650,8
-24282,1518002794331,9
-24283,1518002867902,9
-24284,1518002929886,8
-24285,1518002965094,9
-24286,1518002986208,9
-24287,1518003003415,11
-24288,1518003024034,12
-24289,1518003075535,14
-24290,1518003120629,14
-24291,1518003151086,15
-24292,1518003205913,15
-24293,1518003297456,15
-24294,1518003399619,15
-24295,1518003454324,15
-24296,1518003489096,16
-24297,1518003610219,16
-24298,1518003747404,16
-24299,1518003823473,15
-24300,1518003873318,15
-24301,1518003937064,15
-24302,1518004018602,16
-24303,1518004053010,15
-24304,1518004103141,16
-24305,1518004284897,16
-24306,1518004464308,15
-24307,1518004503229,15
-24308,1518004581056,16
-24309,1518004649053,16
-24310,1518004676571,15
-24311,1518004759139,17
-24312,1518004860820,16
-24313,1518004938394,16
-24314,1518005105538,16
-24315,1518005239643,15
-24316,1518005293156,15
-24317,1518005366912,15
-24318,1518005473751,15
-24319,1518005561639,15
-24320,1518005586798,15
-24321,1518005622319,15
-24322,1518005668044,17
-24323,1518005711981,16
-24324,1518005752128,16
-24325,1518005773056,17
-24326,1518005807805,19
-24327,1518005843551,19
-24328,1518005897087,21
-24329,1518005967592,20
-24330,1518006096255,21
-24331,1518006225381,20
-24332,1518006259968,19
-24333,1518006332201,20
-24334,1518006614031,20
-24335,1518006849281,20
-24336,1518006912504,19
-24337,1518007023675,19
-24338,1518007091537,19
-24339,1518007116654,18
-24340,1518007155552,20
-24341,1518007344366,20
-24342,1518007530810,20
-24343,1518007610035,20
-24344,1518007706114,19
-24345,1518007765230,19
-24346,1518007823761,19
-24347,1518007901234,19
-24348,1518008033851,19
-24349,1518008167754,18
-24350,1518008231111,18
-24351,1518008365991,18
-24352,1518008500695,18
-24353,1518008537083,18
-24354,1518008580099,18
-24355,1518008657908,18
-24356,1518008745025,18
-24357,1518008846462,17
-24358,1518008913452,17
-24359,1518008952627,17
-24360,1518008992558,17
-24361,1518009069944,18
-24362,1518009188468,18
-24363,1518009481638,17
-24364,1518009725948,17
-24365,1518009797607,16
-24366,1518009874361,17
-24367,1518009982585,17
-24368,1518010054592,16
-24369,1518010094936,16
-24370,1518010106911,15
-24371,1518010223988,18
-24372,1518010310760,18
-24373,1518010418600,18
-24374,1518010488057,18
-24375,1518010504634,17
-24376,1518010515821,19
-24377,1518010604149,22
-24378,1518010755598,21
-24379,1518010833449,21
-24380,1518010906297,21
-24381,1518011123174,21
-24382,1518011361491,21
-24383,1518011483613,20
-24384,1518011652694,19
-24385,1518011875178,18
-24386,1518012030496,18
-24387,1518012094991,17
-24388,1518012244108,18
-24389,1518012481183,18
-24390,1518012609948,17
-24391,1518012661583,17
-24392,1518012692792,17
-24393,1518012754814,18
-24394,1518012798685,17
-24395,1518012917978,18
-24396,1518013113590,17
-24397,1518013251041,17
-24398,1518013290672,17
-24399,1518013395274,17
-24400,1518013491604,17
-24401,1518013607644,16
-24402,1518013654498,15
-24403,1518013739130,16
-24404,1518013778602,16
-24405,1518013845738,16
-24406,1518013950479,15
-24407,1518014050250,15
-24408,1518014137203,15
-24409,1518014208646,14
-24410,1518014247865,14
-24411,1518014279046,15
-24412,1518014306270,15
-24413,1518014337700,15
-24414,1518014453817,16
-24415,1518014614032,16
-24416,1518014735092,14
-24417,1518014802608,14
-24418,1518014819023,14
-24419,1518014838750,15
-24420,1518014853899,16
-24421,1518014912696,19
-24422,1518014967631,18
-24423,1518015151700,18
-24424,1518015334101,18
-24425,1518015467566,18
-24426,1518015634619,18
-24427,1518015718701,18
-24428,1518015839272,18
-24429,1518015982816,17
-24430,1518016049766,17
-24431,1518016093977,17
-24432,1518016119917,17
-24433,1518016188488,18
-24434,1518016291350,18
-24435,1518016388202,18
-24436,1518016437172,17
-24437,1518016610728,17
-24438,1518016767645,17
-24439,1518016784313,16
-24440,1518016833710,18
-24441,1518016967851,19
-24442,1518017065685,18
-24443,1518017086759,18
-24444,1518017126534,19
-24445,1518017139218,19
-24446,1518017160053,23
-24447,1518017232935,24
-24448,1518017303322,24
-24449,1518017441592,24
-24450,1518017593341,24
-24451,1518017647266,23
-24452,1518017775776,23
-24453,1518017917142,23
-24454,1518018042140,22
-24455,1518018158945,22
-24456,1518018217172,21
-24457,1518018252171,21
-24458,1518018403919,22
-24459,1518018619430,22
-24460,1518018709758,21
-24461,1518018813576,22
-24462,1518018938901,21
-24463,1518018978947,20
-24464,1518019060527,20
-24465,1518019141553,20
-24466,1518019265777,19
-24467,1518019413291,19
-24468,1518019500576,18
-24469,1518019575185,18
-24470,1518019719787,18
-24471,1518019906189,18
-24472,1518019969313,18
-24473,1518020033821,18
-24474,1518020068235,18
-24475,1518020141591,18
-24476,1518020229252,19
-24477,1518020335159,21
-24478,1518020385642,19
-24479,1518020460259,20
-24480,1518020529888,20
-24481,1518020558679,19
-24482,1518020574517,21
-24483,1518020721544,23
-24484,1518020859973,22
-24485,1518021036835,21
-24486,1518021305123,21
-24487,1518021425884,20
-24488,1518021469514,20
-24489,1518021499671,20
-24490,1518021651396,20
-24491,1518021700195,19
-24492,1518021850444,19
-24493,1518021976392,19
-24494,1518022048456,19
-24495,1518022116467,19
-24496,1518022252018,19
-24497,1518022381801,18
-24498,1518022477101,17
-24499,1518022573448,18
-24500,1518022612756,16
-24501,1518022676645,17
-24502,1518022701959,16
-24503,1518022787632,17
-24504,1518022878809,17
-24505,1518023016847,16
-24506,1518023158636,16
-24507,1518023203973,16
-24508,1518023254283,16
-24509,1518023322670,15
-24510,1518023395568,15
-24511,1518023425764,14
-24512,1518023525182,15
-24513,1518023661301,15
-24514,1518023734032,15
-24515,1518023797045,14
-24516,1518023901730,13
-24517,1518023979552,13
-24518,1518024005692,12
-24519,1518024022386,13
-24520,1518024048510,15
-24521,1518024135292,17
-24522,1518024331152,17
-24523,1518024477902,17
-24524,1518024573897,16
-24525,1518024682696,15
-24526,1518024768772,14
-24527,1518024827563,13
-24528,1518024852058,13
-24529,1518025003109,14
-24530,1518025181950,13
-24531,1518025225757,12
-24532,1518025358070,13
-24533,1518025516983,12
-24534,1518025597990,12
-24535,1518025688277,12
-24536,1518025816190,11
-24537,1518025889387,10
-24538,1518025915314,10
-24539,1518025943886,9
-24540,1518025993001,10
-24541,1518026032291,11
-24542,1518026063151,10
-24543,1518026172022,10
-24544,1518026289340,10
-24545,1518026406878,10
-24546,1518026495209,12
-24547,1518026613406,12
-24548,1518026707780,12
-24549,1518026732599,12
-24550,1518026762596,13
-24551,1518026858288,13
-24552,1518026973147,12
-24553,1518027075616,12
-24554,1518027142444,11
-24555,1518027191540,11
-24556,1518027230661,11
-24557,1518027251961,12
-24558,1518027263691,12
-24559,1518027327039,14
-24560,1518027357180,14
-24561,1518027468019,14
-24562,1518027598075,14
-24563,1518027638278,14
-24564,1518027654132,14
-24565,1518027689283,16
-24566,1518027723693,15
-24567,1518027815490,16
-24568,1518027921318,16
-24569,1518028111745,15
-24570,1518028292735,15
-24571,1518028308375,15
-24572,1518028334110,16
-24573,1518028368936,16
-24574,1518028384863,17
-24575,1518028470955,19
-24576,1518028568005,19
-24577,1518028617209,19
-24578,1518028857661,19
-24579,1518029074073,19
-24580,1518029113448,18
-24581,1518029179379,19
-24582,1518029225091,19
-24583,1518029240806,20
-24584,1518029256597,23
-24585,1518029324822,25
-24586,1518029467883,25
-24587,1518029576696,25
-24588,1518029621785,24
-24589,1518029661756,25
-24590,1518029831704,27
-24591,1518030002338,25
-24592,1518030032488,25
-24593,1518030080213,26
-24594,1518030379692,27
-24595,1518030745299,27
-24596,1518031114871,26
-24597,1518031396975,25
-24598,1518031455293,24
-24599,1518031514074,25
-24600,1518031544168,25
-24601,1518031575295,25
-24602,1518031624339,27
-24603,1518031724947,28
-24604,1518031801924,28
-24605,1518031846757,28
-24606,1518031899718,29
-24607,1518031958522,28
-24608,1518032198207,29
-24609,1518032509544,29
-24610,1518032635407,27
-24611,1518032984606,27
-24612,1518033339575,27
-24613,1518033378794,26
-24614,1518033431884,27
-24615,1518033592226,27
-24616,1518033723078,26
-24617,1518033860482,25
-24618,1518033996844,25
-24619,1518034221365,25
-24620,1518034463109,25
-24621,1518034639739,25
-24622,1518034692829,24
-24623,1518034741983,24
-24624,1518034782069,24
-24625,1518034811545,25
-24626,1518034859564,26
-24627,1518034969608,26
-24628,1518035150927,26
-24629,1518035312421,26
-24630,1518035405529,25
-24631,1518035541619,24
-24632,1518035653432,23
-24633,1518035688150,23
-24634,1518035774677,23
-24635,1518035869219,23
-24636,1518035951373,22
-24637,1518036015255,22
-24638,1518036045521,22
-24639,1518036159839,23
-24640,1518036282805,22
-24641,1518036313586,21
-24642,1518036372259,22
-24643,1518036426249,23
-24644,1518036581868,22
-24645,1518036649460,21
-24646,1518036693235,21
-24647,1518036815254,20
-24648,1518037033291,20
-24649,1518037163415,19
-24650,1518037204107,18
-24651,1518037234575,19
-24652,1518037269243,19
-24653,1518037341865,19
-24654,1518037461688,19
-24655,1518037564465,18
-24656,1518037603663,18
-24657,1518037689639,18
-24658,1518037795472,17
-24659,1518037917683,17
-24660,1518038237893,17
-24661,1518038468783,17
-24662,1518038594081,15
-24663,1518038671750,15
-24664,1518038788282,14
-24665,1518038856281,14
-24666,1518038882353,14
-24667,1518038903021,15
-24668,1518038970496,15
-24669,1518039025050,15
-24670,1518039035901,15
-24671,1518039076575,16
-24672,1518039097251,17
-24673,1518039180265,19
-24674,1518039304552,18
-24675,1518039418876,18
-24676,1518039509973,18
-24677,1518039610328,18
-24678,1518039696362,17
-24679,1518039771929,16
-24680,1518039865195,15
-24681,1518039973523,16
-24682,1518040166638,14
-24683,1518040363399,14
-24684,1518040493324,15
-24685,1518040625924,15
-24686,1518040711467,14
-24687,1518040808598,14
-24688,1518040970971,14
-24689,1518041164185,13
-24690,1518041256108,13
-24691,1518041276268,13
-24692,1518041301243,14
-24693,1518041321576,15
-24694,1518041355896,16
-24695,1518041482245,16
-24696,1518041585666,15
-24697,1518041648678,15
-24698,1518041734141,14
-24699,1518041817534,14
-24700,1518041879715,13
-24701,1518041932073,14
-24702,1518041971662,14
-24703,1518042156533,15
-24704,1518042236298,14
-24705,1518042374586,14
-24706,1518042484434,15
-24707,1518042535411,14
-24708,1518042575237,14
-24709,1518042604928,14
-24710,1518042661595,14
-24711,1518042756197,15
-24712,1518042808006,14
-24713,1518042846650,14
-24714,1518042890654,14
-24715,1518042920377,15
-24716,1518042990414,15
-24717,1518043127001,15
-24718,1518043254701,14
-24719,1518043333548,13
-24720,1518043388984,12
-24721,1518043412999,13
-24722,1518043488482,13
-24723,1518043591858,13
-24724,1518043704930,13
-24725,1518043784234,12
-24726,1518043815310,13
-24727,1518043848774,14
-24728,1518043877921,14
-24729,1518043889435,14
-24730,1518043976897,16
-24731,1518044147227,16
-24732,1518044322661,15
-24733,1518044372008,14
-24734,1518044420016,15
-24735,1518044457174,15
-24736,1518044521608,15
-24737,1518044653977,16
-24738,1518044755806,15
-24739,1518044780616,16
-24740,1518044820456,16
-24741,1518044845421,17
-24742,1518044874683,17
-24743,1518044899579,19
-24744,1518044992036,19
-24745,1518045072254,19
-24746,1518045171800,19
-24747,1518045215643,19
-24748,1518045244330,20
-24749,1518045255277,20
-24750,1518045294092,23
-24751,1518045337248,24
-24752,1518045397054,26
-24753,1518045481703,26
-24754,1518045577341,26
-24755,1518045648097,25
-24756,1518045659449,26
-24757,1518045894407,30
-24758,1518046166453,29
-24759,1518046318774,29
-24760,1518046338770,28
-24761,1518046540730,30
-24762,1518046703369,30
-24763,1518046820320,29
-24764,1518046854502,29
-24765,1518046979122,29
-24766,1518047164818,29
-24767,1518047254062,28
-24768,1518047472456,29
-24769,1518047739866,28
-24770,1518047823278,28
-24771,1518047920093,29
-24772,1518048043859,29
-24773,1518048167825,30
-24774,1518048256535,29
-24775,1518048502194,29
-24776,1518048817805,28
-24777,1518048971530,28
-24778,1518049066442,27
-24779,1518049105454,26
-24780,1518049117024,27
-24781,1518049224229,32
-24782,1518049446319,32
-24783,1518049584188,31
-24784,1518049801405,30
-24785,1518050164009,29
-24786,1518050504691,28
-24787,1518050639548,27
-24788,1518050692028,26
-24789,1518050707298,27
-24790,1518050792627,29
-24791,1518050849895,29
-24792,1518050989910,30
-24793,1518051181053,29
-24794,1518051356657,30
-24795,1518051508467,29
-24796,1518051650128,28
-24797,1518051795328,28
-24798,1518051973883,27
-24799,1518052278108,26
-24800,1518052487020,25
-24801,1518052566253,25
-24802,1518052642825,24
-24803,1518052667858,24
-24804,1518052778194,25
-24805,1518052896847,24
-24806,1518052931640,24
-24807,1518053020289,24
-24808,1518053139844,23
-24809,1518053226373,23
-24810,1518053287554,23
-24811,1518053345696,23
-24812,1518053408296,22
-24813,1518053441873,22
-24814,1518053452054,23
-24815,1518053636690,27
-24816,1518053725182,27
-24817,1518053836410,27
-24818,1518053976530,26
-24819,1518054046705,25
-24820,1518054103303,24
-24821,1518054183008,24
-24822,1518054325596,23
-24823,1518054510703,23
-24824,1518054622034,22
-24825,1518054646618,21
-24826,1518054675438,22
-24827,1518054722264,23
-24828,1518054786428,23
-24829,1518054875250,23
-24830,1518054936921,23
-24831,1518054966262,23
-24832,1518054996601,24
-24833,1518055008577,24
-24834,1518055043466,28
-24835,1518055073463,28
-24836,1518055262614,29
-24837,1518055477547,29
-24838,1518055529227,27
-24839,1518055568748,27
-24840,1518055633562,28
-24841,1518055689821,28
-24842,1518055839719,28
-24843,1518056012059,28
-24844,1518056092040,27
-24845,1518056315798,27
-24846,1518056604197,26
-24847,1518056769888,25
-24848,1518056884572,24
-24849,1518433319586,24
-24850,1518433375335,24
-24851,1518433398038,25
-24852,1518433437666,26
-24853,1518433468832,27
-24854,1518433505087,28
-24855,1518433554725,29
-24856,1518433601424,29
-24857,1518433647757,32
-24858,1518433748053,32
-24859,1518433765263,31
-24860,1518433825267,34
-24861,1518433874849,35
-24862,1518433887798,36
-24863,1518433919301,42
-24864,1518433971787,43
-24865,1518433994267,45
-24866,1518434060113,48
-24867,1518434106902,48
-24868,1518434208321,49
-24869,1518434277760,49
-24870,1518434310280,48
-24871,1518434322155,51
-24872,1518434347302,59
-24873,1518434444501,63
-24874,1518434474656,63
-24875,1518434540336,65
-24876,1518434892592,66
-24877,1518434912550,64
-24878,1518434959267,70
-24879,1518435566687,71
-24880,1518435611587,70
-24881,1518435727623,75
-24882,1518435826427,74
-24883,1518436003287,73
-24884,1518436357594,73
-24885,1518436853672,71
-24886,1518437082972,69
-24887,1518437163362,67
-24888,1518437223677,67
-24889,1518437368583,68
-24890,1518437404178,68
-24891,1518437603242,71
-24892,1518437716852,71
-24893,1518437852748,70
-24894,1518437863053,68
-24895,1518438091008,82
-24896,1518438490691,81
-24897,1518438648400,78
-24898,1518438736855,78
-24899,1518439212429,77
-24900,1518439516118,74
-24901,1518439662845,72
-24902,1518439706432,72
-24903,1518439987700,72
-24904,1518440039243,72
-24905,1518440290091,72
-24906,1518440379671,71
-24907,1518440652861,70
-24908,1518440713842,69
-24909,1518440783320,69
-24910,1518441335467,69
-24911,1518441553488,66
-24912,1518442058684,64
-24913,1518442105571,62
-24914,1518442422706,63
-24915,1518442616469,64
-24916,1518442662914,62
-24917,1518442894213,62
-24918,1518443111321,61
-24919,1518443337209,58
-24920,1518443650669,57
-24921,1518443785425,55
-24922,1518443981560,53
-24923,1518444039640,51
-24924,1518444078499,50
-24925,1518444183359,51
-24926,1518444336338,51
-24927,1518444398954,49
-24928,1518444442845,49
-24929,1518444679020,49
-24930,1518445019821,46
-24931,1518445081844,45
-24932,1518445134557,45
-24933,1518445146202,44
-24934,1518445297549,53
-24935,1518445502238,52
-24936,1518445515629,50
-24937,1518445587662,57
-24938,1518445687521,56
-24939,1518445742658,55
-24940,1518445984963,55
-24941,1518446219146,52
-24942,1518446374354,50
-24943,1518446432128,48
-24944,1518446473662,48
-24945,1518446647180,48
-24946,1518446724927,45
-24947,1518446827136,44
-24948,1518446918601,41
-24949,1518446981112,39
-24950,1518447245911,38
-24951,1518447338177,35
-24952,1518447527217,35
-24953,1518447592878,32
-24954,1518447657970,32
-24955,1518447726441,31
-24956,1518447770995,29
-24957,1518447889451,28
-24958,1518448033970,27
-24959,1518448099684,24
-24960,1518448141663,24
-24961,1518448193556,23
-24962,1518448332267,22
-24963,1518448413401,23
-24964,1518448473654,22
-24965,1518448547268,21
-24966,1518448583874,21
-24967,1518448649203,20
-24968,1518448714478,19
-24969,1518448757429,18
-24970,1518448804002,17
-24971,1518448900667,17
-24972,1518448934858,20
-24973,1518448995106,22
-24974,1518449044408,20
-24975,1518449122584,21
-24976,1518449198070,21
-24977,1518449221292,20
-24978,1518449260274,23
-24979,1518449336296,23
-24980,1518449454586,22
-24981,1518449478971,22
-24982,1518449550480,23
-24983,1518449586161,22
-24984,1518449639401,22
-24985,1518449706521,20
-24986,1518449744276,19
-24987,1518449782257,19
-24988,1518449806644,19
-24989,1518449822629,19
-24990,1518449877405,21
-24991,1518449905315,21
-24992,1518450045811,21
-24993,1518450110197,20
-24994,1518450136842,20
-24995,1518450172566,27
-24996,1518450301096,27
-24997,1518450450744,26
-24998,1518450636360,25
-24999,1518450671063,24
-25000,1518450756179,24
-25001,1518450782433,23
-25002,1518450814162,23
-25003,1518450893315,25
-25004,1518450977967,24
-25005,1518451072628,25
-25006,1518451154021,24
-25007,1518451203730,23
-25008,1518451373607,22
-25009,1518451484545,23
-25010,1518451513416,22
-25011,1518451610816,22
-25012,1518451652409,22
-25013,1518451670307,20
-25014,1518451793209,23
-25015,1518451864292,22
-25016,1518451905985,21
-25017,1518452075997,22
-25018,1518452147183,20
-25019,1518452254287,20
-25020,1518452287288,19
-25021,1518452323841,18
-25022,1518452333831,18
-25023,1518452419118,21
-25024,1518452497228,20
-25025,1518452542684,20
-25026,1518452608538,21
-25027,1518452619333,19
-25028,1518452693173,23
-25029,1518452808867,23
-25030,1518452877856,22
-25031,1518452896650,21
-25032,1518452973109,22
-25033,1518452993363,22
-25034,1518453005286,28
-25035,1518453081251,31
-25036,1518453120561,31
-25037,1518453221831,36
-25038,1518453256804,36
-25039,1518453563587,38
-25040,1518453694876,37
-25041,1518453830399,36
-25042,1518454190874,35
-25043,1518454232272,34
-25044,1518454290825,35
-25045,1518454355194,36
-25046,1518454525381,36
-25047,1518454576717,35
-25048,1518454674641,36
-25049,1518454743774,35
-25050,1518454864608,36
-25051,1518454923755,35
-25052,1518454992796,35
-25053,1518455079588,35
-25054,1518455205895,34
-25055,1518455282879,34
-25056,1518455359510,34
-25057,1518455524015,34
-25058,1518455554619,34
-25059,1518455610913,34
-25060,1518455649216,35
-25061,1518455814405,36
-25062,1518455958224,34
-25063,1518456055456,33
-25064,1518456090828,34
-25065,1518456141833,34
-25066,1518456195675,34
-25067,1518456295740,34
-25068,1518456427000,34
-25069,1518456532315,33
-25070,1518456606549,32
-25071,1518456644912,32
-25072,1518456752530,33
-25073,1518456790879,32
-25074,1518456823896,32
-25075,1518456916358,34
-25076,1518456995640,33
-25077,1518457073208,33
-25078,1518457134682,33
-25079,1518457152306,32
-25080,1518457193371,36
-25081,1518457285857,36
-25082,1518457364953,36
-25083,1518457462430,36
-25084,1518457477398,35
-25085,1518457613683,40
-25086,1518457633820,38
-25087,1518457703195,42
-25088,1518457805565,42
-25089,1518457869766,42
-25090,1518458186476,43
-25091,1518458245367,42
-25092,1518458319482,41
-25093,1518458427375,41
-25094,1518458509440,41
-25095,1518458591395,41
-25096,1518458789992,41
-25097,1518458867073,40
-25098,1518458881970,39
-25099,1518459129358,43
-25100,1518459156949,42
-25101,1518459174599,44
-25102,1518459274586,49
-25103,1518459317640,49
-25104,1518459422509,50
-25105,1518459545924,50
-25106,1518459659144,48
-25107,1518459725714,48
-25108,1518459848538,47
-25109,1518459876619,46
-25110,1518460004995,49
-25111,1518460264467,47
-25112,1518460341377,46
-25113,1518460384533,46
-25114,1518460443645,48
-25115,1518460502605,48
-25116,1518460553915,47
-25117,1518460785310,48
-25118,1518460969857,46
-25119,1518461299195,45
-25120,1518461506791,43
-25121,1518461570790,41
-25122,1518461585721,41
-25123,1518461845735,48
-25124,1518462059006,47
-25125,1518462161437,45
-25126,1518462194290,44
-25127,1518462312107,45
-25128,1518462414978,46
-25129,1518462516837,45
-25130,1518462814795,44
-25131,1518463037856,42
-25132,1518463280249,42
-25133,1518463398526,40
-25134,1518463603235,40
-25135,1518463646302,41
-25136,1518463787505,42
-25137,1518463884790,42
-25138,1518463918072,41
-25139,1518464038691,42
-25140,1518464155135,41
-25141,1518464265245,40
-25142,1518464367812,39
-25143,1518464413613,38
-25144,1518464542277,39
-25145,1518464557275,38
-25146,1518464636377,43
-25147,1518464754550,41
-25148,1518464862275,41
-25149,1518464964561,40
-25150,1518464997741,39
-25151,1518465272708,40
-25152,1518465447212,38
-25153,1518465554691,37
-25154,1518465623426,37
-25155,1518465905616,36
-25156,1518466366325,35
-25157,1518466404782,32
-25158,1518466589610,33
-25159,1518466676835,32
-25160,1518466841160,31
-25161,1518466951563,31
-25162,1518467078042,29
-25163,1518467190726,28
-25164,1518467205692,26
-25165,1518467300308,29
-25166,1518467343493,29
-25167,1518467466745,29
-25168,1518467489662,27
-25169,1518467757419,29
-25170,1518467836933,27
-25171,1518467875221,26
-25172,1518468122360,26
-25173,1518468163047,25
-25174,1518468185713,25
-25175,1518468244216,26
-25176,1518468336700,25
-25177,1518468379950,25
-25178,1518468481970,24
-25179,1518468538077,23
-25180,1518468568501,24
-25181,1518468591024,25
-25182,1518468652165,26
-25183,1518468695016,25
-25184,1518468840385,24
-25185,1518468899298,25
-25186,1518468980805,25
-25187,1518469037210,26
-25188,1518469054656,26
-25189,1518469305729,27
-25190,1518469325871,26
-25191,1518469425298,27
-25192,1518469476372,27
-25193,1518469537363,26
-25194,1518469685841,26
-25195,1518469698514,25
-25196,1518469846903,28
-25197,1518469918354,27
-25198,1518469966615,25
-25199,1518470117409,28
-25200,1518470296603,26
-25201,1518470399010,26
-25202,1518470565375,28
-25203,1518470626264,27
-25204,1518470656511,28
-25205,1518470704734,29
-25206,1518470750188,29
-25207,1518470796416,29
-25208,1518470842355,29
-25209,1518470859991,30
-25210,1518470928777,33
-25211,1518470979687,32
-25212,1518471040820,32
-25213,1518471178423,33
-25214,1518471244707,32
-25215,1518471295582,33
-25216,1518471336155,33
-25217,1518471522853,34
-25218,1518471635155,33
-25219,1518471783350,32
-25220,1518471865292,30
-25221,1518472016133,30
-25222,1518472028942,30
-25223,1518472153590,36
-25224,1518472232803,35
-25225,1518472378421,35
-25226,1518472675572,34
-25227,1518472708493,34
-25228,1518472893284,35
-25229,1518472990938,34
-25230,1518473134015,33
-25231,1518473243639,32
-25232,1518473383795,31
-25233,1518473457882,30
-25234,1518473539581,29
-25235,1518473611140,29
-25236,1518473618416,29
-25237,1518473800025,37
-25238,1518473955902,36
-25239,1518474006840,36
-25240,1518474078327,36
-25241,1518474121453,35
-25242,1518474424642,36
-25243,1518474529470,35
-25244,1518474633840,34
-25245,1518474697320,34
-25246,1518474796592,36
-25247,1518474865685,36
-25248,1518474934780,36
-25249,1518474995819,35
-25250,1518475144581,35
-25251,1518475236072,35
-25252,1518475307721,34
-25253,1518475358756,34
-25254,1518475404724,34
-25255,1518475519547,34
-25256,1518475645248,33
-25257,1518475786256,32
-25258,1518475895757,32
-25259,1518475913261,30
-25260,1518476005393,33
-25261,1518476089463,32
-25262,1518476099392,31
-25263,1518476135121,38
-25264,1518476258105,38
-25265,1518476447840,39
-25266,1518476594004,38
-25267,1518476681178,38
-25268,1518476791214,37
-25269,1518476827150,37
-25270,1518476965123,37
-25271,1518477028851,37
-25272,1518477095098,36
-25273,1518477299743,36
-25274,1518477317175,35
-25275,1518477488714,39
-25276,1518477526870,38
-25277,1518477567564,39
-25278,1518477703023,39
-25279,1518477905319,38
-25280,1518477974016,37
-25281,1518477988982,38
-25282,1518478062501,43
-25283,1518478288082,43
-25284,1518478384847,41
-25285,1518478541618,41
-25286,1518478684738,39
-25287,1518478781597,38
-25288,1518478827540,38
-25289,1518479014601,39
-25290,1518479055277,37
-25291,1518479193380,39
-25292,1518479300449,38
-25293,1518479376516,38
-25294,1518479414758,37
-25295,1518479442474,37
-25296,1518479605772,41
-25297,1518479687951,39
-25298,1518479728180,39
-25299,1518479804717,40
-25300,1518479974115,40
-25301,1518480050464,38
-25302,1518480096491,37
-25303,1518480216326,37
-25304,1518480231346,37
-25305,1518480509636,41
-25306,1518480552834,40
-25307,1518480750683,41
-25308,1518480791118,40
-25309,1518480816305,41
-25310,1518480913595,45
-25311,1518480987399,44
-25312,1518481171921,44
-25313,1518481322267,43
-25314,1518481478943,42
-25315,1518481524664,41
-25316,1518481621614,41
-25317,1518481741458,41
-25318,1518481945817,40
-25319,1518482037664,39
-25320,1518482153338,38
-25321,1518482237740,37
-25322,1518482301449,35
-25323,1518482444597,37
-25324,1518482472268,37
-25325,1518482505074,38
-25326,1518482673934,38
-25327,1518482794381,37
-25328,1518482832437,37
-25329,1518482993029,38
-25330,1518483173050,36
-25331,1518483244101,35
-25332,1518483404877,34
-25333,1518483481502,33
-25334,1518483612212,32
-25335,1518483795852,31
-25336,1518483908931,29
-25337,1518483990855,32
-25338,1518484080191,31
-25339,1518484338635,31
-25340,1518484399875,29
-25341,1518484424987,29
-25342,1518484511940,31
-25343,1518484562721,31
-25344,1518484606008,30
-25345,1518484664573,30
-25346,1518484756441,30
-25347,1518484807503,29
-25348,1518484877125,29
-25349,1518484948150,28
-25350,1518485021785,28
-25351,1518485137095,26
-25352,1518485323464,26
-25353,1518485399988,24
-25354,1518485422912,24
-25355,1518485535312,25
-25356,1518485615020,24
-25357,1518485678377,23
-25358,1518485790754,22
-25359,1518485859998,21
-25360,1518485948966,21
-25361,1518486054330,20
-25362,1518486084816,20
-25363,1518486225834,22
-25364,1518486271597,22
-25365,1518486381859,22
-25366,1518486435502,21
-25367,1518486479000,20
-25368,1518486514718,20
-25369,1518486534702,19
-25370,1518486588276,21
-25371,1518486639226,20
-25372,1518486718202,20
-25373,1518486735814,19
-25374,1518486812605,21
-25375,1518486858493,22
-25376,1518486970641,21
-25377,1518487006245,21
-25378,1518487087802,22
-25379,1518487151890,21
-25380,1518487184801,20
-25381,1518487220360,20
-25382,1518487266465,23
-25383,1518487338051,23
-25384,1518487445291,22
-25385,1518487514025,22
-25386,1518487611314,21
-25387,1518487639323,20
-25388,1518487736787,21
-25389,1518487790202,19
-25390,1518487841207,19
-25391,1518487917488,19
-25392,1518487939993,19
-25393,1518488091432,20
-25394,1518488131888,18
-25395,1518488174909,19
-25396,1518488212950,19
-25397,1518488272140,19
-25398,1518488302569,19
-25399,1518488463977,20
-25400,1518488494292,20
-25401,1518488547872,19
-25402,1518488573041,20
-25403,1518488588144,20
-25404,1518488603354,22
-25405,1518488620828,27
-25406,1518488707119,29
-25407,1518488899476,29
-25408,1518488914519,29
-25409,1518488973140,33
-25410,1518489124299,34
-25411,1518489277845,33
-25412,1518489303194,33
-25413,1518489394696,35
-25414,1518489571496,34
-25415,1518489738398,33
-25416,1518489781566,33
-25417,1518489812019,34
-25418,1518489898522,35
-25419,1518489992739,35
-25420,1518490033375,34
-25421,1518490117502,35
-25422,1518490132473,35
-25423,1518490229490,39
-25424,1518490275313,39
-25425,1518490367807,40
-25426,1518490524364,42
-25427,1518490603518,41
-25428,1518490734176,40
-25429,1518491044632,41
-25430,1518491281891,39
-25431,1518491412281,38
-25432,1518491481059,37
-25433,1518491529251,37
-25434,1518491610910,38
-25435,1518491682628,37
-25436,1518491704983,37
-25437,1518491840514,40
-25438,1518491888891,38
-25439,1518492042729,40
-25440,1518492201241,38
-25441,1518492277936,38
-25442,1518492382681,38
-25443,1518492551620,38
-25444,1518492602466,37
-25445,1518492678704,38
-25446,1518492791535,38
-25447,1518492845447,37
-25448,1518492947646,38
-25449,1518493106467,37
-25450,1518493124011,36
-25451,1518493233959,40
-25452,1518493264300,39
-25453,1518493351807,41
-25454,1518493371717,40
-25455,1518493428172,45
-25456,1518493613015,45
-25457,1518493627859,44
-25458,1518493686784,49
-25459,1518493750856,50
-25460,1518493794195,49
-25461,1518494016851,50
-25462,1518494160233,49
-25463,1518494224618,48
-25464,1518494344316,48
-25465,1518494359183,48
-25466,1518494520876,53
-25467,1518494658700,52
-25468,1518495132772,52
-25469,1518495311785,50
-25470,1518495324398,50
-25471,1518495352598,57
-25472,1518495498667,60
-25473,1518496037233,59
-25474,1518496390859,58
-25475,1518496523662,56
-25476,1518496676810,56
-25477,1518496755964,55
-25478,1518496875939,55
-25479,1518497188331,53
-25480,1518497347108,52
-25481,1518497388160,51
-25482,1518497593331,53
-25483,1518498085137,51
-25484,1518498334029,50
-25485,1518498405510,48
-25486,1518498671037,47
-25487,1518498865393,46
-25488,1518498903601,44
-25489,1518498980186,45
-25490,1518499023188,45
-25491,1518499207448,45
-25492,1518499276201,44
-25493,1518499464886,43
-25494,1518499664453,42
-25495,1518499948301,40
-25496,1518500053815,38
-25497,1518500127806,38
-25498,1518500155584,37
-25499,1518500252823,39
-25500,1518500306025,37
-25501,1518500341604,37
-25502,1518500553657,38
-25503,1518500643058,36
-25504,1518500732695,37
-25505,1518500778573,37
-25506,1518500965263,39
-25507,1518501085487,37
-25508,1518501151985,35
-25509,1518501174476,37
-25510,1518501276401,38
-25511,1518501352726,38
-25512,1518501560294,37
-25513,1518501603848,37
-25514,1518501680440,36
-25515,1518501748856,36
-25516,1518501869352,34
-25517,1518501902577,34
-25518,1518502017083,35
-25519,1518502042491,34
-25520,1518502108810,35
-25521,1518502406497,35
-25522,1518502478220,33
-25523,1518502521954,35
-25524,1518502595631,35
-25525,1518502670047,36
-25526,1518502758662,35
-25527,1518502773526,34
-25528,1518503034878,38
-25529,1518503103712,36
-25530,1518503157261,35
-25531,1518503328390,34
-25532,1518503510394,32
-25533,1518503573869,31
-25534,1518503714412,31
-25535,1518503739944,29
-25536,1518503770678,30
-25537,1518503832142,33
-25538,1518503937423,32
-25539,1518503996023,31
-25540,1518504008746,31
-25541,1518504139114,34
-25542,1518504320904,33
-25543,1518504373575,32
-25544,1518504637168,31
-25545,1518504734411,30
-25546,1518505378746,29
-25547,1518505413268,26
-25548,1518505465548,27
-25549,1518505512897,26
-25550,1518505606435,25
-25551,1518505890694,26
-25552,1518506049170,24
-25553,1518506073757,24
-25554,1518506124120,25
-25555,1518506149723,26
-25556,1518506253500,27
-25557,1518506374513,26
-25558,1518506426091,27
-25559,1518506548938,27
-25560,1518506560249,26
-25561,1518506634678,32
-25562,1518506674787,30
-25563,1518506712481,30
-25564,1518506809371,31
-25565,1518506860748,30
-25566,1518506885617,33
-25567,1518506933664,35
-25568,1518507248751,35
-25569,1518507340683,33
-25570,1518507454758,32
-25571,1518507536100,36
-25572,1518507693312,37
-25573,1518507706205,36
-25574,1518507788494,41
-25575,1518507928085,40
-25576,1518508050868,39
-25577,1518508059040,38
-25578,1518508104563,49
-25579,1518508197781,49
-25580,1518508677079,48
-25581,1518508923778,47
-25582,1518508973700,47
-25583,1518509012761,48
-25584,1518509069364,48
-25585,1518509135143,48
-25586,1518509210074,48
-25587,1518509370732,48
-25588,1518509451653,46
-25589,1518509564324,46
-25590,1518509742661,46
-25591,1518509761715,46
-25592,1518509933496,50
-25593,1518510032610,49
-25594,1518510196612,48
-25595,1518510351634,46
-25596,1518510442252,45
-25597,1518510539766,45
-25598,1518510877575,44
-25599,1518510993079,43
-25600,1518511128966,43
-25601,1518511152726,41
-25602,1518511230024,44
-25603,1518511322845,44
-25604,1518511348779,43
-25605,1518511452220,45
-25606,1518511548028,46
-25607,1518521641884,44
-25608,1518521705233,42
-25609,1518521771083,42
-25610,1518521981929,43
-25611,1518522124165,42
-25612,1518522135582,41
-25613,1518522438603,48
-25614,1518522567161,46
-25615,1518522650096,45
-25616,1518522666570,45
-25617,1518522759951,49
-25618,1518522860131,49
-25619,1518522965858,48
-25620,1518523056774,48
-25621,1518523240657,48
-25622,1518523532510,46
-25623,1518523865266,45
-25624,1518523887725,44
-25625,1518523968856,46
-25626,1518524037840,46
-25627,1518524168934,45
-25628,1518524459105,46
-25629,1518524555701,44
-25630,1518524756453,44
-25631,1518524877008,43
-25632,1518525000270,42
-25633,1518525101836,40
-25634,1518525206888,39
-25635,1518525488532,38
-25636,1518525678378,38
-25637,1518525822050,36
-25638,1518525961288,36
-25639,1518526033087,35
-25640,1518526116089,34
-25641,1518526178734,35
-25642,1518526304029,35
-25643,1518526358756,33
-25644,1518526454766,34
-25645,1518526488220,32
-25646,1518526508505,33
-25647,1518526549155,34
-25648,1518526560613,34
-25649,1518526724565,40
-25650,1518526807922,39
-25651,1518526960966,37
-25652,1518527120864,36
-25653,1518527400319,34
-25654,1518527564023,33
-25655,1518527613009,32
-25656,1518527668879,32
-25657,1518527740622,31
-25658,1518527783433,30
-25659,1518527826619,30
-25660,1518527889500,30
-25661,1518528070074,31
-25662,1518528130214,29
-25663,1518528343201,30
-25664,1518528384339,29
-25665,1518528509580,28
-25666,1518528583039,27
-25667,1518528648164,27
-25668,1518528687743,26
-25669,1518528786650,26
-25670,1518528803112,24
-25671,1518528868567,27
-25672,1518528959358,26
-25673,1518528975734,24
-25674,1518529026317,29
-25675,1518529155030,28
-25676,1518529171103,27
-25677,1518529510226,29
-25678,1518529560233,32
-25679,1518529614241,33
-25680,1518529767913,34
-25681,1518529881452,32
-25682,1518530102714,30
-25683,1518530205737,29
-25684,1518530228121,30
-25685,1518530289951,32
-25686,1518530344167,32
-25687,1518530403844,32
-25688,1518530452364,32
-25689,1518530535261,32
-25690,1518530606807,31
-25691,1518530656099,30
-25692,1518530692619,32
-25693,1518530925022,33
-25694,1518530999873,32
-25695,1518531165800,31
-25696,1518531254882,29
-25697,1518531278890,29
-25698,1518531485148,29
-25699,1518531534200,28
-25700,1518531625969,28
-25701,1518531661396,27
-25702,1518531872558,29
-25703,1518531956128,28
-25704,1518532114929,27
-25705,1518532213365,28
-25706,1518532299216,26
-25707,1518532327384,26
-25708,1518532418767,26
-25709,1518532464403,26
-25710,1518532550474,26
-25711,1518532647747,25
-25712,1518532815536,23
-25713,1518532852424,26
-25714,1518532990416,26
-25715,1518533038792,25
-25716,1518533139173,25
-25717,1518533228765,27
-25718,1518533246789,27
-25719,1518533330464,29
-25720,1518533559403,29
-25721,1518533655934,28
-25722,1518533708281,27
-25723,1518533828145,26
-25724,1518533869382,26
-25725,1518533922757,27
-25726,1518534027705,27
-25727,1518534152376,27
-25728,1518534234851,26
-25729,1518534380770,26
-25730,1518534414904,24
-25731,1518534446828,24
-25732,1518534498456,25
-25733,1518534544237,25
-25734,1518534625973,25
-25735,1518534679539,24
-25736,1518534752900,24
-25737,1518534843973,23
-25738,1518534858562,22
-25739,1518535028292,24
-25740,1518535036471,23
-25741,1518535050968,29
-25742,1518535107196,32
-25743,1518535172108,32
-25744,1518535365174,31
-25745,1518535392571,31
-25746,1518535469792,32
-25747,1518535660390,33
-25748,1518535806831,33
-25749,1518536044152,35
-25750,1518536334819,34
-25751,1518536433720,33
-25752,1518536460064,32
-25753,1518536583917,33
-25754,1518536614607,32
-25755,1518536705049,33
-25756,1518547955097,33
-25757,1518548048051,32
-25758,1518548099998,31
-25759,1518548224689,32
-25760,1518548368606,31
-25761,1518548425513,30
-25762,1518548587446,30
-25763,1518548640876,29
-25764,1518548795920,29
-25765,1518548862251,29
-25766,1518548991430,28
-25767,1518549029567,27
-25768,1518549177355,28
-25769,1518549295461,26
-25770,1518549414862,25
-25771,1518549559566,26
-25772,1518549612087,26
-25773,1518549649098,25
-25774,1518549664266,26
-25775,1518549762648,30
-25776,1518549858481,29
-25777,1518549948876,30
-25778,1518549981619,29
-25779,1518550006857,30
-25780,1518550125048,32
-25781,1518550198283,31
-25782,1518550465386,31
-25783,1518550597943,29
-25784,1518550622572,29
-25785,1518550707768,31
-25786,1518550780705,30
-25787,1518550941668,30
-25788,1518550997421,31
-25789,1518551081426,31
-25790,1518551113092,30
-25791,1518551243082,31
-25792,1518551300673,31
-25793,1518551337059,31
-25794,1518551419970,31
-25795,1518551493887,31
-25796,1518551812407,31
-25797,1518551888041,30
-25798,1518551948693,30
-25799,1518551996094,30
-25800,1518552171548,30
-25801,1518552199682,29
-25802,1518552420559,31
-25803,1518552483269,30
-25804,1518552531835,30
-25805,1518552657498,30
-25806,1518552741951,28
-25807,1518552851361,28
-25808,1518552940665,28
-25809,1518553060669,28
-25810,1518553134559,26
-25811,1518553143881,26
-25812,1518553226969,31
-25813,1518553337327,31
-25814,1518553413824,30
-25815,1518553510634,29
-25816,1518553607179,29
-25817,1518553670828,28
-25818,1518553792870,28
-25819,1518553856348,28
-25820,1518553895463,28
-25821,1518554023739,28
-25822,1518554066048,27
-25823,1518554272978,28
-25824,1518554284607,27
-25825,1518554324128,30
-25826,1518554407228,31
-25827,1518554418270,31
-25828,1518554497290,36
-25829,1518554539271,35
-25830,1518554563236,36
-25831,1518554874110,38
-25832,1518554923133,37
-25833,1518555014938,37
-25834,1518555111175,37
-25835,1518555192120,36
-25836,1518555313234,36
-25837,1518555465628,35
-25838,1518555726337,34
-25839,1518555961768,34
-25840,1518556043849,33
-25841,1518556087793,35
-25842,1518556116629,37
-25843,1518556264425,39
-25844,1518556287421,39
-25845,1518556418390,41
-25846,1518556542044,41
-25847,1518556625331,41
-25848,1518556705458,40
-25849,1518556800614,39
-25850,1518556990221,39
-25851,1518557226561,38
-25852,1518557265208,36
-25853,1518557328875,38
-25854,1518557568094,38
-25855,1518557791248,38
-25856,1518557881139,36
-25857,1518557995877,36
-25858,1518558050044,35
-25859,1518558131448,35
-25860,1518558298216,35
-25861,1518558382974,34
-25862,1518558530013,33
-25863,1518558670502,32
-25864,1518558722633,32
-25865,1518558842329,32
-25866,1518559034617,30
-25867,1518559089242,30
-25868,1518559321785,29
-25869,1518559336816,28
-25870,1518559405750,31
-25871,1518559417559,31
-25872,1518559455232,35
-25873,1518559492240,36
-25874,1518559568696,37
-25875,1518559784833,39
-25876,1518559904461,37
-25877,1518560233818,36
-25878,1518560403507,34
-25879,1518560530483,34
-25880,1518560626582,35
-25881,1518560704593,34
-25882,1518602689308,34
-25883,1518602737796,31
-25884,1518602881794,32
-25885,1518602949626,31
-25886,1518603059727,31
-25887,1518603113239,30
-25888,1518603171756,30
-25889,1518603188118,30
-25890,1518603314557,33
-25891,1518603389038,31
-25892,1518603537434,32
-25893,1518603593363,31
-25894,1518613928461,31
-25895,1518614093644,29
-25896,1518614369160,29
-25897,1518614471150,27
-25898,1518614771283,27
-25899,1518614954106,25
-25900,1518615030860,24
-25901,1518615443484,23
-25902,1518615512145,23
-25903,1518615542238,22
-25904,1518615683774,22
-25905,1518615880480,22
-25906,1518615955240,20
-25907,1518615998331,20
-25908,1518616121006,19
-25909,1518616150606,18
-25910,1518616247900,17
-25911,1518616291837,17
-25912,1518616374846,19
-25913,1518616415807,19
-25914,1518616476745,18
-25915,1518616601910,17
-25916,1518616662666,17
-25917,1518616738712,16
-25918,1518616794815,15
-25919,1518616956661,14
-25920,1518617050413,13
-25921,1518617125558,12
-25922,1518617191613,12
-25923,1518617209431,11
-25924,1518617259103,10
-25925,1518617312475,13
-25926,1518617332591,12
-25927,1518617405444,13
-25928,1518617441947,15
-25929,1518617486394,15
-25930,1518617508853,15
-25931,1518617580596,17
-25932,1518617691132,16
-25933,1518617735739,16
-25934,1518617762348,16
-25935,1518617776783,16
-25936,1518617844638,18
-25937,1518618009039,17
-25938,1518618036348,16
-25939,1518618058306,17
-25940,1518618098014,17
-25941,1518618110397,17
-25942,1518618178640,20
-25943,1518618196865,21
-25944,1518618257225,22
-25945,1518618362509,23
-25946,1518618513306,23
-25947,1518618558442,23
-25948,1518618613356,23
-25949,1518618749258,22
-25950,1518618790075,22
-25951,1518618857580,22
-25952,1518618900905,22
-25953,1518619043994,22
-25954,1518619092992,22
-25955,1518619112299,21
-25956,1518619124762,23
-25957,1518619159360,27
-25958,1518619275736,27
-25959,1518619304367,27
-25960,1518619346207,28
-25961,1518619379294,28
-25962,1518619468690,29
-25963,1518619583125,28
-25964,1518619668274,27
-25965,1518619869289,27
-25966,1518619953152,27
-25967,1518619979968,26
-25968,1518620323493,27
-25969,1518620412355,26
-25970,1518620502722,28
-25971,1518620648664,27
-25972,1518620695359,29
-25973,1518620827233,31
-25974,1518620957065,30
-25975,1518621022877,31
-25976,1518621176925,30
-25977,1518621246740,30
-25978,1518621387895,29
-25979,1518621529368,29
-25980,1518621714059,28
-25981,1518621893975,27
-25982,1518621993308,26
-25983,1518622024714,26
-25984,1518622118002,28
-25985,1518622290730,27
-25986,1518622343503,26
-25987,1518622508075,27
-25988,1518622684533,26
-25989,1518622747310,25
-25990,1518622827659,27
-25991,1518622916419,27
-25992,1518622962946,26
-25993,1518623118905,27
-25994,1518623154633,26
-25995,1518623239782,27
-25996,1518623276471,27
-25997,1518623437603,27
-25998,1518623535889,26
-25999,1518623698532,26
-26000,1518623737490,25
-26001,1518623783335,25
-26002,1518623951748,25
-26003,1518624046402,24
-26004,1518624197024,25
-26005,1518624220381,23
-26006,1518624242725,24
-26007,1518624273857,26
-26008,1518624314738,28
-26009,1518624330195,28
-26010,1518624372921,31
-26011,1518624448778,32
-26012,1518624682844,31
-26013,1518624871893,31
-26014,1518624932528,30
-26015,1518625059256,30
-26016,1518625151603,29
-26017,1518625326655,28
-26018,1518637335279,27
-26019,1518637363877,26
-26020,1518637401275,27
-26021,1518637546938,27
-26022,1518637662421,26
-26023,1518637763307,25
-26024,1518637863581,25
-26025,1518637991211,24
-26026,1518638064350,23
-26027,1518638193748,23
-26028,1518638212976,23
-26029,1518638257196,24
-26030,1518638356345,24
-26031,1518638390071,24
-26032,1518638596066,24
-26033,1518638636643,23
-26034,1518638791898,22
-26035,1518638817533,23
-26036,1518638907249,24
-26037,1518638973943,23
-26038,1518639048199,23
-26039,1518639125080,23
-26040,1518639227525,23
-26041,1518639387047,22
-26042,1518639438396,22
-26043,1518639456118,22
-26044,1518639558292,25
-26045,1518639597369,25
-26046,1518639646976,25
-26047,1518639828029,24
-26048,1518640039430,24
-26049,1518640125327,23
-26050,1518640153303,22
-26051,1518640268738,24
-26052,1518640295746,23
-26053,1518640331308,24
-26054,1518640455340,24
-26055,1518640538451,24
-26056,1518640674598,24
-26057,1518640704550,25
-26058,1518640756727,26
-26059,1518640818946,26
-26060,1518640877525,28
-26061,1518640937355,27
-26062,1518640954137,28
-26063,1518640995188,31
-26064,1518641078599,32
-26065,1518641111896,31
-26066,1518641303237,32
-26067,1518641355609,32
-26068,1518641474890,33
-26069,1518641614752,31
-26070,1518641693663,32
-26071,1518641822764,31
-26072,1518641963984,30
-26073,1518677579219,30
-26074,1518677718291,28
-26075,1518677795054,28
-26076,1518677918785,28
-26077,1518677996367,27
-26078,1518678042248,26
-26079,1518678062862,27
-26080,1518678157533,29
-26081,1518678255566,28
-26082,1518678475074,27
-26083,1518678609269,26
-26084,1518678686481,26
-26085,1518678794602,25
-26086,1518678984426,25
-26087,1518679142446,24
-26088,1518679257230,24
-26089,1518679355892,22
-26090,1518679422071,22
-26091,1518679463668,21
-26092,1518679472179,21
-26093,1518679562699,26
-26094,1518679745086,25
-26095,1518679806420,26
-26096,1518679853879,25
-26097,1518679865248,25
-26098,1518679877062,29
-26099,1518679917520,34
-26100,1518679983829,35
-26101,1518680075198,34
-26102,1518680220645,34
-26103,1518680262470,33
-26104,1518680335690,33
-26105,1518680367683,33
-26106,1518680475438,35
-26107,1518680625451,35
-26108,1518680664918,35
-26109,1518680851747,37
-26110,1518681115314,37
-26111,1518681182944,37
-26112,1518681402626,37
-26113,1518681423357,36
-26114,1518681474862,39
-26115,1518681546527,39
-26116,1518681672699,39
-26117,1518681899638,38
-26118,1518682011622,37
-26119,1518682169841,36
-26120,1518682209291,35
-26121,1518682445915,37
-26122,1518682601530,36
-26123,1518682702273,35
-26124,1518682886766,34
-26125,1518682901871,34
-26126,1518682918418,37
-26127,1518683054260,42
-26128,1518683091613,40
-26129,1518683210495,42
-26130,1518683345039,42
-26131,1518683469451,41
-26132,1518683502998,41
-26133,1518683656645,42
-26134,1518683773437,42
-26135,1518683889417,40
-26136,1518683975154,40
-26137,1518684004235,39
-26138,1518684114610,42
-26139,1518684182073,41
-26140,1518684545805,41
-26141,1518684598373,39
-26142,1518684847415,39
-26143,1518685106344,38
-26144,1518685206761,38
-26145,1518685334580,37
-26146,1518685357681,36
-26147,1518685458524,39
-26148,1518685497994,38
-26149,1518685568101,38
-26150,1518685626691,38
-26151,1518685758708,39
-26152,1518686043366,38
-26153,1518686135198,37
-26154,1518686178936,37
-26155,1518686265667,37
-26156,1518686602014,37
-26157,1518686664360,35
-26158,1518686808988,35
-26159,1518687062549,34
-26160,1518687158095,33
-26161,1518687329010,33
-26162,1518687560241,32
-26163,1518687693649,32
-26164,1518687821486,32
-26165,1518687926526,31
-26166,1518687990508,31
-26167,1518688230087,30
-26168,1518688238338,30
-26169,1518688389447,36
-26170,1518688415691,36
-26171,1518688518741,38
-26172,1518688631091,37
-26173,1518688818004,35
-26174,1518689071655,34
-26175,1518689274775,33
-26176,1518689353137,32
-26177,1518689529399,31
-26178,1518689710447,29
-26179,1518689865105,28
-26180,1518689956620,28
-26181,1518690028005,28
-26182,1518690124015,26
-26183,1518690320374,26
-26184,1518690407449,24
-26185,1518690455328,23
-26186,1518690521795,23
-26187,1518690633041,22
-26188,1518690689712,20
-26189,1518690818552,19
-26190,1518690876340,18
-26191,1518690898521,17
-26192,1518690917923,17
-26193,1518690963281,21
-26194,1518690986336,20
-26195,1518691094845,21
-26196,1518691113006,19
-26197,1518691212928,20
-26198,1518691294364,22
-26199,1518691397420,24
-26200,1518691451065,23
-26201,1518691565819,23
-26202,1518691711837,22
-26203,1518691758945,21
-26204,1518691807082,22
-26205,1518691886503,21
-26206,1518692032767,22
-26207,1518692084559,20
-26208,1518692155205,20
-26209,1518692194382,20
-26210,1518692222577,19
-26211,1518692259183,19
-26212,1518692282632,20
-26213,1518692321184,20
-26214,1518692398163,22
-26215,1518692447229,21
-26216,1518692472801,21
-26217,1518692645761,22
-26218,1518692676028,21
-26219,1518692755402,21
-26220,1518692828840,20
-26221,1518692853733,20
-26222,1518692993123,21
-26223,1518693057620,19
-26224,1518693073628,19
-26225,1518693135354,21
-26226,1518693329320,22
-26227,1518693389422,23
-26228,1518693450326,23
-26229,1518693469528,24
-26230,1518693516519,25
-26231,1518693551476,26
-26232,1518693618263,26
-26233,1518693705513,26
-26234,1518693816310,26
-26235,1518693938744,26
-26236,1518694132226,25
-26237,1518694200605,24
-26238,1518694400196,25
-26239,1518694422424,24
-26240,1518694512934,25
-26241,1518694657405,25
-26242,1518694711848,25
-26243,1518694803172,24
-26244,1518694894183,24
-26245,1518694929024,23
-26246,1518695065781,23
-26247,1518695163571,24
-26248,1518695239175,23
-26249,1518695278202,24
-26250,1518695331139,24
-26251,1518695361822,24
-26252,1518695545219,25
-26253,1518695648791,25
-26254,1518695660457,24
-26255,1518695743562,28
-26256,1518695833549,28
-26257,1518695979324,28
-26258,1518696113737,27
-26259,1518696270179,26
-26260,1518696333538,25
-26261,1518696427687,25
-26262,1518696443646,24
-26263,1518696521575,26
-26264,1518696589527,25
-26265,1518696700162,26
-26266,1518696757481,24
-26267,1518696845730,24
-26268,1518696898071,24
-26269,1518696995551,28
-26270,1518697155407,27
-26271,1518697215638,28
-26272,1518697467144,28
-26273,1518697564698,27
-26274,1518697624887,27
-26275,1518697774133,27
-26276,1518697806512,26
-26277,1518697924067,27
-26278,1518698119794,25
-26279,1518698340159,25
-26280,1518698421395,24
-26281,1518698460737,24
-26282,1518698535219,24
-26283,1518698565089,23
-26284,1518698791123,23
-26285,1518698848339,22
-26286,1518698859950,23
-26287,1518698891454,26
-26288,1518699015697,27
-26289,1518699025437,27
-26290,1518699150054,31
-26291,1518699226665,30
-26292,1518699268056,31
-26293,1518699380095,33
-26294,1518699430787,32
-26295,1518699501322,33
-26296,1518699705777,32
-26297,1518699830554,32
-26298,1518699902274,32
-26299,1518699938095,31
-26300,1518699995742,32
-26301,1518700076744,32
-26302,1518700220234,32
-26303,1518700288620,30
-26304,1518700319487,30
-26305,1518700385927,32
-26306,1518700470063,32
-26307,1518700530362,31
-26308,1518700612007,31
-26309,1518700688544,31
-26310,1518700896235,30
-26311,1518701005635,29
-26312,1518701260074,30
-26313,1518701844933,29
-26314,1518702031402,28
-26315,1518702103701,27
-26316,1518702147101,26
-26317,1518702171547,28
-26318,1518702301948,29
-26319,1518702388162,28
-26320,1518702443459,28
-26321,1518702596102,28
-26322,1518702639871,28
-26323,1518702761019,28
-26324,1518702796808,27
-26325,1518702850598,29
-26326,1518702918237,29
-26327,1518702976208,28
-26328,1518703075300,29
-26329,1518703116831,28
-26330,1518703154454,29
-26331,1518703194209,30
-26332,1518703264704,31
-26333,1518703281199,31
-26334,1518703307396,35
-26335,1518703416851,36
-26336,1518703448405,35
-26337,1518703501889,36
-26338,1518703564463,36
-26339,1518703710322,36
-26340,1518703764443,36
-26341,1518703818362,36
-26342,1518703852281,36
-26343,1518704008776,38
-26344,1518704156119,37
-26345,1518704317950,36
-26346,1518704422344,35
-26347,1518704531131,34
-26348,1518704714839,33
-26349,1518704802988,33
-26350,1518704883275,33
-26351,1518705014726,32
-26352,1518705289518,32
-26353,1518705407424,31
-26354,1518705474642,29
-26355,1518705652388,32
-26356,1518705811282,30
-26357,1518705882527,29
-26358,1518706166467,29
-26359,1518710570740,28
-26360,1518710600940,26
-26361,1518710612681,27
-26362,1518710616545,31
-26363,1518710639278,51
-26364,1518710677607,54
-26365,1518710703269,55
-26366,1518710848622,60
-26367,1518711010027,59
-26368,1518711152063,57
-26369,1518711198838,57
-26370,1518711322328,58
-26371,1518711492999,57
-26372,1518711553527,56
-26373,1518711589799,56
-26374,1518711814655,57
-26375,1518711851193,56
-26376,1518711874005,58
-26377,1518712010452,63
-26378,1518712119603,62
-26379,1518712178593,61
-26380,1518712517512,61
-26381,1518712526711,60
-26382,1518712843852,73
-26383,1518712917560,72
-26384,1518712940601,72
-26385,1518715786530,77
-26386,1518716079192,75
-26387,1518716355603,74
-26388,1518717498776,74
-26389,1518717743409,71
-26390,1518717826043,73
-26391,1518717913505,72
-26392,1518718039473,72
-26393,1518718368679,72
-26394,1518718383040,70
-26395,1518718602419,80
-26396,1518718945833,78
-26397,1518719475654,76
-26398,1518719682572,74
-26399,1518719952228,73
-26400,1518720147561,72
-26401,1518720271994,70
-26402,1518720424608,70
-26403,1518720694276,68
-26404,1518720773918,66
-26405,1518720890089,67
-26406,1518721126233,66
-26407,1518721285627,64
-26408,1518721484477,63
-26409,1518721595187,62
-26410,1518721696911,61
-26411,1518721890828,59
-26412,1518721974104,57
-26413,1518722145627,57
-26414,1518722357793,54
-26415,1518722622431,52
-26416,1518722665889,50
-26417,1518722760389,51
-26418,1518722800616,51
-26419,1518722855675,51
-26420,1518722982504,51
-26421,1518723026479,50
-26422,1518723180027,50
-26423,1518723384183,49
-26424,1518723703640,46
-26425,1518723772079,44
-26426,1518724117027,44
-26427,1518724221507,42
-26428,1518724358008,40
-26429,1518724416831,39
-26430,1518724473869,38
-26431,1518724640510,38
-26432,1518724795683,37
-26433,1518724822153,35
-26434,1518724839481,37
-26435,1518725038139,41
-26436,1518725134093,39
-26437,1518725178396,39
-26438,1518725213331,38
-26439,1518725547117,39
-26440,1518725668258,37
-26441,1518725740497,35
-26442,1518725928497,35
-26443,1518726082437,34
-26444,1518726214973,32
-26445,1518726339418,30
-26446,1518726419725,28
-26447,1518726464975,27
-26448,1518726591096,25
-26449,1518726671436,23
-26450,1518726835412,21
-26451,1518726944733,19
-26452,1518726970312,18
-26453,1518727093162,16
-26454,1518727222380,14
-26455,1518727276847,12
-26456,1518727317936,11
-26457,1518727325788,8
-26458,1518727367533,8
-26459,1518727395962,6
-26460,1518727440596,4
-26461,1518727463989,2
-26462,1518727471805,2
-26463,1518727485103,10
-26464,1518727493913,12
-26465,1518727526650,15
-26466,1518727558150,16
-26467,1518727652521,15
-26468,1518727730094,14
-26469,1518727765872,13
-26470,1518727810520,13
-26471,1518727871361,12
-26472,1518727897216,10
-26473,1518727924318,10
-26474,1518727947402,11
-26475,1518728045388,10
-26476,1518728144819,10
-26477,1518728159659,11
-26478,1518728198228,11
-26479,1518728253951,10
-26480,1518728307404,10
-26481,1518728349395,8
-26482,1518728381225,15
-26483,1518728395567,15
-26484,1518728407151,17
-26485,1518728465001,22
-26486,1518728530225,21
-26487,1518728649965,21
-26488,1518728782912,19
-26489,1518728894034,18
-26490,1518728961185,17
-26491,1518728993268,17
-26492,1518729029039,18
-26493,1518729115782,18
-26494,1518729167617,16
-26495,1518729222071,22
-26496,1518729263271,21
-26497,1518729335697,21
-26498,1518729401357,20
-26499,1518729507392,20
-26500,1518729519140,20
-26501,1518729580611,22
-26502,1518729627913,22
-26503,1518729717650,22
-26504,1518729796823,22
-26505,1518729914356,21
-26506,1518730012906,21
-26507,1518730021654,20
-26508,1518730139486,24
-26509,1518730181523,23
-26510,1518730219937,24
-26511,1518730271149,25
-26512,1518730368658,24
-26513,1518730441343,24
-26514,1518730657819,23
-26515,1518730728560,23
-26516,1518730759122,22
-26517,1518730827659,24
-26518,1518730858901,24
-26519,1518731012509,26
-26520,1518731030282,25
-26521,1518731193453,28
-26522,1518731286811,27
-26523,1518731307272,27
-26524,1518731347065,29
-26525,1518731413620,29
-26526,1518731524123,29
-26527,1518731630621,28
-26528,1518731766027,28
-26529,1518731820397,27
-26530,1518731893165,28
-26531,1518732027591,28
-26532,1518732038818,27
-26533,1518732109137,31
-26534,1518732211497,33
-26535,1518732293900,34
-26536,1518732402470,34
-26537,1518732502199,33
-26538,1518732527948,34
-26539,1518732595758,36
-26540,1518732804416,36
-26541,1518732882507,35
-26542,1518732982126,36
-26543,1518733076603,35
-26544,1518733103121,34
-26545,1518733168791,36
-26546,1518733271838,36
-26547,1518733348720,36
-26548,1518733436092,36
-26549,1518733724525,36
-26550,1518733851710,35
-26551,1518734019641,34
-26552,1518734163175,33
-26553,1518734232290,32
-26554,1518734265850,32
-26555,1518734316556,33
-26556,1518734391832,33
-26557,1518734453910,33
-26558,1518734541311,33
-26559,1518734634863,33
-26560,1518734722131,33
-26561,1518734791318,32
-26562,1518734839155,31
-26563,1518734981069,31
-26564,1518735146148,31
-26565,1518735237203,32
-26566,1518735384878,31
-26567,1518735442990,31
-26568,1518735721245,30
-26569,1518735816686,29
-26570,1518735993578,29
-26571,1518736143359,28
-26572,1518736330498,27
-26573,1518736433233,26
-26574,1518736472660,26
-26575,1518736487441,26
-26576,1518736576610,28
-26577,1518736659766,28
-26578,1518736689288,27
-26579,1518736755649,28
-26580,1518736889790,28
-26581,1518737098702,26
-26582,1518737119687,25
-26583,1518737164790,27
-26584,1518737255209,28
-26585,1518737315354,29
-26586,1518737360370,29
-26587,1518737688400,29
-26588,1518737743331,27
-26589,1518737845821,28
-26590,1518737960221,27
-26591,1518738016831,26
-26592,1518738089362,25
-26593,1518738223706,25
-26594,1518738250048,24
-26595,1518738390454,25
-26596,1518738565160,24
-26597,1518738590687,23
-26598,1518738685954,24
-26599,1518738995670,24
-26600,1518739044666,22
-26601,1518739091431,24
-26602,1518739142561,24
-26603,1518739170379,23
-26604,1518739357480,24
-26605,1518739405995,23
-26606,1518739451977,23
-26607,1518739478661,22
-26608,1518739520622,25
-26609,1518739551097,26
-26610,1518739568409,26
-26611,1518739623437,29
-26612,1518739679839,29
-26613,1518739786257,29
-26614,1518739841504,28
-26615,1518739926417,27
-26616,1518740017034,27
-26617,1518740052229,26
-26618,1518740176455,27
-26619,1518740215467,27
-26620,1518740290937,27
-26621,1518740442916,28
-26622,1518740582126,27
-26623,1518740651909,26
-26624,1518740751499,27
-26625,1518740835725,27
-26626,1518740961681,26
-26627,1518740976758,25
-26628,1518740988525,28
-26629,1518741134538,32
-26630,1518741148371,32
-26631,1518741327566,36
-26632,1518741415152,35
-26633,1518741502221,36
-26634,1518741541251,37
-26635,1518741650021,37
-26636,1518741764200,36
-26637,1518741917315,36
-26638,1518742083096,35
-26639,1518742155261,36
-26640,1518742358783,35
-26641,1518742425043,34
-26642,1518742589856,34
-26643,1518742645733,33
-26644,1518742716313,33
-26645,1518742814931,34
-26646,1518742931309,34
-26647,1518742975920,34
-26648,1518743107169,34
-26649,1518743209425,33
-26650,1518743258361,33
-26651,1518743513924,33
-26652,1518743588373,31
-26653,1518743714944,31
-26654,1518744019335,31
-26655,1518744055961,30
-26656,1518744208911,31
-26657,1518744226629,31
-26658,1518744467146,34
-26659,1518744598786,33
-26660,1518744622658,32
-26661,1518744676238,34
-26662,1518744760331,34
-26663,1518744783335,34
-26664,1518744892048,36
-26665,1518744973636,35
-26666,1518745112179,35
-26667,1518745244656,34
-26668,1518745403660,34
-26669,1518745520136,33
-26670,1518745605039,31
-26671,1518745683812,31
-26672,1518745758174,30
-26673,1518745804866,30
-26674,1518745953876,30
-26675,1518746128411,28
-26676,1518746186143,28
-26677,1518746326193,29
-26678,1518746395366,29
-26679,1518746471317,28
-26680,1518746577037,28
-26681,1518746650925,27
-26682,1518746753093,27
-26683,1518746804452,27
-26684,1518746834675,27
-26685,1518747043899,27
-26686,1518747107795,27
-26687,1518747174263,27
-26688,1518747191749,27
-26689,1518747262980,29
-26690,1518747389842,29
-26691,1518747483422,27
-26692,1518747491686,26
-26693,1518747583858,33
-26694,1518747598258,32
-26695,1518747715009,37
-26696,1518747768116,36
-26697,1518747793754,36
-26698,1518747938028,38
-26699,1518748132047,37
-26700,1518748215600,35
-26701,1518748254550,35
-26702,1518748299935,36
-26703,1518748453082,36
-26704,1518748555274,36
-26705,1518748614865,35
-26706,1518749035175,35
-26707,1518749085289,33
-26708,1518749379522,34
-26709,1518749447110,33
-26710,1518749520598,34
-26711,1518749664864,34
-26712,1518749768871,33
-26713,1518750226641,33
-26714,1518750373599,31
-26715,1518750432818,31
-26716,1518750516226,31
-26717,1518750656029,30
-26718,1518750717691,30
-26719,1518750845837,29
-26720,1518751003491,28
-26721,1518751262252,27
-26722,1518751384117,26
-26723,1518751433281,25
-26724,1518751462184,25
-26725,1518751483178,25
-26726,1518751494630,26
-26727,1518751690066,31
-26728,1518751738197,31
-26729,1518751822137,33
-26730,1518751866219,32
-26731,1518752025507,36
-26732,1518752141195,35
-26733,1518752220575,34
-26734,1518752271571,33
-26735,1518752465405,34
-26736,1518752635996,33
-26737,1518752839708,33
-26738,1518752886531,31
-26739,1518752911736,31
-26740,1518753013733,33
-26741,1518753102161,32
-26742,1518753196887,32
-26743,1518753296709,31
-26744,1518753428325,30
-26745,1518753592865,29
-26746,1518753673724,29
-26747,1518753723576,28
-26748,1518753851157,29
-26749,1518753986425,28
-26750,1518754055751,27
-26751,1518754246128,27
-26752,1518754416408,26
-26753,1518754559735,25
-26754,1518754659649,23
-26755,1518754694995,22
-26756,1518754896797,22
-26757,1518754922727,22
-26758,1518755007325,24
-26759,1518755150575,23
-26760,1518755200267,22
-26761,1518755289848,22
-26762,1518755348003,22
-26763,1518755682115,22
-26764,1518755712519,22
-26765,1518755780838,22
-26766,1518755835843,23
-26767,1518755864435,22
-26768,1518755919473,22
-26769,1518756100627,22
-26770,1518756147195,21
-26771,1518756200358,21
-26772,1518756226595,20
-26773,1518756294596,21
-26774,1518756346427,21
-26775,1518756459333,20
-26776,1518756488093,19
-26777,1518756544699,20
-26778,1518756683846,19
-26779,1518756725121,18
-26780,1518756882130,18
-26781,1518756935352,17
-26782,1518756998269,17
-26783,1518757101852,16
-26784,1518757154390,15
-26785,1518757245575,15
-26786,1518757301759,14
-26787,1518757397028,13
-26788,1518757424566,12
-26789,1518757441940,14
-26790,1518757468078,14
-26791,1518757569731,15
-26792,1518757610957,14
-26793,1518757619134,16
-26794,1518757676202,20
-26795,1518757702885,22
-26796,1518757717698,23
-26797,1518757795321,26
-26798,1518757859095,27
-26799,1518757921785,26
-26800,1518757936550,27
-26801,1518757989808,30
-26802,1518758029113,30
-26803,1518758190377,32
-26804,1518758272452,31
-26805,1518758293935,31
-26806,1518758339725,34
-26807,1518758533015,34
-26808,1518758582087,33
-26809,1518758630384,33
-26810,1518758729521,34
-26811,1518758787700,34
-26812,1518758853056,33
-26813,1518758893413,34
-26814,1518758982166,34
-26815,1518759107753,33
-26816,1518759228678,33
-26817,1518759427229,33
-26818,1518759739382,31
-26819,1518759823393,30
-26820,1518759869352,30
-26821,1518759926717,30
-26822,1518760101994,30
-26823,1518760232517,29
-26824,1518760295510,28
-26825,1518760426063,28
-26826,1518760464561,29
-26827,1518760546482,32
-26828,1518760573203,31
-26829,1518760580997,34
-26830,1518760646682,43
-26831,1518760776390,43
-26832,1518760870213,42
-26833,1518761233817,43
-26834,1518761408675,41
-26835,1518761484809,41
-26836,1518761566818,41
-26837,1518761670161,40
-26838,1518761767828,40
-26839,1518761826173,40
-26840,1518761861221,41
-26841,1518762116824,42
-26842,1518762329635,41
-26843,1518762402112,41
-26844,1518762450560,41
-26845,1518762716184,41
-26846,1518762740565,40
-26847,1518762785773,42
-26848,1518762905556,44
-26849,1518763054942,42
-26850,1518763088253,41
-26851,1518763315041,43
-26852,1518763492490,42
-26853,1518763512932,41
-26854,1518763646685,44
-26855,1518763822279,43
-26856,1518764010124,43
-26857,1518764160312,41
-26858,1518764225015,41
-26859,1518764288256,41
-26860,1518764494641,40
-26861,1518764632478,40
-26862,1518764668441,38
-26863,1518764688834,40
-26864,1518764803764,42
-26865,1518764914702,43
-26866,1518765078569,41
-26867,1518765268591,41
-26868,1518765294943,40
-26869,1518765407410,42
-26870,1518765442160,41
-26871,1518765481681,42
-26872,1518765524223,43
-26873,1518765609978,44
-26874,1518765627150,44
-26875,1518765810721,48
-26876,1518765944321,47
-26877,1518766400611,47
-26878,1518766478146,45
-26879,1518766550500,45
-26880,1518766629036,44
-26881,1518766818767,43
-26882,1518766946079,42
-26883,1518767080275,41
-26884,1518767481985,39
-26885,1518767623484,38
-26886,1518767739720,36
-26887,1518768198909,35
-26888,1518768210404,33
-26889,1518768306129,39
-26890,1518768404684,39
-26891,1518768522219,37
-26892,1518768588737,36
-26893,1518768733578,36
-26894,1518768851943,36
-26895,1518769103341,35
-26896,1518769178700,34
-26897,1518769223214,35
-26898,1518769269099,35
-26899,1518769371923,35
-26900,1518769600220,34
-26901,1518769690294,34
-26902,1518769837541,34
-26903,1518769921315,33
-26904,1518769936297,33
-26905,1518769978777,36
-26906,1518770055357,37
-26907,1518770130484,38
-26908,1518770183543,37
-26909,1518770510373,37
-26910,1518770703911,36
-26911,1518770810382,35
-26912,1518770886602,34
-26913,1518770930108,34
-26914,1518770965372,34
-26915,1518771168517,34
-26916,1518771355309,34
-26917,1518771572015,32
-26918,1518771630928,30
-26919,1518771843107,29
-26920,1518771925069,28
-26921,1518772128510,28
-26922,1518772153971,26
-26923,1518772175860,27
-26924,1518772218187,28
-26925,1518772337445,28
-26926,1518772359179,27
-26927,1518772420817,28
-26928,1518772673732,27
-26929,1518772836239,27
-26930,1518772954060,31
-26931,1518773008549,30
-26932,1518773203896,30
-26933,1518773324174,28
-26934,1518773379728,27
-26935,1518773508718,27
-26936,1518773626659,26
-26937,1518773824895,25
-26938,1518773903630,24
-26939,1518774014085,23
-26940,1518774067851,22
-26941,1518774080781,23
-26942,1518774255078,25
-26943,1518774412226,24
-26944,1518774618868,23
-26945,1518774669135,22
-26946,1518774859838,22
-26947,1518775001638,21
-26948,1518775045342,21
-26949,1518775110129,21
-26950,1518775185025,19
-26951,1518775220660,20
-26952,1518775271305,20
-26953,1518775301553,19
-26954,1518775384756,22
-26955,1518775450083,21
-26956,1518775549469,19
-26957,1518775649639,19
-26958,1518775692812,17
-26959,1518775817059,17
-26960,1518775911998,16
-26961,1518776020239,15
-26962,1518776075059,14
-26963,1518776111395,14
-26964,1518776123761,16
-26965,1518776190861,18
-26966,1518776224050,17
-26967,1518776281552,17
-26968,1518776321048,16
-26969,1518776358102,17
-26970,1518776448092,17
-26971,1518776567823,17
-26972,1518776587447,17
-26973,1518776635016,19
-26974,1518776746014,19
-26975,1518776780135,21
-26976,1518776831704,21
-26977,1518776954934,20
-26978,1518777076032,19
-26979,1518777108387,19
-26980,1518777264381,19
-26981,1518777302612,20
-26982,1518777345968,19
-26983,1518777373865,19
-26984,1518777483759,20
-26985,1518777675717,18
-26986,1518777887229,18
-26987,1518777921270,17
-26988,1518777972566,16
-26989,1518778041107,19
-26990,1518778124508,18
-26991,1518778201200,18
-26992,1518778210362,17
-26993,1518778336433,21
-26994,1518778449751,20
-26995,1518778629893,19
-26996,1518778724961,19
-26997,1518778785302,18
-26998,1518778873537,18
-26999,1518778917025,18
-27000,1518779064445,18
-27001,1518779204566,17
-27002,1518779310666,16
-27003,1518779384983,15
-27004,1518779440228,15
-27005,1518779497753,17
-27006,1518779660000,17
-27007,1518779703073,17
-27008,1518779809090,16
-27009,1518779894316,17
-27010,1518779932413,16
-27011,1518780006657,16
-27012,1518780146197,16
-27013,1518780210230,15
-27014,1518780288432,15
-27015,1518780311811,15
-27016,1518780333862,16
-27017,1518780387188,17
-27018,1518780478939,17
-27019,1518780494415,16
-27020,1518780525451,17
-27021,1518780537961,18
-27022,1518780648053,20
-27023,1518780668048,21
-27024,1518780765128,23
-27025,1518780861151,23
-27026,1518780908382,23
-27027,1518780961481,24
-27028,1518781062928,24
-27029,1518781214006,24
-27030,1518781234763,24
-27031,1518781335416,25
-27032,1518781345191,25
-27033,1518781416073,29
-27034,1518781511833,30
-27035,1518781657117,30
-27036,1518781737035,29
-27037,1518781945664,29
-27038,1518782066815,28
-27039,1518782147881,27
-27040,1518782314755,27
-27041,1518782385747,26
-27042,1518782483501,28
-27043,1518782562766,28
-27044,1518782831655,27
-27045,1518782996896,26
-27046,1518783042061,26
-27047,1518783204617,25
-27048,1518783367569,25
-27049,1518783393264,25
-27050,1518788356084,26
-27051,1518788395941,25
-27052,1518788462440,26
-27053,1518788504552,26
-27054,1518788532442,26
-27055,1518788574680,28
-27056,1518788618084,28
-27057,1518788666797,28
-27058,1518788924608,29
-27059,1518789047375,28
-27060,1518789147660,27
-27061,1518789163992,27
-27062,1518789235704,29
-27063,1518789443500,30
-27064,1518789458027,28
-27065,1518789545463,33
-27066,1518789691882,32
-27067,1518789855484,33
-27068,1518789894294,32
-27069,1518789940110,33
-27070,1518790080606,33
-27071,1518790199963,33
-27072,1518790366294,32
-27073,1518790462380,32
-27074,1518790591335,32
-27075,1518790661693,31
-27076,1518790740167,31
-27077,1518790790283,32
-27078,1518790807636,31
-27079,1518790837186,35
-27080,1518790978934,37
-27081,1518791073039,36
-27082,1518791378111,36
-27083,1518791576205,35
-27084,1518791744539,34
-27085,1518791786277,33
-27086,1518791863811,33
-27087,1518792011533,33
-27088,1518792230764,33
-27089,1518792278094,32
-27090,1518792357360,32
-27091,1518792586668,32
-27092,1518792815422,31
-27093,1518792924648,32
-27094,1518793016301,31
-27095,1518793045884,31
-27096,1518793067748,32
-27097,1518793205480,33
-27098,1518793363118,33
-27099,1518793489703,33
-27100,1518793797356,32
-27101,1518793917976,30
-27102,1518794013965,29
-27103,1518794071714,29
-27104,1518794175853,29
-27105,1518794307320,28
-27106,1518794328517,27
-27107,1518794420856,28
-27108,1518794585849,28
-27109,1518794734492,27
-27110,1518794837719,26
-27111,1518794886391,26
-27112,1518794934090,25
-27113,1518795013338,25
-27114,1518795172308,24
-27115,1518795505618,23
-27116,1518795748023,22
-27117,1518795799987,22
-27118,1518795855364,22
-27119,1518795889398,21
-27120,1518796085323,22
-27121,1518796127952,21
-27122,1518796224736,22
-27123,1518796277533,22
-27124,1518796373305,23
-27125,1518796394971,22
-27126,1518796504528,23
-27127,1518796612338,23
-27128,1518796752658,22
-27129,1518796807985,21
-27130,1518796892503,20
-27131,1518797166141,21
-27132,1518797172439,19
-27133,1518797178720,29
-27134,1518797220450,38
-27135,1518797236929,39
-27136,1518797255647,43
-27137,1518797302863,47
-27138,1518797375209,48
-27139,1518797383996,47
-27140,1518797395045,58
-27141,1518797401238,69
-27142,1518797405020,95
-27143,1518797498848,153
-27144,1518797763427,153
-27145,1518798072029,150
-27146,1518798236385,148
-27147,1518798646440,148
-27148,1518798722092,145
-27149,1518798736231,146
-27150,1518801242906,168
-27151,1518801352858,164
-27152,1518801391312,165
-27153,1518801737597,171
-27154,1518802434943,168
-27155,1518802505020,166
-27156,1518802648463,168
-27157,1518802886347,168
-27158,1518802983145,165
-27159,1518803147091,165
-27160,1518803547985,164
-27161,1518803709266,161
-27162,1518804079551,161
-27163,1518804285042,158
-27164,1518804590108,155
-27165,1518804703790,154
-27166,1518805266383,154
-27167,1518805450327,150
-27168,1518806924671,148
-27169,1518807044941,145
-27170,1518807206049,144
-27171,1518807403084,142
-27172,1518807571682,140
-27173,1518808041297,138
-27174,1518808268527,134
-27175,1518808516972,132
-27176,1518808702071,129
-27177,1518808844212,126
-27178,1518809359574,125
-27179,1518809651440,123
-27180,1518809925713,121
-27181,1518809996735,117
-27182,1518810380678,117
-27183,1518810780644,114
-27184,1518810911161,111
-27185,1518811002182,108
-27186,1518811031861,108
-27187,1518811123153,112
-27188,1518811331463,111
-27189,1518811390345,107
-27190,1518811440369,107
-27191,1518811474401,109
-27192,1518811605787,111
-27193,1518811764258,109
-27194,1518811922433,106
-27195,1518812135592,103
-27196,1518812178613,100
-27197,1518812238313,103
-27198,1518812387411,102
-27199,1518812757121,99
-27200,1518813111197,95
-27201,1518813199692,90
-27202,1518813429245,89
-27203,1518813578214,83
-27204,1518813998600,81
-27205,1518814286040,76
-27206,1518814299452,72
-27207,1518814372828,81
-27208,1518814791679,79
-27209,1518815205359,75
-27210,1518815796175,71
-27211,1518815848210,66
-27212,1518815964631,64
-27213,1518816133933,61
-27214,1518816385414,56
-27215,1518816561654,52
-27216,1518816608670,47
-27217,1518817124814,44
-27218,1518817405787,40
-27219,1518817745122,35
-27220,1518817919146,31
-27221,1518818022066,27
-27222,1518818190750,22
-27223,1518818257354,17
-27224,1518818307954,13
-27225,1518818348349,8
-27226,1518818388614,6
-27227,1518818424498,1
-27228,1518818438159,1
-27229,1518818447905,1
-27230,1518818458549,1
-27231,1518818468334,1
-27232,1518818477519,1
-27233,1518818487677,1
-27234,1518818497477,1
-27235,1518818507381,1
-27236,1518818524059,1
-27237,1518818533635,1
-27238,1518818544011,1
-27239,1518818552882,1
-27240,1518818562680,1
-27241,1518818571748,1
-27242,1518818582012,1
-27243,1518818592929,2
-27244,1518818604326,2
-27245,1518818614944,1
-27246,1518818626091,1
-27247,1518818639612,1
-27248,1518818653362,1
-27249,1518818667801,1
-27250,1518818678230,4
-27251,1518818706109,3
-27252,1518818716279,2
-27253,1518818729781,5
-27254,1518818739456,5
-27255,1518818779763,4
-27256,1518818813692,4
-27257,1518818872477,4
-27258,1518818901633,2
-27259,1518818925306,3
-27260,1518818935477,2
-27261,1518818944520,1
-27262,1518818957993,1
-27263,1518818971078,1
-27264,1518818988453,1
-27265,1518818997622,1
-27266,1518819007783,1
-27267,1518819017832,1
-27268,1518819028145,1
-27269,1518819038071,1
-27270,1518819047795,1
-27271,1518819057259,1
-27272,1518819071050,1
-27273,1518819080980,1
-27274,1518819090305,1
-27275,1518819103959,1
-27276,1518819117802,1
-27277,1518819127464,1
-27278,1518819137601,1
-27279,1518819151297,1
-27280,1518819164937,1
-27281,1518819174584,1
-27282,1518819183774,1
-27283,1518819193314,1
-27284,1518819202433,1
-27285,1518819211881,1
-27286,1518819222824,1
-27287,1518819236209,1
-27288,1518819245555,1
-27289,1518819259576,1
-27290,1518819277211,1
-27291,1518819291654,1
-27292,1518819301692,1
-27293,1518819310868,1
-27294,1518819320808,1
-27295,1518819330387,1
-27296,1518819339644,1
-27297,1518819350436,1
-27298,1518819359607,1
-27299,1518819373690,1
-27300,1518819383036,1
-27301,1518819392290,1
-27302,1518819406096,1
-27303,1518819415366,1
-27304,1518819425359,1
-27305,1518819435053,1
-27306,1518819456378,1
-27307,1518819465294,1
-27308,1518819475193,2
-27309,1518819485785,2
-27310,1518819498895,2
-27311,1518819508718,2
-27312,1518819521841,4
-27313,1518819535139,5
-27314,1518819578600,6
-27315,1518819592030,6
-27316,1518819608856,6
-27317,1518819626476,8
-27318,1518819643802,9
-27319,1518819661022,10
-27320,1518819681978,10
-27321,1518819717419,12
-27322,1518819732219,12
-27323,1518819755477,13
-27324,1518819799211,15
-27325,1518819911615,16
-27326,1518819975586,16
-27327,1518820007420,15
-27328,1518820086056,17
-27329,1518820130160,16
-27330,1518820256461,16
-27331,1518820293388,17
-27332,1518820303705,17
-27333,1518820396572,20
-27334,1518820507964,20
-27335,1518820610437,20
-27336,1518820708162,20
-27337,1518820815891,20
-27338,1518820875569,20
-27339,1518820945544,20
-27340,1518821045954,21
-27341,1518821291680,21
-27342,1518821313272,20
-27343,1518821465670,21
-27344,1518821504991,21
-27345,1518821547280,22
-27346,1518821678152,23
-27347,1518821828368,23
-27348,1518821841187,22
-27349,1518821952278,26
-27350,1518822175666,25
-27351,1518822373040,26
-27352,1518822575422,25
-27353,1518822674203,24
-27354,1518823027902,25
-27355,1518823068491,25
-27356,1518823152862,26
-27357,1518823371805,25
-27358,1518823592040,25
-27359,1518823608300,25
-27360,1518823667673,28
-27361,1518823780679,28
-27362,1518823908011,28
-27363,1518823988183,28
-27364,1518824111330,28
-27365,1518824194620,27
-27366,1518824320319,28
-27367,1518824363927,27
-27368,1518824714577,28
-27369,1518824867411,27
-27370,1518825006929,27
-27371,1518825231832,27
-27372,1518825438853,26
-27373,1518825472568,25
-27374,1518825670204,26
-27375,1518825739427,26
-27376,1518825898152,26
-27377,1518825931001,25
-27378,1518826033888,27
-27379,1518826060621,26
-27380,1518826136581,27
-27381,1518826169699,27
-27382,1518826263853,29
-27383,1518826345203,29
-27384,1518826523875,28
-27385,1518826593847,27
-27386,1518826702361,27
-27387,1518826753990,27
-27388,1518826779140,27
-27389,1518826864838,29
-27390,1518826979001,28
-27391,1518827150267,28
-27392,1518827404859,27
-27393,1518827521309,27
-27394,1518827576795,26
-27395,1518828118677,26
-27396,1518828214624,24
-27397,1518828290417,25
-27398,1518828398973,24
-27399,1518828511804,23
-27400,1518828752970,22
-27401,1518828868515,21
-27402,1518829047920,21
-27403,1518829091426,21
-27404,1518829143076,20
-27405,1518829186794,20
-27406,1518829364953,20
-27407,1518829405893,19
-27408,1518829587182,19
-27409,1518829668237,18
-27410,1518829768410,18
-27411,1518829903561,18
-27412,1518829979598,17
-27413,1518830179569,16
-27414,1518830205285,15
-27415,1518830351469,16
-27416,1518830457599,16
-27417,1518830506755,15
-27418,1518830552563,15
-27419,1518830584008,15
-27420,1518830626657,15
-27421,1518830693044,15
-27422,1518830788565,15
-27423,1518831048778,16
-27424,1518831115337,15
-27425,1518831150991,15
-27426,1518831165471,15
-27427,1518831246393,16
-27428,1518831282355,16
-27429,1518831304148,17
-27430,1518831362954,17
-27431,1518831462073,17
-27432,1518831519762,16
-27433,1518831591079,18
-27434,1518831619528,18
-27435,1518831668781,18
-27436,1518831731320,18
-27437,1518831860083,18
-27438,1518831952706,17
-27439,1518832008840,17
-27440,1518832213088,17
-27441,1518832260088,16
-27442,1518832288576,15
-27443,1518832343695,17
-27444,1518832392585,16
-27445,1518832474212,17
-27446,1518832545660,17
-27447,1518832619265,16
-27448,1518832655101,16
-27449,1518832719148,18
-27450,1518832812454,17
-27451,1518832931503,17
-27452,1518832982518,17
-27453,1518833015236,16
-27454,1518833220727,16
-27455,1518833300200,15
-27456,1518833469359,16
-27457,1518833517828,15
-27458,1518833582607,15
-27459,1518833636647,14
-27460,1518833658650,15
-27461,1518833721636,17
-27462,1518833799013,16
-27463,1518833854149,17
-27464,1518833916628,17
-27465,1518833992362,16
-27466,1518834006532,16
-27467,1518834087302,18
-27468,1518834114687,18
-27469,1518834173705,18
-27470,1518834244435,18
-27471,1518834343423,18
-27472,1518834411144,17
-27473,1518834435950,17
-27474,1518834494451,18
-27475,1518834541666,18
-27476,1518834605631,18
-27477,1518834627172,18
-27478,1518834666675,20
-27479,1518834725066,20
-27480,1518834746193,21
-27481,1518834806695,23
-27482,1518834880032,23
-27483,1518834911122,24
-27484,1518835055707,24
-27485,1518835132608,23
-27486,1518835178818,24
-27487,1518835376097,24
-27488,1518835491819,24
-27489,1518835543186,24
-27490,1518835633880,24
-27491,1518835677388,24
-27492,1518835760216,25
-27493,1518835772894,24
-27494,1518835962877,28
-27495,1518836090029,27
-27496,1518836161010,27
-27497,1518836221759,27
-27498,1518836293705,28
-27499,1518836422404,27
-27500,1518836495577,27
-27501,1518836533810,27
-27502,1518836589274,27
-27503,1518836806940,27
-27504,1518836850255,27
-27505,1518836916776,28
-27506,1518837031612,28
-27507,1518837128153,27
-27508,1518837240210,27
-27509,1518837304710,27
-27510,1518837371106,26
-27511,1518837519777,27
-27512,1518837558620,26
-27513,1518837725084,26
-27514,1518837769220,26
-27515,1518837819274,26
-27516,1518838066159,27
-27517,1518838090652,25
-27518,1518838150020,27
-27519,1518838243829,28
-27520,1518838359888,27
-27521,1518838426387,27
-27522,1518838491599,26
-27523,1518838563626,26
-27524,1518838612156,26
-27525,1518838698476,26
-27526,1518838748670,25
-27527,1518838830614,26
-27528,1518838870297,27
-27529,1518838911138,28
-27530,1518838969507,29
-27531,1518839017257,28
-27532,1518839127936,29
-27533,1518839238940,28
-27534,1518839488667,28
-27535,1518839684132,28
-27536,1518839773519,27
-27537,1518839829122,26
-27538,1518839914023,27
-27539,1518839959048,26
-27540,1518840105071,26
-27541,1518840203649,26
-27542,1518840264249,25
-27543,1518840380455,25
-27544,1518840518487,25
-27545,1518840611065,25
-27546,1518840679751,24
-27547,1518840784400,23
-27548,1518840825019,23
-27549,1518841018827,23
-27550,1518841055257,22
-27551,1518841170509,23
-27552,1518841206842,23
-27553,1518841299656,23
-27554,1518841377310,23
-27555,1518841424133,21
-27556,1518841484123,22
-27557,1518841497263,22
-27558,1518841507396,24
-27559,1518841797460,29
-27560,1518841851344,28
-27561,1518841901768,29
-27562,1518842152969,28
-27563,1518842201581,27
-27564,1518842256655,28
-27565,1518842286308,27
-27566,1518842476324,28
-27567,1518842603401,29
-27568,1518842736070,28
-27569,1518842832042,28
-27570,1518842898917,27
-27571,1518842919567,27
-27572,1518843097380,29
-27573,1518843227584,27
-27574,1518843257315,27
-27575,1518843333378,28
-27576,1518843392715,28
-27577,1518843451596,27
-27578,1518843566228,28
-27579,1518843723549,28
-27580,1518843867715,28
-27581,1518843915297,27
-27582,1518843954996,28
-27583,1518844127521,28
-27584,1518844231664,28
-27585,1518844389455,27
-27586,1518844554508,26
-27587,1518844685871,26
-27588,1518844877340,25
-27589,1518844921477,24
-27590,1518845168509,24
-27591,1518845245375,23
-27592,1518845286733,23
-27593,1518845370873,23
-27594,1518845688864,25
-27595,1518845713848,23
-27596,1518845761346,25
-27597,1518845846665,25
-27598,1518845933853,24
-27599,1518846073420,24
-27600,1518846292655,23
-27601,1518846350265,22
-27602,1518846515401,22
-27603,1518846524741,22
-27604,1518846591972,27
-27605,1518846720561,27
-27606,1518846771451,26
-27607,1518846807219,26
-27608,1518846973460,27
-27609,1518847183829,26
-27610,1518847273560,25
-27611,1518847419673,25
-27612,1518847454392,23
-27613,1518847467752,25
-27614,1518847587684,28
-27615,1518847776684,28
-27616,1518847805758,27
-27617,1518847848549,28
-27618,1518847959760,29
-27619,1518848072331,29
-27620,1518848168183,28
-27621,1518848222834,28
-27622,1518848296366,27
-27623,1518848417727,28
-27624,1518848705566,26
-27625,1518848766461,27
-27626,1518848818207,26
-27627,1518848846136,26
-27628,1518848971946,27
-27629,1518849024287,27
-27630,1518849141371,28
-27631,1518849257544,27
-27632,1518849348166,27
-27633,1518849422738,26
-27634,1518849485782,26
-27635,1518849615779,25
-27636,1518849676060,24
-27637,1518849719479,24
-27638,1518849773957,24
-27639,1518849817158,25
-27640,1518849864502,25
-27641,1518849886044,25
-27642,1518849996758,26
-27643,1518850041029,26
-27644,1518850136117,26
-27645,1518850258699,26
-27646,1518850595422,24
-27647,1518850653317,23
-27648,1518850703098,23
-27649,1518850733062,24
-27650,1518850860913,24
-27651,1518850941015,23
-27652,1518851063523,22
-27653,1518851192613,22
-27654,1518851221536,22
-27655,1518851276972,22
-27656,1518851362236,22
-27657,1518851467253,21
-27658,1518851510364,22
-27659,1518851651102,24
-27660,1518851691345,24
-27661,1518851900234,24
-27662,1518851987451,24
-27663,1518852089621,23
-27664,1518852110117,22
-27665,1518852145844,25
-27666,1518852272159,26
-27667,1518852406195,25
-27668,1518852456816,24
-27669,1518852532493,24
-27670,1518852676636,24
-27671,1518966225749,23
-27672,1519054219917,23
-27673,1519054265359,22
-27674,1519054328227,22
-27675,1519060660130,23
-27676,1519060718394,21
-27677,1519060756142,22
-27678,1519060769655,22
-27679,1519060819294,24
-27680,1519060826868,25
-27681,1519061609515,31
-27682,1519061708877,30
-27683,1519150094042,31
-27684,1519151197715,29
-27685,1519151242624,28
-27686,1519151341918,28
-27687,1519151436925,28
-27688,1519151459319,27
-27689,1519151502660,28
-27690,1519204689045,28
-27691,1519204963896,27
-27692,1519205026583,27
-27693,1519205078733,26
-27694,1519205144329,26
-27695,1519205225055,25
-27696,1519205266575,25
-27697,1519205277638,27
-27698,1519205307150,32
-27699,1519205387904,32
-27700,1519205396055,32
-27701,1519205486184,40
-27702,1519205515467,39
-27703,1519205541691,41
-27704,1519535393216,45
-27705,1519536384281,45
-27706,1519633159123,43
-27707,1519633177491,41
-27708,1519633185172,46
-27709,1519633203372,59
-27710,1519633260702,64
-27711,1519633329449,65
-27712,1519633371735,65
-27713,1519633381675,68
-27714,1519633473078,84
-27715,1519633519907,84
-27716,1519634652916,86
-27717,1519634859342,84
-27718,1519635323377,84
-27719,1519635488953,83
-27720,1519635532119,81
-27721,1519635760809,84
-27722,1519637013374,83
-27723,1519637040785,80
-27724,1519637141739,85
-27725,1519637301112,85
-27726,1519637377546,83
-27727,1519639077778,84
-27728,1519639142787,83
-27729,1519639234133,83
-27730,1519639242160,84
-27731,1519641354966,106
-27732,1519641470321,104
-27733,1519641661342,102
-27734,1519641901585,102
-27735,1519641927837,100
-27736,1519642010020,106
-27737,1519642120980,106
-27738,1519642303415,106
-27739,1519642327431,105
-27740,1519642341752,112
-27741,1519642361141,128
-27742,1519642540359,142
-27743,1519642634931,140
-27744,1519642717785,141
-27745,1519643364499,141
-27746,1519643480894,138
-27747,1519643675231,136
-27748,1519643783885,135
-27749,1519643829052,134
-27750,1519643970640,138
-27751,1519644194478,137
-27752,1519644209270,134
-27753,1519644621458,152
-27754,1519644797274,148
-27755,1519645143186,147
-27756,1519645205373,144
-27757,1519645288886,145
-27758,1519645604267,145
-27759,1519645861782,142
-27760,1519646032168,139
-27761,1519646260585,137
-27762,1519646399259,134
-27763,1519646600416,132
-27764,1519646615368,128
-27765,1519646706855,146
-27766,1519647009535,145
-27767,1519647048580,141
-27768,1519647122873,145
-27769,1519647228884,145
-27770,1519647280879,144
-27771,1519647396398,146
-27772,1519647461235,143
-27773,1519647720294,143
-27774,1519648048716,140
-27775,1519648197306,135
-27776,1519648463741,131
-27777,1519648536938,128
-27778,1519648638622,127
-27779,1519648735902,127
-27780,1519649183745,125
-27781,1519649394887,124
-27782,1519649660138,119
-27783,1519649760537,116
-27784,1519649870430,112
-27785,1519649963367,109
-27786,1519650106521,108
-27787,1519650187440,104
-27788,1519650228670,102
-27789,1519650250990,104
-27790,1519650389318,110
-27791,1519650426027,106
-27792,1519650482049,107
-27793,1519650586166,106
-27794,1519650654530,103
-27795,1519650722711,101
-27796,1519650747251,99
-27797,1519650846972,103
-27798,1519650881224,102
-27799,1519650988152,105
-27800,1519651353478,101
-27801,1519651489180,101
-27802,1519651688098,97
-27803,1519651773495,94
-27804,1519651898726,91
-27805,1519652177166,87
-27806,1519652192291,81
-27807,1519652328117,89
-27808,1519652718334,86
-27809,1519652735619,88
-27810,1519652760398,98
-27811,1519652790151,102
-27812,1519652819880,106
-27813,1519652899164,109
-27814,1519653128746,115
-27815,1519653162848,111
-27816,1519653313006,115
-27817,1519653383624,110
-27818,1519653841652,108
-27819,1519653916851,103
-27820,1519653936604,100
-27821,1519654111486,109
-27822,1519654404458,103
-27823,1519654491392,98
-27824,1519654530780,98
-27825,1519654610870,98
-27826,1519654645203,95
-27827,1519654723104,97
-27828,1519654811682,93
-27829,1519654885357,91
-27830,1519655016688,88
-27831,1519655142268,96
-27832,1519655151992,92
-27833,1519655167125,109
-27834,1519655233220,120
-27835,1519655385647,118
-27836,1519655596309,119
-27837,1519655647840,114
-27838,1519655851462,114
-27839,1519655941800,109
-27840,1519656065215,110
-27841,1519656072967,115
-27842,1519656094912,153
-27843,1519656380542,164
-27844,1519656771945,160
-27845,1519657048064,157
-27846,1519657085104,150
-27847,1519657198548,155
-27848,1519657265466,152
-27849,1519657471166,152
-27850,1519658070751,150
-27851,1519658213544,145
-27852,1519658319756,142
-27853,1519659370999,149
-27854,1519659388477,142
-27855,1519659769392,156
-27856,1519659885171,151
-27857,1519659895221,150
-27858,1519660049375,181
-27859,1519660150217,177
-27860,1519660213661,174
-27861,1519660357419,175
-27862,1519660730256,170
-27863,1519660853304,166
-27864,1519661023318,161
-27865,1519661419046,167
-27866,1519662087792,163
-27867,1519662238908,156
-27868,1519662248875,156
-27869,1519662307360,189
-27870,1519662331807,191
-27871,1519662544959,205
-27872,1519662577233,201
-27873,1519663060958,211
-27874,1519663327937,204
-27875,1519663410645,198
-27876,1519663876050,197
-27877,1519664053656,191
-27878,1519664427861,188
-27879,1519664709548,183
-27880,1519664874591,177
-27881,1519664897261,172
-27882,1519665094242,183
-27883,1519665228582,178
-27884,1519665245819,174
-27885,1519665386967,191
-27886,1519665802864,186
-27887,1519666150991,180
-27888,1519666246167,175
-27889,1519666799833,173
-27890,1519666827253,171
-27891,1519667159887,179
-27892,1519667301179,175
-27893,1519667583089,172
-27894,1519667690828,166
-27895,1519667710535,163
-27896,1519667944167,176
-27897,1519668014605,174
-27898,1519668986677,172
-27899,1519669091209,168
-27900,1519669490733,165
-27901,1519670119100,157
-27902,1519670210992,149
-27903,1519670465745,146
-27904,1519670548836,140
-27905,1519670641300,136
-27906,1519670687986,131
-27907,1519670899930,136
-27908,1519670953904,129
-27909,1519671177396,127
-27910,1519671986053,126
-27911,1519672034679,123
-27912,1519672309137,124
-27913,1519672780369,122
-27914,1519672788034,115
-27915,1519673136253,144
-27916,1519673357094,140
-27917,1519673460991,134
-27918,1519673558499,130
-27919,1519673699769,125
-27920,1519673853709,120
-27921,1519673876092,120
-27922,1519674024417,125
-27923,1519674206834,119
-27924,1519674258119,113
-27925,1519674300531,113
-27926,1519674362461,112
-27927,1519674391725,111
-27928,1519674500765,113
-27929,1519674686374,107
-27930,1519675178406,102
-27931,1519675394448,95
-27932,1519675402024,88
-27933,1519675842127,119
-27934,1519675956015,119
-27935,1519676294272,116
-27936,1519676574311,108
-27937,1519676611491,102
-27938,1519676725718,103
-27939,1519676925104,97
-27940,1519677041662,91
-27941,1519677142958,86
-27942,1519677513717,97
-27943,1519677986127,98
-27944,1519678164830,92
-27945,1519678174806,86
-27946,1519678216610,99
-27947,1519678299050,102
-27948,1519678321444,99
-27949,1519678527968,104
-27950,1519678559717,98
-27951,1519678764768,98
-27952,1519678869460,93
-27953,1519678881862,88
-27954,1519679351501,98
-27955,1519679504691,99
-27956,1519679565652,93
-27957,1519679575649,91
-27958,1519679664080,123
-27959,1519679671578,120
-27960,1519680191417,152
-27961,1519680332191,148
-27962,1519680496718,144
-27963,1519680721136,138
-27964,1519680857546,133
-27965,1519681152823,128
-27966,1519681254374,122
-27967,1519681524405,116
-27968,1519681680294,111
-27969,1519681756131,123
-27970,1519682081536,123
-27971,1519682334615,127
-27972,1519682369573,122
-27973,1519682858604,130
-27974,1519682885675,123
-27975,1519683962625,128
-27976,1519684074283,124
-27977,1519684145226,120
-27978,1519684387968,117
-27979,1519684445009,112
-27980,1519684686487,110
-27981,1519684875877,105
-27982,1519684897933,109
-27983,1519685063486,115
-27984,1519685175029,110
-27985,1519685469316,118
-27986,1519685574085,113
-27987,1519685837474,109
-27988,1519686167439,105
-27989,1519686328072,100
-27990,1519686343273,95
-27991,1519686447129,111
-27992,1519686473988,108
-27993,1519686652331,111
-27994,1519686983104,107
-27995,1519687078080,103
-27996,1519687085596,108
-27997,1519687103400,137
-27998,1519687113301,151
-27999,1519687549910,181
-28000,1519687717883,176
-28001,1519687939753,170
-28002,1519688061797,164
-28003,1519688373480,162
-28004,1519688761726,156
-28005,1519689385387,151
-28006,1519689698742,146
-28007,1519689832390,142
-28008,1519690003415,138
-28009,1519690168576,135
-28010,1519690376763,130
-28011,1519690795320,124
-28012,1519690886144,120
-28013,1519691146445,116
-28014,1519691395200,110
-28015,1519691453848,121
-28016,1519691491145,120
-28017,1519691498630,121
-28018,1519691639693,154
-28019,1519691795438,150
-28020,1519692080282,146
-28021,1519692195498,141
-28022,1519692304342,142
-28023,1519692547306,138
-28024,1519692562176,133
-28025,1519692669610,150
-28026,1519692810942,148
-28027,1519692908101,145
-28028,1519692972704,145
-28029,1519693357342,144
-28030,1519693721950,137
-28031,1519693894085,131
-28032,1519694293167,126
-28033,1519694329944,133
-28034,1519694444754,134
-28035,1519694464419,130
-28036,1519694548812,140
-28037,1519694612364,136
-28038,1519694622295,136
-28039,1519694827413,163
-28040,1519695031899,157
-28041,1519695118431,152
-28042,1519695150340,149
-28043,1519695165095,152
-28044,1519695420967,168
-28045,1519695627090,161
-28046,1519695646768,165
-28047,1519695987177,180
-28048,1519696021460,173
-28049,1519696172129,182
-28050,1519696248513,178
-28051,1519696542800,178
-28052,1519696667277,171
-28053,1519697399947,167
-28054,1519697432324,167
-28055,1519697500809,171
-28056,1519697589817,169
-28057,1519697745720,166
-28058,1519698140183,172
-28059,1519698201379,166
-28060,1519698216327,183
-28061,1519698573890,205
-28062,1519698850911,200
-28063,1519698965171,193
-28064,1519699019063,190
-28065,1519699730519,191
-28066,1519699872786,184
-28067,1519699892730,180
-28068,1519699976056,193
-28069,1519700623452,192
-28070,1519700669961,185
-28071,1519700949692,186
-28072,1519701161820,180
-28073,1519701191167,177
-28074,1519701285533,183
-28075,1519701349885,184
-28076,1519701384010,181
-28077,1519701555266,186
-28078,1519701653237,181
-28079,1519701727858,178
-28080,1519702463580,176
-28081,1519702517206,168
-28082,1519702874512,167
-28083,1519702889543,165
-28084,1519703540321,183
-28085,1519703648765,175
-28086,1519703809881,170
-28087,1519703827268,164
-28088,1519704049102,178
-28089,1519704642346,169
-28090,1519705227240,161
-28091,1519705237221,160
-28092,1519705286702,189
-28093,1519705433180,193
-28094,1519705682262,187
-28095,1519705914203,179
-28096,1519705965645,172
-28097,1519706066071,187
-28098,1519706157533,191
-28099,1519706876381,206
-28100,1519707199358,197
-28101,1519707445231,191
-28102,1519707495093,185
-28103,1519707556703,186
-28104,1519707690804,185
-28105,1519707805167,179
-28106,1519707909182,174
-28107,1519708084190,169
-28108,1519708188814,162
-28109,1519708286250,157
-28110,1519708440002,153
-28111,1519709019874,147
-28112,1519709430198,138
-28113,1519709760966,131
-28114,1519709810022,123
-28115,1519710128027,119
-28116,1519710155190,113
-28117,1519710182519,118
-28118,1519710521542,138
-28119,1519710608898,131
-28120,1519710705934,127
-28121,1519710750731,121
-28122,1519710773093,120
-28123,1519710817103,126
-28124,1519711085928,124
-28125,1519711239670,127
-28126,1519711737523,121
-28127,1519711825519,114
-28128,1519711950010,109
-28129,1519712003912,106
-28130,1519712579474,102
-28131,1519712643737,93
-28132,1519712658640,88
-28133,1519712705627,94
-28134,1519713001747,94
-28135,1519713101785,87
-28136,1519713131135,88
-28137,1519713248212,88
-28138,1519713270551,84
-28139,1519713367444,100
-28140,1519713484512,95
-28141,1519713596712,89
-28142,1519713690722,85
-28143,1519713735428,84
-28144,1519713918090,93
-28145,1519713999372,87
-28146,1519714034141,81
-28147,1519714177592,90
-28148,1519714214512,84
-28149,1519714243943,87
-28150,1519714372849,88
-28151,1519714441381,84
-28152,1519714524478,80
-28153,1519715084409,77
-28154,1519715113892,70
-28155,1519715146658,73
-28156,1519715224388,74
-28157,1519715297013,70
-28158,1519715369336,66
-28159,1519715621217,61
-28160,1519715667854,57
-28161,1519715675580,68
-28162,1519715688070,82
-28163,1519715700515,92
-28164,1519715922086,103
-28165,1519716018424,101
-28166,1519716035966,96
-28167,1519716220838,102
-28168,1519716301124,107
-28169,1519716427626,105
-28170,1519716435300,100
-28171,1519716476601,128
-28172,1519716890241,128
-28173,1519716931671,122
-28174,1519717049392,129
-28175,1519717104323,125
-28176,1519717330707,126
-28177,1519717484458,126
-28178,1519717671167,122
-28179,1519717801078,118
-28180,1519717965242,115
-28181,1519717992018,109
-28182,1519718146276,115
-28183,1519718158639,110
-28184,1519718418613,137
-28185,1519718550461,131
-28186,1519719367929,128
-28187,1519719441275,122
-28188,1519719471325,130
-28189,1519719575929,133
-28190,1519719600908,129
-28191,1519719898322,135
-28192,1519719928219,148
-28193,1519720009095,157
-28194,1519721007201,157
-28195,1519721404291,150
-28196,1519721502584,146
-28197,1519721646340,146
-28198,1519721831976,144
-28199,1519721854412,141
-28200,1519722089613,149
-28201,1519722334803,144
-28202,1519722351880,140
-28203,1519722513431,156
-28204,1519722618108,155
-28205,1519722867030,153
-28206,1519722914292,149
-28207,1519723344895,152
-28208,1519723355004,146
-28209,1519723529953,175
-28210,1519723970014,171
-28211,1519724943223,166
-28212,1519724958215,159
-28213,1519725040409,177
-28214,1519725570547,175
-28215,1519725751402,170
-28216,1519726111049,165
-28217,1519726163232,163
-28218,1519726175664,168
-28219,1519726633024,193
-28220,1519726816104,188
-28221,1519726848163,184
-28222,1519727286858,191
-28223,1519727454800,191
-28224,1519727653632,189
-28225,1519727984834,184
-28226,1519728038374,178
-28227,1519728046054,178
-28228,1519728245377,227
-28229,1519728511084,222
-28230,1519728719444,216
-28231,1519729339615,210
-28232,1519730240390,204
-28233,1519730446930,202
-28234,1519730804092,198
-28235,1519731683585,191
-28236,1519731772372,184
-28237,1519732239383,183
-28238,1519732273480,176
-28239,1519732329962,184
-28240,1519732400968,185
-28241,1519732792526,183
-28242,1519733018153,177
-28243,1519733297084,170
-28244,1519734007331,165
-28245,1519734214478,157
-28246,1519734317348,152
-28247,1519734487880,149
-28248,1519734539077,143
-28249,1519734634342,144
-28250,1519734931001,142
-28251,1519735051533,135
-28252,1519735353012,130
-28253,1519735424558,123
-28254,1519735551680,119
-28255,1519735564054,116
-28256,1519735603574,132
-28257,1519735621156,132
-28258,1519735968634,142
-28259,1519736635189,135
-28260,1519736704543,126
-28261,1519736909810,123
-28262,1519736924686,125
-28263,1519737398416,144
-28264,1519737844196,146
-28265,1519738050672,138
-28266,1519738375266,132
-28267,1519738405213,130
-28268,1519738544093,133
-28269,1519738551568,128
-28270,1519738564019,161
-28271,1519738668989,199
-28272,1519738778607,197
-28273,1519738997541,192
-28274,1519739075669,189
-28275,1519739251450,187
-28276,1519739366015,182
-28277,1519739680989,178
-28278,1519739814663,171
-28279,1519739968924,166
-28280,1519740499654,159
-28281,1519740633267,152
-28282,1519740809036,150
-28283,1519741003024,143
-28284,1519741297980,147
-28285,1519741409657,139
-28286,1519741487868,135
-28287,1519741505408,130
-28288,1519741559706,141
-28289,1519741800806,143
-28290,1519742155271,137
-28291,1519742222305,135
-28292,1519742308633,131
-28293,1519742366311,132
-28294,1519742449130,131
-28295,1519742500291,126
-28296,1519742745057,124
-28297,1519742783856,118
-28298,1519742803660,116
-28299,1519742953146,122
-28300,1519743193725,122
-28301,1519743336530,116
-28302,1519743378305,109
-28303,1519743511250,116
-28304,1519743543988,110
-28305,1519743586100,112
-28306,1519743707055,110
-28307,1519743744178,107
-28308,1519743823887,105
-28309,1519743925202,117
-28310,1519744401838,112
-28311,1519744705534,105
-28312,1519744753109,97
-28313,1519744913618,106
-28314,1519744940777,103
-28315,1519745050320,104
-28316,1519745120261,99
-28317,1519745253598,94
-28318,1519745261077,92
-28319,1519745673565,129
-28320,1519745878057,123
-28321,1519746106871,117
-28322,1519746276847,116
-28323,1519746292181,111
-28324,1519746511992,122
-28325,1519746627610,116
-28326,1519746686843,111
-28327,1519746704306,111
-28328,1519746714411,146
-28329,1519746985502,175
-28330,1519747611085,169
-28331,1519748010993,164
-28332,1519748188105,157
-28333,1519748217818,151
-28334,1519748334031,157
-28335,1519748704611,151
-28336,1519749057635,145
-28337,1519749458823,140
-28338,1519749956386,134
-28339,1519750193074,131
-28340,1519750225310,129
-28341,1519750397492,134
-28342,1519750466996,128
-28343,1519750476961,125
-28344,1519750508843,148
-28345,1519750573138,151
-28346,1519750697876,149
-28347,1519750727951,145
-28348,1519750743103,149
-28349,1519750915815,168
-28350,1519750955450,163
-28351,1519751010081,163
-28352,1519751022456,164
-28353,1519751091769,186
-28354,1519751358147,185
-28355,1519751439703,178
-28356,1519751906747,185
-28357,1519752138525,180
-28358,1519752763189,182
-28359,1519752829701,174
-28360,1519753028375,172
-28361,1519753157497,166
-28362,1519753190110,162
-28363,1519753613132,174
-28364,1519753704478,167
-28365,1519753778312,162
-28366,1519753898939,159
-28367,1519753943840,153
-28368,1519753973922,158
-28369,1519754035646,163
-28370,1519754109588,180
-28371,1519754242323,194
-28372,1519754891532,191
-28373,1519754904020,185
-28374,1519755480311,214
-28375,1519755535361,209
-28376,1519755666700,210
-28377,1519756059424,207
-28378,1519756099329,200
-28379,1519756914735,205
-28380,1519756939390,198
-28381,1519757485126,208
-28382,1519757714454,201
-28383,1519757726970,194
-28384,1519757931458,224
-28385,1519757978299,217
-28386,1519758155898,220
-28387,1519758378208,215
-28388,1519758506096,216
-28389,1519758523716,214
-28390,1519759294782,235
-28391,1519759882951,226
-28392,1519760126544,218
-28393,1519760283890,213
-28394,1519760419534,209
-28395,1519760540358,204
-28396,1519760717210,201
-28397,1519761345559,195
-28398,1519761675412,189
-28399,1519761762053,188
-28400,1519762006306,185
-28401,1519762513812,177
-28402,1519762965282,169
-28403,1519763160077,164
-28404,1519763255465,157
-28405,1519763347598,156
-28406,1519763513432,153
-28407,1519763734836,146
-28408,1519763744847,142
-28409,1519763779645,169
-28410,1519763853418,172
-28411,1519763909949,168
-28412,1519764320570,165
-28413,1519764797115,158
-28414,1519765379919,150
-28415,1519765451531,145
-28416,1519765641142,141
-28417,1519765749399,134
-28418,1519765880056,128
-28419,1519766123708,136
-28420,1519766335039,128
-28421,1519766406488,120
-28422,1519766480705,114
-28423,1519766673415,109
-28424,1519767629963,110
-28425,1519767784896,101
-28426,1519768159969,95
-28427,1519768465481,89
-28428,1519768586535,88
-28429,1519768672994,97
-28430,1519768801004,92
-28431,1519769042712,86
-28432,1519769082057,78
-28433,1519769141469,75
-28434,1519769282229,76
-28435,1519769356327,70
-28436,1519769405803,64
-28437,1519769413452,59
-28438,1519769426101,70
-28439,1519769502081,74
-28440,1519769679737,68
-28441,1519769714394,65
-28442,1519769843053,61
-28443,1519769895190,56
-28444,1519769905104,65
-28445,1519769932732,78
-28446,1519769950134,79
-28447,1519770014466,83
-28448,1519770027325,82
-28449,1519770049936,102
-28450,1519770079557,105
-28451,1519770097045,110
-28452,1519770201358,121
-28453,1519770266457,131
-28454,1519770398770,130
-28455,1519770550939,125
-28456,1519770566313,122
-28457,1519770618601,133
-28458,1519771279471,132
-28459,1519771405101,124
-28460,1519771454579,120
-28461,1519771509296,119
-28462,1519771584211,117
-28463,1519771739061,119
-28464,1519771943184,112
-28465,1519772103137,107
-28466,1519772191221,104
-28467,1519772206275,99
-28468,1519772346873,110
-28469,1519772354591,111
-28470,1519772512443,140
-28471,1519772532552,136
-28472,1519772600467,145
-28473,1519772770644,143
-28474,1519773297838,153
-28475,1519773312696,146
-28476,1519773433330,166
-28477,1519773488040,163
-28478,1519773675325,162
-28479,1519773762380,161
-28480,1519774292263,157
-28481,1519774772821,159
-28482,1519775102490,152
-28483,1519775281260,146
-28484,1519776623110,159
-28485,1519776766307,153
-28486,1519776959584,153
-28487,1519777511616,149
-28488,1519778072639,143
-28489,1519778144417,138
-28490,1519778390603,150
-28491,1519778418240,145
-28492,1519778974305,151
-28493,1519779075347,145
-28494,1519779144350,142
-28495,1519779458950,141
-28496,1519779594427,137
-28497,1519779641445,134
-28498,1519780158180,134
-28499,1519780266540,128
-28500,1519780291151,126
-28501,1519780840206,132
-28502,1519780870222,125
-28503,1519781136092,128
-28504,1519781268767,123
-28505,1519781475389,119
-28506,1519781492756,115
-28507,1519781616417,124
-28508,1519781650826,120
-28509,1519781826438,138
-28510,1519781851599,138
-28511,1519782263259,147
-28512,1519782280654,144
-28513,1519782436248,157
-28514,1519782495557,152
-28515,1519782530244,151
-28516,1519782616713,156
-28517,1519782802147,154
-28518,1519783014761,149
-28519,1519783074711,144
-28520,1519783338332,143
-28521,1519783353267,138
-28522,1519783407765,154
-28523,1519783450267,154
-28524,1519783548791,155
-28525,1519783622080,151
-28526,1519783667330,149
-28527,1519784026580,148
-28528,1519784122955,141
-28529,1519784350967,137
-28530,1519784358299,131
-28531,1519784650252,166
-28532,1519784863068,158
-28533,1519785023819,154
-28534,1519785238374,149
-28535,1519785315172,142
-28536,1519785337377,138
-28537,1519785399541,146
-28538,1519785513103,152
-28539,1519785839549,152
-28540,1519785847121,146
-28541,1519786278563,183
-28542,1519786659893,177
-28543,1519786719478,169
-28544,1519786882790,168
-28545,1519787098353,168
-28546,1519787132877,164
-28547,1519787650204,172
-28548,1519787818242,165
-28549,1519788191292,166
-28550,1519788199125,163
-28551,1519788317456,208
-28552,1519788837688,211
-28553,1519789529373,204
-28554,1519789643338,197
-28555,1519790034294,194
-28556,1519790061525,187
-28557,1519790086531,204
-28558,1519790096718,217
-28559,1519790202748,258
-28560,1519790726551,256
-28561,1519791104589,249
-28562,1519791182538,243
-28563,1519791532314,242
-28564,1519791589335,234
-28565,1519791958825,234
-28566,1519792536124,227
-28567,1519793103071,219
-28568,1519793240505,217
-28569,1519793250597,211
-28570,1519793394412,270
-28571,1519793404298,264
-28572,1519793611264,326
-28573,1519793927518,321
-28574,1519794098135,314
-28575,1519794452524,307
-28576,1519794995065,311
-28577,1519795156780,303
-28578,1519795228267,300
-28579,1519795255750,300
-28580,1519796385169,318
-28581,1519796437458,307
-28582,1519796492531,310
-28583,1519797152555,313
-28584,1519797283198,304
-28585,1519797557697,298
-28586,1519797688209,290
-28587,1519797705605,284
-28588,1519798046093,311
-28589,1519798228509,302
-28590,1519798398470,296
-28591,1519798763257,288
-28592,1519798822587,284
-28593,1519798941343,284
-28594,1519798971884,279
-28595,1519799549215,291
-28596,1519799719582,279
-28597,1519799978596,272
-28598,1519800040477,266
-28599,1519800357813,263
-28600,1519800725346,253
-28601,1519800774364,248
-28602,1519800809981,248
-28603,1519800997532,258
-28604,1519801066724,248
-28605,1519801267122,245
-28606,1519801472017,235
-28607,1519801522358,233
-28608,1519801850554,232
-28609,1519801983873,225
-28610,1519802688401,218
-28611,1519802910971,213
-28612,1519804337901,202
-28613,1519804446436,200
-28614,1519804454170,194
-28615,1519804718652,244
-28616,1519804948194,238
-28617,1519804965718,230
-28618,1519805357957,249
-28619,1519806012075,238
-28620,1519806111119,228
-28621,1519806295879,220
-28622,1519806752675,221
-28623,1519806974483,212
-28624,1519807067166,206
-28625,1519807811724,201
-28626,1519808661938,190
-28627,1519808822522,182
-28628,1519809249688,171
-28629,1519809378155,161
-28630,1519809484570,152
-28631,1519809514334,165
-28632,1519810375415,166
-28633,1519810398044,155
-28634,1519810423156,160
-28635,1519810451187,163
-28636,1519810797028,167
-28637,1519810827043,162
-28638,1519810877170,165
-28639,1519811017864,161
-28640,1519811333758,152
-28641,1519811769315,163
-28642,1519812358592,153
-28643,1519812856292,141
-28644,1519812915596,133
-28645,1519813026598,127
-28646,1519813457754,118
-28647,1519813554215,112
-28648,1519813767881,104
-28649,1519814237881,94
-28650,1519814250465,82
-28651,1519814377127,111
-28652,1519814446602,103
-28653,1519814495321,96
-28654,1519814574542,89
-28655,1519814682364,82
-28656,1519814877821,73
-28657,1519814988113,71
-28658,1519814997885,71
-28659,1519815045958,103
-28660,1519815299507,100
-28661,1519815309429,91
-28662,1519815436161,103
-28663,1519815622438,98
-28664,1519815646781,89
-28665,1519815661284,91
-28666,1519815733550,97
-28667,1519815750739,89
-28668,1519815813097,91
-28669,1519815822997,85
-28670,1519815881028,120
-28671,1519815955319,117
-28672,1519816037224,142
-28673,1519816071074,138
-28674,1519816250262,140
-28675,1519816413008,133
-28676,1519816619425,126
-28677,1519816753399,118
-28678,1519816991581,113
-28679,1519817082745,108
-28680,1519817195247,115
-28681,1519817214635,108
-28682,1519817286533,119
-28683,1519817336896,121
-28684,1519817626194,117
-28685,1519817723043,112
-28686,1519817814202,106
-28687,1519817872236,103
-28688,1519817945034,118
-28689,1519818198175,113
-28690,1519818643171,108
-28691,1519818735382,101
-28692,1519818759816,96
-28693,1519818942879,103
-28694,1519819054634,99
-28695,1519819244968,103
-28696,1519819266986,96
-28697,1519819296125,100
-28698,1519819371824,101
-28699,1519819486344,102
-28700,1519819506046,96
-28701,1519819857484,100
-28702,1519820018677,98
-28703,1519820045724,100
-28704,1519820063134,102
-28705,1519820145167,112
-28706,1519820407581,109
-28707,1519820483342,103
-28708,1519820979992,103
-28709,1519821105431,96
-28710,1519821120327,91
-28711,1519821152040,98
-28712,1519821239732,99
-28713,1519821775611,93
-28714,1519821836443,87
-28715,1519822044817,113
-28716,1519822131863,108
-28717,1519822272004,104
-28718,1519822323395,115
-28719,1519822347684,113
-28720,1519822530950,118
-28721,1519822625432,115
-28722,1519822836853,112
-28723,1519823350200,107
-28724,1519823701038,101
-28725,1519823725479,97
-28726,1519823829498,100
-28727,1519823837064,94
-28728,1519823864223,119
-28729,1519823987286,122
-28730,1519824294009,117
-28731,1519824301638,113
-28732,1519824510233,147
-28733,1519824527661,141
-28734,1519824678194,161
-28735,1519824808561,162
-28736,1519825037003,164
-28737,1519825078389,159
-28738,1519825187262,166
-28739,1519825194758,166
-28740,1519825321691,214
-28741,1519825841142,209
-28742,1519826150240,202
-28743,1519826463274,195
-28744,1519826638686,188
-28745,1519826682314,186
-28746,1519826782442,188
-28747,1519827051595,184
-28748,1519827119854,178
-28749,1519827132267,177
-28750,1519827323158,202
-28751,1519827614897,204
-28752,1519827773963,197
-28753,1519827784002,192
-28754,1519828046204,231
-28755,1519828114508,226
-28756,1519828552491,224
-28757,1519828576861,217
-28758,1519829035887,229
-28759,1519829205580,228
-28760,1519829453455,224
-28761,1519829643411,217
-28762,1519829699311,221
-28763,1519829818188,222
-28764,1519830382364,218
-28765,1519830401939,213
-28766,1519830601351,237
-28767,1519830637706,232
-28768,1519830793997,244
-28769,1519831118858,240
-28770,1519831257537,242
-28771,1519831445700,239
-28772,1519832301529,234
-28773,1519832529673,227
-28774,1519832830543,226
-28775,1519832850076,219
-28776,1519833307254,237
-28777,1519833341635,229
-28778,1519833653053,237
-28779,1519833731690,229
-28780,1519834008738,228
-28781,1519834157129,221
-28782,1519834928289,221
-28783,1519835005841,214
-28784,1519835173520,214
-28785,1519835646003,208
-28786,1519835896812,200
-28787,1519836035487,194
-28788,1519836295280,189
-28789,1519836633162,183
-28790,1519836745593,175
-28791,1519836806370,169
-28792,1519836845476,168
-28793,1519837411158,173
-28794,1519837751790,164
-28795,1519838096697,156
-28796,1519838673523,148
-28797,1519838709997,145
-28798,1519838931247,148
-28799,1519839038525,142
-28800,1519839263907,136
-28801,1519839455943,134
-28802,1519839595274,127
-28803,1519839812213,119
-28804,1519840039512,115
-28805,1519840137108,115
-28806,1519840531739,109
-28807,1519840650139,101
-28808,1519840819977,96
-28809,1519840858777,88
-28810,1519840963098,86
-28811,1519841203743,85
-28812,1519841233289,81
-28813,1519841460133,80
-28814,1519841467686,72
-28815,1519841502256,88
-28816,1519841553588,85
-28817,1519841657572,80
-28818,1519841677584,74
-28819,1519841706852,75
-28820,1519841743793,78
-28821,1519841763523,74
-28822,1519841867805,76
-28823,1519842052028,68
-28824,1519842088634,60
-28825,1519842178287,55
-28826,1519842255639,51
-28827,1519842301675,44
-28828,1519842394189,52
-28829,1519842406514,49
-28830,1519842448107,52
-28831,1519842640248,46
-28832,1519842802786,55
-28833,1519842863707,49
-28834,1519842960538,52
-28835,1519843185778,46
-28836,1519843203172,40
-28837,1519843213113,38
-28838,1519843240242,44
-28839,1519843247731,41
-28840,1519843371466,72
-28841,1519843426700,68
-28842,1519843473087,64
-28843,1519843544099,60
-28844,1519843612681,55
-28845,1519843837980,51
-28846,1519843891445,49
-28847,1519843937846,46
-28848,1519844049116,41
-28849,1519844178264,38
-28850,1519844238943,49
-28851,1519844275291,45
-28852,1519844367355,41
-28853,1519844408755,37
-28854,1519844450348,57
-28855,1519844489390,54
-28856,1519844640849,56
-28857,1519844660630,50
-28858,1519844668111,61
-28859,1519844767553,75
-28860,1519844914905,72
-28861,1519845052491,68
-28862,1519845235297,65
-28863,1519845313794,64
-28864,1519845553586,62
-28865,1519845568402,58
-28866,1519845655859,74
-28867,1519845832040,72
-28868,1519845856794,74
-28869,1519845947366,78
-28870,1519846023059,75
-28871,1519846037804,74
-28872,1519846128082,82
-28873,1519846182080,79
-28874,1519846201754,78
-28875,1519846313110,83
-28876,1519846349399,92
-28877,1519846468337,94
-28878,1519846625340,98
-28879,1519846794892,95
-28880,1519847005072,95
-28881,1519847036875,92
-28882,1519847334482,94
-28883,1519847424151,90
-28884,1519847567788,91
-28885,1519847599599,88
-28886,1519847633752,91
-28887,1519847706789,92
-28888,1519847759993,92
-28889,1519847819113,92
-28890,1519847902318,91
-28891,1519847919743,89
-28892,1519847970650,100
-28893,1519847997817,104
-28894,1519848024734,109
-28895,1519848317960,113
-28896,1519848410096,109
-28897,1519848550632,106
-28898,1519848609342,107
-28899,1519848655815,107
-28900,1519848788268,108
-28901,1519848945920,105
-28902,1519849119747,101
-28903,1519849260398,99
-28904,1519849405653,95
-28905,1519849415985,92
-28906,1519849684819,108
-28907,1519850158084,104
-28908,1519850213734,99
-28909,1519850221578,99
-28910,1519850275812,126
-28911,1519850285710,126
-28912,1519850392167,151
-28913,1519851092128,150
-28914,1519851164812,144
-28915,1519851562543,154
-28916,1519851669714,151
-28917,1519851846280,151
-28918,1519852010966,147
-28919,1519852317237,147
-28920,1519852324690,145
-28921,1519852590656,188
-28922,1519853829833,187
-28923,1519855258866,181
-28924,1519855361164,176
-28925,1519855622742,175
-28926,1519856047875,170
-28927,1519856180733,165
-28928,1519856900818,163
-28929,1519857518198,157
-28930,1519857639239,156
-28931,1519858087391,153
-28932,1519858495302,148
-28933,1519858544039,142
-28934,1519858750037,144
-28935,1519858920946,140
-28936,1519859006466,135
-28937,1519859290087,135
-28938,1519859478072,134
-28939,1519859567642,131
-28940,1519859592278,135
-28941,1519859780470,142
-28942,1519859863068,138
-28943,1519860181024,138
-28944,1519860200790,133
-28945,1519860623377,144
-28946,1519861031385,138
-28947,1519861180249,133
-28948,1519861234281,130
-28949,1519861355335,129
-28950,1519861487281,125
-28951,1519862150605,121
-28952,1519862495742,117
-28953,1519862592600,111
-28954,1519862614987,107
-28955,1519862651356,114
-28956,1519862676098,117
-28957,1519862736914,121
-28958,1519863029608,122
-28959,1519863326193,126
-28960,1519863341166,121
-28961,1519863480222,133
-28962,1519863492630,130
-28963,1519863626364,147
-28964,1519863764263,144
-28965,1519863983906,139
-28966,1519864065929,137
-28967,1519864150175,135
-28968,1519864177457,133
-28969,1519864409262,140
-28970,1519865364777,135
-28971,1519865591189,129
-28972,1519865736073,129
-28973,1519866143069,125
-28974,1519866279188,120
-28975,1519866667753,119
-28976,1519866817579,113
-28977,1519866942314,111
-28978,1519866988804,107
-28979,1519867152856,106
-28980,1519867189505,101
-28981,1519867313220,101
-28982,1519867514887,99
-28983,1519867616747,93
-28984,1519867880390,90
-28985,1519867983440,83
-28986,1519868174159,82
-28987,1519868222733,79
-28988,1519868252437,77
-28989,1519868428687,79
-28990,1519868482112,74
-28991,1519868571919,72
-28992,1519868586494,73
-28993,1519868647215,81
-28994,1519868679207,81
-28995,1519868783266,86
-28996,1519868995357,80
-28997,1519869048990,76
-28998,1519869124962,74
-28999,1519869296682,72
-29000,1519869442779,68
-29001,1519869462463,63
-29002,1519869523175,65
-29003,1519869662150,62
-29004,1519869737478,56
-29005,1519869771626,52
-29006,1519869865710,59
-29007,1519869928468,55
-29008,1519870129169,51
-29009,1519870254883,47
-29010,1519870340072,57
-29011,1519870456374,55
-29012,1519870485522,66
-29013,1519870859010,67
-29014,1519870883665,62
-29015,1519871119085,65
-29016,1519871165277,60
-29017,1519871286458,59
-29018,1519871352627,56
-29019,1519871372286,53
-29020,1519871585198,55
-29021,1519871597594,73
-29022,1519871654122,84
-29023,1519871804904,82
-29024,1519872236824,78
-29025,1519872366669,75
-29026,1519872457091,71
-29027,1519872854612,69
-29028,1519872869322,66
-29029,1519872985582,71
-29030,1519873000626,67
-29031,1519873150764,74
-29032,1519873278865,71
-29033,1519873468507,66
-29034,1519873625282,66
-29035,1519874036738,62
-29036,1519874107118,58
-29037,1519874138883,57
-29038,1519874158591,56
-29039,1519874183078,58
-29040,1519874227148,59
-29041,1519874261314,64
-29042,1519874324801,64
-29043,1519874441571,64
-29044,1519874579451,60
-29045,1519874715624,64
-29046,1519875082253,60
-29047,1519875109097,55
-29048,1519875155347,57
-29049,1519875345607,57
-29050,1519875399316,53
-29051,1519875411644,52
-29052,1519875438393,58
-29053,1519875477291,58
-29054,1519875535218,57
-29055,1519875589639,60
-29056,1519875613890,61
-29057,1519875932818,68
-29058,1519875983550,65
-29059,1519876074323,64
-29060,1519876463845,62
-29061,1519876517469,66
-29062,1519876529860,66
-29063,1519876583390,87
-29064,1519876632187,88
-29065,1519876697992,88
-29066,1519876793666,87
-29067,1519876801497,87
-29068,1519876842832,111
-29069,1519876994585,118
-29070,1519877232879,116
-29071,1519877339933,112
-29072,1519877359553,111
-29073,1519877410570,120
-29074,1519877456915,121
-29075,1519877500807,123
-29076,1519877579197,125
-29077,1519877940994,124
-29078,1519878270981,121
-29079,1519878425350,119
-29080,1519878770274,117
-29081,1519878809302,116
-29082,1519879410950,119
-29083,1519879510118,114
-29084,1519879613764,113
-29085,1519879830805,111
-29086,1519879860214,107
-29087,1519879882372,111
-29088,1519880186222,120
-29089,1519880234961,119
-29090,1519880289064,119
-29091,1519880313238,121
-29092,1519880470618,128
-29093,1519880572649,131
-29094,1519880763511,130
-29095,1519880790358,129
-29096,1519881048988,136
-29097,1519881356481,132
-29098,1519881861912,129
-29099,1519881925149,125
-29100,1519882079455,125
-29101,1519882200398,121
-29102,1519882612455,123
-29103,1519882837264,119
-29104,1519883093423,115
-29105,1519883609319,111
-29106,1519883633825,108
-29107,1519883655736,114
-29108,1519883803664,122
-29109,1519883837745,118
-29110,1519884114965,121
-29111,1519884399047,117
-29112,1519884501473,112
-29113,1519884684054,112
-29114,1519884716043,108
-29115,1519884742968,113
-29116,1519884784061,118
-29117,1519885018683,120
-29118,1519885258785,116
-29119,1519885273639,112
-29120,1519885669568,127
-29121,1519885703751,122
-29122,1519885865483,132
-29123,1519885970261,129
-29124,1519886076969,127
-29125,1519886291195,123
-29126,1519886334933,119
-29127,1519886391017,120
-29128,1519886422696,119
-29129,1519886471936,128
-29130,1519886800833,128
-29131,1519887163230,128
-29132,1519887288011,123
-29133,1519887442983,120
-29134,1519887674972,116
-29135,1519887704466,111
-29136,1519887892766,114
-29137,1519888044985,110
-29138,1519888100763,107
-29139,1519888118226,109
-29140,1519888246330,120
-29141,1519888275613,118
-29142,1519888292727,123
-29143,1519888633618,136
-29144,1519888871868,131
-29145,1519888969269,125
-29146,1519889035306,122
-29147,1519889146684,120
-29148,1519889554733,118
-29149,1519889782078,114
-29150,1519890184664,108
-29151,1519890204467,103
-29152,1519890236328,114
-29153,1519890357859,119
-29154,1519890440226,116
-29155,1519890549587,112
-29156,1519890600425,110
-29157,1519890612924,112
-29158,1519890655344,127
-29159,1519890689233,128
-29160,1519890863217,131
-29161,1519891044556,126
-29162,1519891095282,120
-29163,1519891747873,126
-29164,1519891808201,121
-29165,1519891912324,121
-29166,1519892144783,118
-29167,1519892200607,114
-29168,1519892249837,125
-29169,1519892335115,128
-29170,1519892799467,126
-29171,1519892826380,119
-29172,1519892928195,125
-29173,1519893063807,127
-29174,1519893567926,126
-29175,1519893577641,123
-29176,1519893665323,150
-29177,1519893779946,149
-29178,1519893836058,145
-29179,1519894006435,145
-29180,1519894151025,141
-29181,1519894286732,137
-29182,1519894433013,135
-29183,1519894471906,131
-29184,1519894503665,133
-29185,1519894518572,137
-29186,1519894533785,152
-29187,1519894689416,173
-29188,1519894791523,174
-29189,1519895482144,170
-29190,1519895557202,167
-29191,1519895639561,167
-29192,1519895872204,170
-29193,1519896171636,165
-29194,1519896313143,161
-29195,1519896706655,156
-29196,1519896787304,156
-29197,1519897013520,154
-29198,1519897230604,148
-29199,1519897672734,143
-29200,1519897714022,138
-29201,1519898102910,140
-29202,1519898284683,135
-29203,1519898448790,129
-29204,1519898485466,124
-29205,1519898711880,125
-29206,1519898748830,119
-29207,1519898862297,124
-29208,1519898940568,126
-29209,1519899099843,123
-29210,1519899665978,122
-29211,1519899859549,116
-29212,1519900164755,110
-29213,1519900218588,105
-29214,1519900301424,102
-29215,1519900384774,103
-29216,1519900486271,104
-29217,1519900607622,102
-29218,1519900663675,98
-29219,1519900675834,96
-29220,1519900880760,116
-29221,1519901109948,110
-29222,1519901269826,109
-29223,1519901297067,105
-29224,1519901441995,108
-29225,1519901468621,104
-29226,1519901526705,107
-29227,1519902368801,107
-29228,1519902386068,102
-29229,1519902446681,114
-29230,1519902466158,115
-29231,1519902527055,123
-29232,1519902877168,120
-29233,1519903193395,115
-29234,1519903220174,108
-29235,1519903285612,111
-29236,1519903449728,112
-29237,1519903519769,107
-29238,1519903565922,104
-29239,1519903652815,105
-29240,1519903761388,107
-29241,1519903918882,103
-29242,1519904044509,102
-29243,1519904141498,106
-29244,1519904243362,102
-29245,1519904253410,98
-29246,1519904294688,116
-29247,1519904473616,117
-29248,1519904766276,113
-29249,1519904822029,107
-29250,1519904983766,105
-29251,1519905015402,99
-29252,1519905346071,105
-29253,1519905408895,103
-29254,1519905430830,101
-29255,1519905581117,106
-29256,1519905682823,102
-29257,1519905767909,99
-29258,1519905780290,106
-29259,1519905822157,123
-29260,1519905849489,127
-29261,1519905987875,133
-29262,1519906147797,127
-29263,1519906170196,125
-29264,1519906371176,132
-29265,1519906602711,128
-29266,1519906656488,123
-29267,1519906664364,121
-29268,1519907014145,153
-29269,1519907131630,149
-29270,1519907241119,146
-29271,1519907263185,142
-29272,1519907449147,155
-29273,1519907493383,150
-29274,1519907535354,151
-29275,1519907598794,152
-29276,1519907640801,165
-29277,1519908146895,169
-29278,1519908154307,163
-29279,1519908724984,212
-29280,1519908737382,204
-29281,1519909027079,237
-29282,1519909348073,230
-29283,1519909450999,224
-29284,1519909637994,224
-29285,1519909736296,224
-29286,1519909797939,231
-29287,1519910369037,244
-29288,1519910536585,238
-29289,1519910865357,235
-29290,1519911001683,228
-29291,1519911079705,226
-29292,1519911162755,227
-29293,1519911175445,226
-29294,1519911630907,261
-29295,1519911717125,254
-29296,1519912474060,252
-29297,1519912719641,247
-29298,1519913177919,241
-29299,1519913479667,233
-29300,1519913526688,226
-29301,1519913590970,232
-29302,1519914006522,232
-29303,1519914397381,225
-29304,1519915030567,218
-29305,1519915089677,213
-29306,1519915288919,213
-29307,1519915495991,210
-29308,1519915916722,205
-29309,1519915980266,198
-29310,1519916166983,197
-29311,1519916347303,191
-29312,1519916856036,184
-29313,1519917659494,177
-29314,1519917932729,170
-29315,1519918233560,163
-29316,1519918260584,157
-29317,1519918400588,163
-29318,1519918447763,157
-29319,1519918777993,158
-29320,1519919150540,159
-29321,1519919274129,151
-29322,1519919434710,146
-29323,1519919540950,140
-29324,1519919593094,138
-29325,1519919627997,136
-29326,1519919693087,140
-29327,1519919923884,139
-29328,1519919981117,131
-29329,1519920263122,134
-29330,1519920418432,129
-29331,1519920450777,129
-29332,1519920507440,132
-29333,1519920557403,129
-29334,1519920584735,126
-29335,1519920669284,133
-29336,1519920828957,129
-29337,1519920881472,123
-29338,1519921005654,122
-29339,1519921193516,117
-29340,1519921208598,111
-29341,1519921265868,121
-29342,1519921666564,117
-29343,1519921843951,109
-29344,1519921873708,103
-29345,1519922156168,102
-29346,1519922173505,106
-29347,1519922284745,115
-29348,1519922563185,109
-29349,1519922603040,101
-29350,1519922669648,100
-29351,1519922753548,95
-29352,1519922863207,92
-29353,1519923024461,85
-29354,1519923306962,79
-29355,1519923460296,76
-29356,1519923502477,69
-29357,1519923524863,66
-29358,1519923584493,65
-29359,1519923611589,69
-29360,1519923631338,69
-29361,1519923658422,75
-29362,1519923745207,73
-29363,1519923908548,68
-29364,1519923928593,66
-29365,1519924025403,67
-29366,1519924065081,60
-29367,1519924092342,57
-29368,1519924102265,72
-29369,1519924144213,82
-29370,1519924404002,80
-29371,1519924461307,73
-29372,1519924479158,76
-29373,1519924543556,79
-29374,1519924570942,77
-29375,1519924774056,80
-29376,1519924808815,75
-29377,1519924821155,77
-29378,1519925050212,85
-29379,1519925161867,104
-29380,1519925252057,98
-29381,1519925470452,114
-29382,1519925603954,109
-29383,1519925634089,104
-29384,1519925733940,109
-29385,1519926118407,105
-29386,1519926180300,101
-29387,1519926212972,103
-29388,1519926543700,104
-29389,1519926655512,99
-29390,1519926665721,95
-29391,1519926885359,113
-29392,1519927293143,110
-29393,1519927407181,107
-29394,1519927529541,124
-29395,1519927559502,120
-29396,1519927589477,127
-29397,1519927609403,131
-29398,1519927918293,140
-29399,1519928346337,135
-29400,1519928412355,131
-29401,1519928494052,134
-29402,1519928571161,136
-29403,1519928800722,133
-29404,1519928855183,128
-29405,1519928907182,128
-29406,1519929117548,132
-29407,1519929204685,127
-29408,1519929217222,125
-29409,1519929452192,143
-29410,1519929742475,141
-29411,1519929872335,136
-29412,1519929978961,133
-29413,1519930048502,129
-29414,1519930120254,127
-29415,1519930296383,124
-29416,1519930321616,120
-29417,1519930559439,131
-29418,1519930623893,126
-29419,1519930658571,128
-29420,1519930894894,130
-29421,1519930977348,124
-29422,1519931263949,123
-29423,1519931310868,118
-29424,1519931427923,118
-29425,1519931440157,116
-29426,1519931536293,136
-29427,1519931767346,134
-29428,1519931782491,130
-29429,1519931802355,146
-29430,1519932043868,156
-29431,1519932344497,151
-29432,1519932509320,149
-29433,1519932893209,146
-29434,1519932987263,143
-29435,1519932994798,145
-29436,1519933431561,185
-29437,1519933839967,179
-29438,1519933889670,174
-29439,1519934641362,176
-29440,1519934982231,170
-29441,1519935038746,171
-29442,1519935830590,174
-29443,1519935907672,167
-29444,1519936140374,164
-29445,1519936162545,162
-29446,1519936349278,172
-29447,1519936436824,174
-29448,1519936647834,172
-29449,1519936667944,167
-29450,1519936783282,181
-29451,1519936805923,179
-29452,1519937164334,190
-29453,1519937904026,185
-29454,1519938033685,178
-29455,1519938265132,173
-29456,1519938323340,166
-29457,1519938656753,166
-29458,1519938704541,163
-29459,1519938915987,164
-29460,1519939481130,160
-29461,1519939832860,157
-29462,1519939875509,153
-29463,1519939939744,154
-29464,1519940409047,152
-29465,1519940544122,149
-29466,1519940593925,143
-29467,1519941864093,144
-29468,1519941954385,138
-29469,1519942223865,143
-29470,1519942507207,139
-29471,1519942690191,132
-29472,1519942747705,127
-29473,1519942772893,129
-29474,1519942832250,135
-29475,1519943002712,136
-29476,1519943253269,130
-29477,1519943331920,126
-29478,1519943463016,129
-29479,1519943927536,124
-29480,1519944364369,118
-29481,1519944435251,113
-29482,1519944509676,109
-29483,1519944702395,106
-29484,1519944815887,103
-29485,1519945027888,99
-29486,1519945065042,92
-29487,1519945203461,93
-29488,1519945281606,91
-29489,1519945536611,86
-29490,1519945601302,80
-29491,1519945624622,86
-29492,1519945686668,89
-29493,1519945767166,85
-29494,1519945792179,80
-29495,1519946090234,82
-29496,1519946140161,80
-29497,1519946246543,82
-29498,1519946440841,84
-29499,1519946448388,78
-29500,1519946607686,96
-29501,1519946946416,93
-29502,1519947130719,87
-29503,1519947161068,83
-29504,1519947188579,84
-29505,1519947216477,86
-29506,1519947236746,89
-29507,1519947401405,92
-29508,1519947649601,88
-29509,1519947674194,93
-29510,1519947938187,95
-29511,1519947983208,89
-29512,1519948037063,88
-29513,1519948471865,86
-29514,1519948932085,81
-29515,1519949015042,76
-29516,1519949084710,71
-29517,1519949135788,73
-29518,1519949170892,70
-29519,1519949245917,70
-29520,1519949449949,68
-29521,1519949596495,63
-29522,1519949653701,58
-29523,1519949666310,54
-29524,1519949902055,60
-29525,1519949934721,55
-29526,1519949944708,64
-29527,1519950122196,73
-29528,1519950192649,68
-29529,1519950356030,74
-29530,1519950431324,77
-29531,1519950601894,74
-29532,1519950875681,69
-29533,1519951071289,64
-29534,1519951185258,59
-29535,1519951249995,55
-29536,1519951460944,75
-29537,1519951556730,70
-29538,1519951807767,67
-29539,1519951926917,65
-29540,1519951964088,62
-29541,1519952031003,61
-29542,1519952064853,60
-29543,1519952111538,59
-29544,1519952187405,59
-29545,1519952469917,56
-29546,1519952480009,60
-29547,1519952664995,70
-29548,1519952764798,67
-29549,1519952779739,64
-29550,1519952908361,79
-29551,1519953072935,77
-29552,1519953168289,82
-29553,1519953224234,80
-29554,1519953417599,78
-29555,1519953432718,76
-29556,1519953579707,83
-29557,1519953821077,83
-29558,1519953843638,79
-29559,1519953873065,87
-29560,1519953908501,89
-29561,1519953938709,90
-29562,1519953968238,93
-29563,1519954080406,99
-29564,1519954145062,98
-29565,1519954225894,97
-29566,1519954256056,96
-29567,1519954389596,101
-29568,1519954451649,98
-29569,1519954500834,98
-29570,1519954684914,98
-29571,1519954781563,94
-29572,1519954878453,92
-29573,1519954900712,91
-29574,1519955137921,102
-29575,1519955274484,100
-29576,1519955548607,97
-29577,1519955780022,94
-29578,1519955844524,91
-29579,1519955916275,90
-29580,1519955987819,88
-29581,1519956133766,85
-29582,1519956353578,84
-29583,1519956661177,81
-29584,1519956792223,76
-29585,1519956940919,74
-29586,1519957027319,70
-29587,1519957086699,70
-29588,1519957207772,68
-29589,1519957240616,65
-29590,1519957447213,65
-29591,1519957572791,62
-29592,1519957590046,62
-29593,1519957640288,68
-29594,1519957711380,67
-29595,1519957918280,68
-29596,1519958005702,64
-29597,1519958018177,62
-29598,1519958025853,70
-29599,1519958080217,87
-29600,1519958090276,98
-29601,1519958185494,117
-29602,1519958280350,114
-29603,1519958309806,112
-29604,1519958359607,119
-29605,1519958428384,123
-29606,1519958475358,124
-29607,1519958734160,131
-29608,1519958766454,127
-29609,1519958882554,131
-29610,1519959068153,133
-29611,1519959684162,129
-29612,1519959716350,126
-29613,1519959768725,132
-29614,1519959821311,132
-29615,1519959918299,134
-29616,1519960211562,131
-29617,1519960396748,128
-29618,1519960414092,126
-29619,1519960604888,140
-29620,1519960699410,136
-29621,1519960877152,134
-29622,1519961242035,131
-29623,1519961346408,126
-29624,1519961575438,129
-29625,1519961716097,125
-29626,1519961768321,122
-29627,1519961788044,130
-29628,1519962238618,141
-29629,1519962468802,137
-29630,1519962711666,133
-29631,1519962800417,129
-29632,1519963212822,127
-29633,1519963548090,123
-29634,1519963992678,118
-29635,1519964044644,113
-29636,1519964067311,113
-29637,1519964099768,119
-29638,1519964917152,123
-29639,1519965005669,117
-29640,1519965201036,114
-29641,1519965385415,112
-29642,1519965450167,108
-29643,1519965613964,108
-29644,1519965668474,105
-29645,1519965718732,104
-29646,1519965924338,103
-29647,1519965971830,105
-29648,1519965994352,105
-29649,1519966024400,110
-29650,1519966108215,118
-29651,1519966213329,115
-29652,1519966237926,112
-29653,1519966525888,118
-29654,1519966870937,114
-29655,1519966962310,108
-29656,1519966977300,112
-29657,1519967204375,123
-29658,1519967681320,118
-29659,1519967698997,117
-29660,1519968082604,130
-29661,1519968475188,127
-29662,1519968699197,125
-29663,1519969279919,124
-29664,1519969591133,119
-29665,1519969613696,115
-29666,1519969890050,123
-29667,1519969902467,121
-29668,1519969939544,139
-29669,1519970068376,143
-29670,1519970539121,142
-29671,1519971065397,136
-29672,1519971090868,132
-29673,1519971418899,138
-29674,1519971473321,137
-29675,1519971610156,137
-29676,1519971647304,133
-29677,1519971672550,136
-29678,1519971854462,143
-29679,1519972143472,139
-29680,1519972397117,134
-29681,1519972417121,130
-29682,1519972758327,139
-29683,1519973057616,133
-29684,1519973137345,127
-29685,1519973369419,124
-29686,1519973475742,120
-29687,1519973498315,116
-29688,1519973537359,123
-29689,1519973722996,123
-29690,1519973804982,119
-29691,1519973899720,116
-29692,1519974001044,112
-29693,1519974127706,111
-29694,1519974214070,108
-29695,1519974445304,104
-29696,1519974607184,99
-29697,1519975003202,94
-29698,1519975156950,92
-29699,1519975251881,98
-29700,1519975334045,95
-29701,1519975356669,103
-29702,1519975518471,109
-29703,1519975578506,105
-29704,1519975722113,107
-29705,1519975809766,106
-29706,1519976000490,104
-29707,1519976057764,101
-29708,1519976085172,100
-29709,1519976271692,107
-29710,1519976567974,103
-29711,1519976661980,98
-29712,1519976832343,94
-29713,1519976893827,94
-29714,1519977035546,95
-29715,1519977099925,92
-29716,1519977214556,91
-29717,1519977236877,87
-29718,1519977476685,91
-29719,1519977627457,95
-29720,1519977661483,91
-29721,1519977841382,93
-29722,1519978100867,89
-29723,1519978175096,84
-29724,1519978316388,82
-29725,1519978401586,78
-29726,1519978507040,74
-29727,1519978519822,73
-29728,1519978546750,89
-29729,1519978710539,91
-29730,1519978755106,87
-29731,1519978784598,85
-29732,1519978806967,88
-29733,1519979043873,92
-29734,1519979219625,86
-29735,1519979487926,82
-29736,1519979510916,79
-29737,1519979543255,86
-29738,1519979558279,91
-29739,1519979729491,99
-29740,1519979781549,95
-29741,1519979826640,94
-29742,1519979853904,94
-29743,1519979962243,97
-29744,1519980066191,93
-29745,1519980093366,91
-29746,1519980162335,95
-29747,1519980236494,92
-29748,1519980293682,91
-29749,1519980328814,94
-29750,1519980341238,98
-29751,1519980368531,112
-29752,1519980425461,117
-29753,1519980805393,121
-29754,1519980815553,115
-29755,1519980915263,135
-29756,1519980987431,133
-29757,1519981290772,139
-29758,1519981424855,134
-29759,1519981489094,130
-29760,1519981599518,136
-29761,1519981723579,132
-29762,1519981751238,128
-29763,1519981786338,134
-29764,1519981971243,136
-29765,1519982013358,131
-29766,1519982228545,137
-29767,1519982263816,132
-29768,1519982656454,146
-29769,1519982752921,144
-29770,1519982790501,143
-29771,1519982948865,145
-29772,1519983040252,141
-29773,1519983217191,144
-29774,1519983232116,139
-29775,1519983398250,158
-29776,1519983706114,154
-29777,1519983811169,153
-29778,1519984128735,156
-29779,1519984267549,151
-29780,1519984481473,148
-29781,1519984584290,143
-29782,1519984768528,148
-29783,1519985088877,144
-29784,1519985166988,138
-29785,1519985357740,138
-29786,1519985394522,134
-29787,1519985607680,137
-29788,1519985732226,138
-29789,1519985802109,137
-29790,1519985930839,136
-29791,1519986013008,134
-29792,1519986141010,134
-29793,1519986261010,130
-29794,1519986344495,127
-29795,1519986361886,126
-29796,1519986574709,137
-29797,1519986703509,133
-29798,1519986951929,129
-29799,1519986987003,123
-29800,1519987068458,126
-29801,1519987078215,124
-29802,1519987095510,154
-29803,1519987317089,168
-29804,1519987337109,165
-29805,1519987518884,178
-29806,1519987703645,173
-29807,1519988060998,169
-29808,1519988333512,165
-29809,1519988470135,163
-29810,1519988559365,158
-29811,1519988626700,155
-29812,1519988685880,155
-29813,1519988766212,154
-29814,1519988938839,152
-29815,1519989018737,148
-29816,1519989525727,146
-29817,1519989576311,139
-29818,1519989732509,143
-29819,1519989773831,137
-29820,1519989837408,139
-29821,1519989961402,138
-29822,1519989992760,134
-29823,1519990013205,137
-29824,1519990224609,146
-29825,1519990288288,140
-29826,1519990606425,137
-29827,1519990771107,132
-29828,1519991043753,132
-29829,1519991353253,130
-29830,1519991607895,123
-29831,1519991906133,118
-29832,1519992041328,114
-29833,1519992054145,114
-29834,1519992106953,128
-29835,1519992205037,126
-29836,1519992531529,121
-29837,1519992860982,118
-29838,1519992957194,114
-29839,1519993138349,116
-29840,1519993196954,111
-29841,1519993288222,110
-29842,1519993507200,107
-29843,1519993963007,105
-29844,1519994121869,99
-29845,1519994472838,94
-29846,1519994505593,90
-29847,1519994558791,92
-29848,1519994596834,90
-29849,1519994624703,89
-29850,1519994637262,92
-29851,1519994704145,112
-29852,1519994949223,114
-29853,1519995165617,110
-29854,1519995180921,104
-29855,1519995498598,127
-29856,1519995582262,121
-29857,1519995707099,120
-29858,1519995880931,116
-29859,1519995969219,110
-29860,1519996134849,109
-29861,1519996523069,105
-29862,1519996680441,100
-29863,1519996723402,99
-29864,1519996738746,103
-29865,1519997092792,112
-29866,1519997401570,110
-29867,1519997447268,104
-29868,1519997689000,108
-29869,1519997995457,102
-29870,1519998013307,97
-29871,1519998038610,108
-29872,1519998069110,112
-29873,1519998182559,115
-29874,1519998255909,111
-29875,1519998389066,119
-29876,1519998928568,116
-29877,1519998976758,110
-29878,1519999256493,110
-29879,1519999271914,104
-29880,1519999407112,115
-29881,1519999449665,110
-29882,1519999658515,111
-29883,1520000102604,106
-29884,1520000185693,99
-29885,1520000272372,98
-29886,1520000305222,94
-29887,1520000358198,98
-29888,1520000541455,96
-29889,1520000563991,91
-29890,1520000771117,96
-29891,1520001883828,91
-29892,1520001908836,86
-29893,1520001949626,87
-29894,1520001964904,87
-29895,1520002080434,95
-29896,1520002246471,98
-29897,1520002532855,93
-29898,1520002684040,88
-29899,1520002731850,83
-29900,1520002895179,83
-29901,1520002941264,79
-29902,1520003004269,92
-29903,1520003024399,100
-29904,1520003406110,106
-29905,1520003443988,111
-29906,1520003938314,112
-29907,1520004001761,107
-29908,1520004042316,105
-29909,1520004126527,106
-29910,1520004134211,104
-29911,1520004159566,132
-29912,1520004368434,140
-29913,1520004414727,138
-29914,1520004572692,141
-29915,1520004702447,137
-29916,1520005020520,134
-29917,1520005075778,129
-29918,1520005096371,130
-29919,1520005305664,140
-29920,1520005321006,139
-29921,1520005586106,156
-29922,1520005593722,151
-29923,1520006128405,197
-29924,1520006680747,198
-29925,1520006779908,192
-29926,1520006835569,191
-29927,1520007129118,193
-29928,1520007397787,188
-29929,1520007430805,182
-29930,1520007643435,188
-29931,1520008155865,183
-29932,1520008472528,176
-29933,1520008497953,170
-29934,1520008714856,190
-29935,1520008818341,186
-29936,1520009472444,185
-29937,1520010028254,178
-29938,1520010086344,171
-29939,1520010306315,172
-29940,1520010510695,167
-29941,1520010684576,163
-29942,1520010779052,159
-29943,1520010850427,156
-29944,1520010935281,153
-29945,1520011061411,150
-29946,1520011223876,146
-29947,1520011267169,143
-29948,1520011350435,145
-29949,1520011509016,144
-29950,1520011724073,143
-29951,1520011841417,145
-29952,1520011963823,142
-29953,1520012219393,138
-29954,1520012287530,132
-29955,1520012397067,138
-29956,1520012477874,133
-29957,1520012761085,131
-29958,1520012922742,126
-29959,1520013210019,121
-29960,1520013354163,116
-29961,1520013387931,111
-29962,1520013607596,112
-29963,1520013685676,107
-29964,1520013781272,105
-29965,1520013832603,108
-29966,1520014059489,106
-29967,1520014235590,100
-29968,1520014582220,97
-29969,1520014645982,91
-29970,1520014685923,87
-29971,1520014762216,92
-29972,1520014779829,92
-29973,1520014938092,103
-29974,1520015150516,98
-29975,1520015467097,93
-29976,1520015823925,88
-29977,1520015830415,82
-29978,1520015838316,108
-29979,1520015937355,134
-29980,1520016168145,137
-29981,1520016353808,131
-29982,1520016663357,129
-29983,1520016789371,122
-29984,1520016955011,117
-29985,1520016993123,112
-29986,1520017028490,113
-29987,1520017061056,116
-29988,1520017145136,119
-29989,1520017268128,116
-29990,1520017578448,115
-29991,1520017588708,108
-29992,1520017631542,126
-29993,1520017639188,129
-29994,1520017685131,164
-29995,1520017791234,171
-29996,1520017952393,167
-29997,1520017980225,161
-29998,1520018103762,167
-29999,1520018189807,162
-30000,1520018492828,160
-30001,1520018555662,153
-30002,1520018986329,152
-30003,1520019289025,146
-30004,1520019401889,144
-30005,1520019466840,138
-30006,1520019626359,138
-30007,1520019634154,132
-30008,1520019651928,166
-30009,1520019781828,182
-30010,1520020273417,177
-30011,1520020438875,185
-30012,1520020675314,185
-30013,1520020833366,179
-30014,1520021410391,177
-30015,1520021549817,170
-30016,1520021744857,165
-30017,1520022151888,159
-30018,1520022277746,153
-30019,1520022358614,155
-30020,1520022373864,152
-30021,1520022472122,179
-30022,1520022540158,175
-30023,1520022772667,196
-30024,1520023256438,191
-30025,1520023541788,184
-30026,1520023819451,180
-30027,1520024539006,177
-30028,1520024662746,170
-30029,1520024716162,167
-30030,1520024774045,173
-30031,1520025015929,174
-30032,1520025056793,167
-30033,1520025364366,170
-30034,1520025409944,171
-30035,1520025671484,173
-30036,1520025770484,169
-30037,1520025920941,165
-30038,1520026020057,161
-30039,1520026116516,161
-30040,1520026212891,157
-30041,1520026253627,154
-30042,1520026293548,156
-30043,1520026472690,159
-30044,1520026496068,156
-30045,1520026647632,166
-30046,1520026693269,161
-30047,1520026992944,163
-30048,1520027190186,159
-30049,1520027223218,155
-30050,1520027289500,159
-30051,1520027395004,157
-30052,1520027460678,154
-30053,1520027651665,152
-30054,1520027702009,146
-30055,1520027760235,147
-30056,1520027816595,146
-30057,1520027991384,145
-30058,1520028179297,139
-30059,1520028302808,133
-30060,1520028435526,127
-30061,1520028707189,122
-30062,1520028723863,118
-30063,1520028741517,127
-30064,1520028822607,137
-30065,1520028858156,133
-30066,1520028918377,136
-30067,1520029195534,132
-30068,1520029223422,125
-30069,1520029342875,127
-30070,1520029373287,122
-30071,1520029408747,124
-30072,1520029595210,125
-30073,1520029662744,124
-30074,1520029801306,119
-30075,1520029849358,112
-30076,1520029897937,108
-30077,1520030059844,105
-30078,1520030109752,112
-30079,1520030184540,126
-30080,1520030224837,122
-30081,1520030327954,122
-30082,1520030374183,117
-30083,1520030500466,114
-30084,1520030752438,108
-30085,1520030762327,102
-30086,1520030904012,121
-30087,1520030968870,118
-30088,1520031251708,118
-30089,1520031339500,111
-30090,1520031390336,107
-30091,1520031436394,103
-30092,1520031664926,112
-30093,1520031680396,109
-30094,1520031695999,137
-30095,1520031998329,155
-30096,1520032081720,149
-30097,1520032089304,146
-30098,1520032249517,191
-30099,1520032310295,187
-30100,1520032330251,187
-30101,1520032428505,201
-30102,1520032649580,199
-30103,1520032724964,193
-30104,1520033048882,190
-30105,1520033081436,183
-30106,1520033157920,190
-30107,1520033188194,187
-30108,1520033253703,214
-30109,1520033464296,224
-30110,1520033469025,219
-30111,1520033882789,322
-30112,1520034587856,315
-30113,1520034725794,306
-30114,1520035657803,302
-30115,1520035787626,293
-30116,1520035902272,288
-30117,1520036345368,285
-30118,1520036521888,276
-30119,1520036537599,271
-30120,1520036600368,303
-30121,1520036643656,316
-30122,1520036797617,325
-30123,1520037205988,322
-30124,1520037564091,314
-30125,1520037792878,305
-30126,1520037835924,297
-30127,1520037884040,303
-30128,1520038286608,306
-30129,1520038714329,299
-30130,1520038887633,292
-30131,1520039301695,288
-30132,1520039558344,279
-30133,1520039726178,275
-30134,1520039762157,268
-30135,1520039961306,279
-30136,1520040033030,272
-30137,1520040197437,271
-30138,1520041195454,264
-30139,1520041596118,255
-30140,1520041648432,247
-30141,1520042138977,248
-30142,1520042481320,242
-30143,1520042600954,237
-30144,1520042700435,231
-30145,1520042723346,234
-30146,1520042872386,248
-30147,1520042907711,245
-30148,1520043054067,249
-30149,1520043073515,243
-30150,1520043622606,267
-30151,1520044130297,258
-30152,1520044199133,249
-30153,1520044293640,248
-30154,1520044372182,243
-30155,1520044546697,241
-30156,1520045079871,236
-30157,1520045105101,228
-30158,1520045209269,239
-30159,1520045532284,233
-30160,1520046443568,223
-30161,1520046574070,212
-30162,1520046763490,204
-30163,1520047038832,203
-30164,1520047145385,200
-30165,1520047237676,195
-30166,1520047525058,193
-30167,1520047819067,185
-30168,1520047871907,175
-30169,1520048100363,176
-30170,1520048256309,167
-30171,1520048396798,163
-30172,1520048425078,159
-30173,1520048455470,161
-30174,1520048650397,163
-30175,1520048871938,154
-30176,1520049023305,146
-30177,1520049095550,140
-30178,1520049274936,133
-30179,1520049304113,126
-30180,1520049351135,127
-30181,1520049569252,124
-30182,1520049756014,115
-30183,1520049995945,107
-30184,1520050094135,97
-30185,1520050116837,88
-30186,1520050155054,99
-30187,1520050368359,94
-30188,1520050380995,86
-30189,1520050514389,91
-30190,1520050761176,82
-30191,1520050822420,73
-30192,1520050850286,67
-30193,1520050919351,61
-30194,1520050997159,60
-30195,1520051014898,62
-30196,1520051067766,59
-30197,1520051223833,53
-30198,1520051261919,65
-30199,1520051351025,60
-30200,1520051381349,55
-30201,1520051470245,60
-30202,1520051787823,54
-30203,1520051808033,45
-30204,1520051889857,43
-30205,1520051900113,34
-30206,1520051925398,39
-30207,1520051960693,35
\ No newline at end of file
diff --git a/ergo-core/src/test/resources/execute-script.json b/ergo-core/src/test/resources/execute-script.json
deleted file mode 100644
index 104b871c9e..0000000000
--- a/ergo-core/src/test/resources/execute-script.json
+++ /dev/null
@@ -1,1185 +0,0 @@
-{
- "script": "{ (HEIGHT > deadline) }",
- "namedConstants": {"deadline": {"type": "Int", "value": 1},
- "pkA": { "type": "String", "value": "12345678" } },
- "context": {
- "scriptVersion": 1,
- "lastBlockUtxoRoot" : {
- "digest" : "000000000000000000000000000000000000000000000000000000000000000000",
- "treeFlags" : 7,
- "keyLength" : 32,
- "valueLength" : null
- },
- "headers" : [
- ],
- "preHeader" : {
- "votes" : "",
- "timestamp" : 3,
- "height" : 10,
- "nBits" : 0,
- "version" : 0,
- "minerPk" : "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
- "parentId" : ""
- },
- "dataBoxes" : [
- ],
- "boxesToSpend" : [
- {
- "boxId" : "68a04e9532e9cb721e0a8f74e60e73fe9357eba62095acd98e1154d1440b99d2",
- "value" : 1,
- "ergoTree" : "10010101d17300",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "0000000000000000000000000000000000000000000000000000000000000000",
- "index" : 0
- },
- {
- "boxId" : "68a04e9532e9cb721e0a8f74e60e73fe9357eba62095acd98e1154d1440b99d2",
- "value" : 1,
- "ergoTree" : "10010101d17300",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "0000000000000000000000000000000000000000000000000000000000000000",
- "index" : 0
- },
- {
- "boxId" : "68a04e9532e9cb721e0a8f74e60e73fe9357eba62095acd98e1154d1440b99d2",
- "value" : 1,
- "ergoTree" : "10010101d17300",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "0000000000000000000000000000000000000000000000000000000000000000",
- "index" : 0
- },
- {
- "boxId" : "68a04e9532e9cb721e0a8f74e60e73fe9357eba62095acd98e1154d1440b99d2",
- "value" : 1,
- "ergoTree" : "10010101d17300",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "0000000000000000000000000000000000000000000000000000000000000000",
- "index" : 0
- },
- {
- "boxId" : "68a04e9532e9cb721e0a8f74e60e73fe9357eba62095acd98e1154d1440b99d2",
- "value" : 1,
- "ergoTree" : "10010101d17300",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "0000000000000000000000000000000000000000000000000000000000000000",
- "index" : 0
- },
- {
- "boxId" : "68a04e9532e9cb721e0a8f74e60e73fe9357eba62095acd98e1154d1440b99d2",
- "value" : 1,
- "ergoTree" : "10010101d17300",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "0000000000000000000000000000000000000000000000000000000000000000",
- "index" : 0
- },
- {
- "boxId" : "68a04e9532e9cb721e0a8f74e60e73fe9357eba62095acd98e1154d1440b99d2",
- "value" : 1,
- "ergoTree" : "10010101d17300",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "0000000000000000000000000000000000000000000000000000000000000000",
- "index" : 0
- },
- {
- "boxId" : "68a04e9532e9cb721e0a8f74e60e73fe9357eba62095acd98e1154d1440b99d2",
- "value" : 1,
- "ergoTree" : "10010101d17300",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "0000000000000000000000000000000000000000000000000000000000000000",
- "index" : 0
- },
- {
- "boxId" : "68a04e9532e9cb721e0a8f74e60e73fe9357eba62095acd98e1154d1440b99d2",
- "value" : 1,
- "ergoTree" : "10010101d17300",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "0000000000000000000000000000000000000000000000000000000000000000",
- "index" : 0
- },
- {
- "boxId" : "68a04e9532e9cb721e0a8f74e60e73fe9357eba62095acd98e1154d1440b99d2",
- "value" : 1,
- "ergoTree" : "10010101d17300",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "0000000000000000000000000000000000000000000000000000000000000000",
- "index" : 0
- }
- ],
- "spendingTransaction" : {
- "id" : "a9facd3e2a7c6a9253bbb6cfc5a535762d30f3459bedef04a46b8ea8de5e4ccb",
- "inputs" : [
- ],
- "dataInputs" : [
- ],
- "outputs" : [
- {
- "boxId" : "0bf4750cc49f27e5e9a9b370728ba2186313551e4a6287fdbce6d61a65e051f8",
- "value" : 1,
- "ergoTree" : "0008cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "a9facd3e2a7c6a9253bbb6cfc5a535762d30f3459bedef04a46b8ea8de5e4ccb",
- "index" : 0
- },
- {
- "boxId" : "28030edabb0ebc394313d662069ac216ad300de866888644b89f323e8bcd8d61",
- "value" : 1,
- "ergoTree" : "0008cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "a9facd3e2a7c6a9253bbb6cfc5a535762d30f3459bedef04a46b8ea8de5e4ccb",
- "index" : 1
- },
- {
- "boxId" : "371bfda55caa125253f178d0b08be672d1c6ae5a372055b979708d8430b0cbd8",
- "value" : 1,
- "ergoTree" : "0008cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "a9facd3e2a7c6a9253bbb6cfc5a535762d30f3459bedef04a46b8ea8de5e4ccb",
- "index" : 2
- },
- {
- "boxId" : "a307d01a482b05d5311f60462237fd83d6d7aedeb918baeaca6713f0089e67fc",
- "value" : 1,
- "ergoTree" : "0008cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "a9facd3e2a7c6a9253bbb6cfc5a535762d30f3459bedef04a46b8ea8de5e4ccb",
- "index" : 3
- },
- {
- "boxId" : "a40369be6d85d6c400e92d1ab209ad856dd10ae92bad99cb9b2e1370e86323d3",
- "value" : 1,
- "ergoTree" : "0008cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "a9facd3e2a7c6a9253bbb6cfc5a535762d30f3459bedef04a46b8ea8de5e4ccb",
- "index" : 4
- },
- {
- "boxId" : "883e8d2639532e23cb4970b4fb95575d7da3b9e683f1abd6db473b25c3c9a4c5",
- "value" : 1,
- "ergoTree" : "0008cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "a9facd3e2a7c6a9253bbb6cfc5a535762d30f3459bedef04a46b8ea8de5e4ccb",
- "index" : 5
- },
- {
- "boxId" : "6e50542c7efee569e021b07939c13d79bfedb213842abaaf22a28f696595df80",
- "value" : 1,
- "ergoTree" : "0008cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "a9facd3e2a7c6a9253bbb6cfc5a535762d30f3459bedef04a46b8ea8de5e4ccb",
- "index" : 6
- },
- {
- "boxId" : "3957e356e47b26133d71fd8849bfc1ee3df9a02319e90f0d0585f83cfc734eb5",
- "value" : 1,
- "ergoTree" : "0008cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "a9facd3e2a7c6a9253bbb6cfc5a535762d30f3459bedef04a46b8ea8de5e4ccb",
- "index" : 7
- },
- {
- "boxId" : "66198e6ac8b0b522bbe8434cdce8641e5cdedf0741898ba0104f9ed7c82b6285",
- "value" : 1,
- "ergoTree" : "0008cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "a9facd3e2a7c6a9253bbb6cfc5a535762d30f3459bedef04a46b8ea8de5e4ccb",
- "index" : 8
- },
- {
- "boxId" : "04f8f69d0b719f6dd0a6872f53b58da55ca9644de467a047182999616f3deb13",
- "value" : 1,
- "ergoTree" : "0008cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "assets" : [
- {
- "tokenId" : "8028007f7fb72f005b01eb000064ff004e0080e58b68ffb700007f8417360000",
- "amount" : 2
- },
- {
- "tokenId" : "1dee7f8701080a5a4e457f95ffe39e00eaea006a4c01018089607f83800001e8",
- "amount" : 2
- },
- {
- "tokenId" : "011b010900017f017f8001005d01f97fffa71700c400ff887f80f0a7b37f0080",
- "amount" : 2
- },
- {
- "tokenId" : "c7e300a94ca200e940ff7fb18eff28747f00dacfb87f5d007f7f8080440011fb",
- "amount" : 2
- },
- {
- "tokenId" : "cc7f56fff1fa7f017fff859b012effb080068056cb80e1017596b3cab14f6e59",
- "amount" : 2
- },
- {
- "tokenId" : "23c1801e2392018004f6807f00ca807fff3e01fc00d8e20100f6805f5a7facff",
- "amount" : 2
- },
- {
- "tokenId" : "d2ff907f1f807f0100b27f807f12bb7f00ff824e53c37380ff80ffc3fb010501",
- "amount" : 2
- },
- {
- "tokenId" : "ee7f3dec00008080fd00e56fae80748cd7ff36acf401803b00657ff57e2e0158",
- "amount" : 2
- },
- {
- "tokenId" : "7ff4019a0180017f7f8ba8808cff46664100d2807f30800165008438dc807f68",
- "amount" : 2
- },
- {
- "tokenId" : "53017c7c7001007f9a2cffdc7f011180ff7f6a010a7fff00ff27007f00ff80ff",
- "amount" : 2
- }
- ],
- "creationHeight" : 10,
- "additionalRegisters" : {
- "R4" : "0201",
- "R5" : "08cd02a73151bd3c8864d6cf9c81fa288df7940ea828dd6ccf96c8437805076c851fa0",
- "R6" : "0414",
- "R7" : "0e0a0a0a0a0a0a0a0a0a0a0a",
- "R8" : "0ece1f0202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202"
- },
- "transactionId" : "a9facd3e2a7c6a9253bbb6cfc5a535762d30f3459bedef04a46b8ea8de5e4ccb",
- "index" : 9
- }
- ]
- },
- "selfIndex" : 0,
- "extension" : {
-
- },
- "validationSettings" : "10e8070001e9070001ea070001eb070001ec070001ed070001ee070001ef070001f0070001f1070001f2070001f3070001f4070001f5070001f6070001f7070001",
- "costLimit" : 1000000,
- "initCost" : 0
- }
-}
\ No newline at end of file
diff --git a/ergo-core/src/test/resources/logback-test.xml b/ergo-core/src/test/resources/logback-test.xml
deleted file mode 100644
index f3a04e2b7b..0000000000
--- a/ergo-core/src/test/resources/logback-test.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
- System.out
-
- WARN
-
-
- [%thread] >> [%-5level] %logger{36} >> %d{HH:mm:ss.SSS} %msg%n
-
-
-
-
-
-
-
-
diff --git a/ergo-core/src/test/resources/settings.conf b/ergo-core/src/test/resources/settings.conf
deleted file mode 100644
index ad5b2ff500..0000000000
--- a/ergo-core/src/test/resources/settings.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "ergo": {
- "node": {
- "blocksToKeep": 13,
- "mempoolSorting": "bySize"
- }
- }
-}
\ No newline at end of file
diff --git a/ergo-core/src/test/resources/settings.json b/ergo-core/src/test/resources/settings.json
deleted file mode 100644
index f9d813aa9a..0000000000
--- a/ergo-core/src/test/resources/settings.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "ergo": {
- "node": {
- "blocksToKeep": 12,
- "mempoolSorting": "bySize"
- }
- }
-}
\ No newline at end of file
diff --git a/ergo-core/src/test/scala/org/ergoplatform/db/DBSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/db/DBSpec.scala
deleted file mode 100644
index f2617ee32a..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/db/DBSpec.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.ergoplatform.db
-
-import akka.util.ByteString
-import org.ergoplatform.settings.Algos
-import org.ergoplatform.wallet.utils.TestFileUtils
-import org.iq80.leveldb.{DB, Options}
-import scorex.db.LDBFactory.factory
-import scorex.db.{LDBKVStore, LDBVersionedStore}
-
-trait DBSpec extends TestFileUtils {
-
- implicit class ValueOps(x: Option[Array[Byte]]) {
- def toBs: Option[ByteString] = x.map(ByteString.apply)
- }
-
- implicit class KeyValueOps(xs: Seq[(Array[Byte], Array[Byte])]) {
- def toBs: Seq[(ByteString, ByteString)] = xs.map(x => ByteString(x._1) -> ByteString(x._2))
- }
-
- protected def byteString(s: String): Array[Byte] = s.getBytes("UTF-8")
-
- protected def byteString32(s: String): Array[Byte] = Algos.hash(byteString(s))
-
- protected def withDb(body: DB => Unit): Unit = {
- val options = new Options()
- options.createIfMissing(true)
- options.verifyChecksums(true)
- options.maxOpenFiles(2000)
- val db = factory.open(createTempDir, options)
- try body(db) finally db.close()
- }
-
- protected def versionId(s: String): Array[Byte] = byteString32(s)
-
- protected def withStore(body: LDBKVStore => Unit): Unit =
- withDb { db: DB => body(new LDBKVStore(db)) }
-
- protected def withVersionedStore(keepVersions: Int)(body: LDBVersionedStore => Unit): Unit = {
- val db = new LDBVersionedStore(createTempDir, keepVersions)
- try body(db) finally db.close()
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/db/KvStoreReaderSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/db/KvStoreReaderSpec.scala
deleted file mode 100644
index 9159876876..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/db/KvStoreReaderSpec.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.ergoplatform.db
-
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-
-class KvStoreReaderSpec extends AnyPropSpec with Matchers with DBSpec {
-
- property("getRange works properly") {
- withStore {store =>
- val keyStart = byteString("A")
- val keyEnd = byteString("Z")
- store.getRange(keyStart, keyEnd).length shouldBe 0
-
- store.insert(keyStart, keyStart).get
- store.getRange(keyStart, keyEnd).length shouldBe 1
-
- store.insert(keyEnd, keyEnd).get
- store.getRange(keyStart, keyEnd).length shouldBe 2
-
- // keys before the range
- store.getRange(byteString("a"), byteString("z")).length shouldBe 0
-
- // keys inside the range
- store.getRange(byteString("<"), byteString("z")).length shouldBe 2
-
- // keys after the range
- store.getRange(byteString("<"), byteString("?")).length shouldBe 0
-
- //removing keys
- store.remove(Array(keyStart, keyEnd)).get
- store.getRange(keyStart, keyEnd).length shouldBe 0
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/db/LDBKVStoreSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/db/LDBKVStoreSpec.scala
deleted file mode 100644
index cd32b21c29..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/db/LDBKVStoreSpec.scala
+++ /dev/null
@@ -1,64 +0,0 @@
-package org.ergoplatform.db
-
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-
-class LDBKVStoreSpec extends AnyPropSpec with Matchers with DBSpec {
-
- property("put/get/getAll/delete") {
- withStore { store =>
- val valueA = (byteString("A"), byteString("1"))
- val valueB = (byteString("B"), byteString("2"))
-
- store.update(Array(valueA._1, valueB._1), Array(valueA._2, valueB._2), toRemove = Array.empty).get
-
- store.get(valueA._1).toBs shouldBe Some(valueA._2).toBs
- store.get(valueB._1).toBs shouldBe Some(valueB._2).toBs
-
- store.getAll.toSeq.toBs shouldBe Seq(valueA, valueB).toBs
-
- store.update(Array.empty, Array.empty, toRemove = Array(valueA._1)).get
- store.get(valueA._1) shouldBe None
- }
- }
-
- property("record rewriting") {
- withStore { store =>
- val key = byteString("A")
- val valA = byteString("1")
- val valB = byteString("2")
-
- store.insert(key, valA).get
-
- store.get(key).toBs shouldBe Some(valA).toBs
-
- store.insert(key, valB).get
-
- store.get(key).toBs shouldBe Some(valB).toBs
-
- store.getAll.size shouldBe 1
- }
- }
-
- property("last key in range") {
- withStore { store =>
- val valueA = (byteString("A"), byteString("1"))
- val valueB = (byteString("B"), byteString("2"))
- val valueC = (byteString("C"), byteString("1"))
- val valueD = (byteString("D"), byteString("2"))
- val valueE = (byteString("E"), byteString("3"))
- val valueF = (byteString("F"), byteString("4"))
-
- val values = Array(valueA, valueB, valueC, valueD, valueE, valueF)
- store.insert(values.map(_._1), values.map(_._2)).get
-
- store.lastKeyInRange(valueA._1, valueC._1).get.toSeq shouldBe valueC._1.toSeq
- store.lastKeyInRange(valueD._1, valueF._1).get.toSeq shouldBe valueF._1.toSeq
- store.lastKeyInRange(valueF._1, byteString32("Z")).get.toSeq shouldBe valueF._1.toSeq
- store.lastKeyInRange(Array(10: Byte), valueA._1).get.toSeq shouldBe valueA._1.toSeq
-
- store.lastKeyInRange(Array(10: Byte), Array(11: Byte)).isDefined shouldBe false
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/db/VersionedStoreSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/db/VersionedStoreSpec.scala
deleted file mode 100644
index 59aa72d8b0..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/db/VersionedStoreSpec.scala
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.ergoplatform.db
-
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-
-class VersionedStoreSpec extends AnyPropSpec with Matchers with DBSpec {
-
- private val (keyA, valA) = (byteString("A"), byteString("1"))
- private val (keyB, valB) = (byteString("B"), byteString("2"))
- private val (keyC, valC) = (byteString("C"), byteString("3"))
- private val (keyD, valD) = (byteString("D"), byteString("4"))
- private val (keyE, valE) = (byteString("E"), byteString("5"))
-
- private val v1 = versionId("v1")
- private val v2 = versionId("v2")
- private val v3 = versionId("v3")
- private val v4 = versionId("v4")
-
- property("rollback (1 version back)") {
- withVersionedStore(10) { store =>
- store.insert(v1, Seq(keyA -> valA)).get
- store.insert(v2, Seq(keyB -> valB, keyC -> valC)).get
- store.update(v3, Seq(keyC), Seq(keyA -> byteString("6"), keyD -> valD)).get
-
- store.getAll.toSeq.toBs should contain allElementsOf Seq(
- keyA -> byteString("6"),
- keyB -> valB,
- keyD -> valD
- ).toBs
-
- store.rollbackTo(v2) shouldBe 'success
-
- store.getAll.toSeq.toBs should contain allElementsOf Seq(keyA -> valA, keyB -> valB, keyC -> valC).toBs
- store.get(keyD) shouldBe None
- store.get(keyA).get.sameElements(valA) shouldBe true
-
- store.lastVersionID shouldBe Some(v2)
- }
- }
-
- property("rollback (2 versions back)") {
- withVersionedStore(10) { store =>
- store.insert(v1, Seq(keyA -> valA)).get
- store.insert(v2, Seq(keyB -> valB, keyC -> valC)).get
- store.update(v3, Seq(keyC), Seq(keyA -> byteString("6"), keyD -> valD)).get
- store.update(v4, Seq(keyA), Seq(keyB -> byteString("7"), keyE -> valE)).get
-
- store.getAll.toSeq.toBs should contain allElementsOf Seq(keyB -> byteString("7"), keyE -> valE, keyD -> valD).toBs
- store.get(keyC) shouldBe None
- store.get(keyA) shouldBe None
-
- store.rollbackTo(v2) shouldBe 'success
-
- store.getAll.toSeq.toBs should contain allElementsOf Seq(keyA -> valA, keyB -> valB, keyC -> valC).toBs
- store.get(keyE) shouldBe None
- store.get(keyD) shouldBe None
- }
- }
-
- property("Outdated versions pruning") {
- withVersionedStore(2) { store =>
- store.insert(v1, Seq(keyA -> valA)).get
- store.insert(v2, Seq(keyB -> valB)).get
-
- store.versionIdExists(v1) shouldBe true
-
- store.insert(v3, Seq(keyC -> valC)).get
- store.insert(v4, Seq(keyA -> valA)).get
-
- store.versionIdExists(v4) shouldBe true
- store.versionIdExists(v3) shouldBe true
- store.versionIdExists(v2) shouldBe true
- store.versionIdExists(v1) shouldBe false
-
- store.get(keyA).isDefined shouldBe true
- store.get(keyB).isDefined shouldBe true
- store.get(keyC).isDefined shouldBe true
-
- store.rollbackTo(v1).isSuccess shouldBe false
-
- store.get(keyA).isDefined shouldBe true
- store.get(keyB).isDefined shouldBe true
- store.get(keyC).isDefined shouldBe true
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/examples/LiteClientExamples.scala b/ergo-core/src/test/scala/org/ergoplatform/examples/LiteClientExamples.scala
deleted file mode 100644
index d90cf00afc..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/examples/LiteClientExamples.scala
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.ergoplatform.examples
-
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.crypto.authds.merkle.MerkleProof
-import scorex.crypto.authds.{LeafData, Side}
-import scorex.crypto.hash.{Blake2b256, Digest32}
-import scorex.util.encode.Base16
-
-/**
- * This class contains how-to examples for building clients
- */
-class LiteClientExamples extends ErgoPropertyTest {
-
- /**
- * This code shows how to do a client checking a Merkle-tree based membership proof against an
- * incomplete header (so header without a proof-of-work solution). This could be useful for a
- * decentralized pool with collaterals, where the pool checks shares from miners, and a share
- * includes proof that a corresponding block contains a certain transaction (paying to the pool).
- *
- * For example, a working scheme for a decentralized pool could be as follows:
- * 1. A miner is creating a transaction which is paying to the pool
- * (posting of the tx by the pool outside the block should be impossible)
- * 2. The miner is creating block candidate with the tx included (via calling "mining/candidateWithTxs").
- * The result would be like the following:
- * {
- * "msg" : "6cb37d0a202bc2984f43de003cbc5558804db45798d0fc8faae7390b96d42d15",
- * "b" : 748014723576678314041035877227113663879264849498014394977645987,
- * "pk" : "0278011ec0cf5feb92d61adb51dcb75876627ace6fd9446ab4cabc5313ab7b39a7",
- * "proof" : {
- * "msgPreimage" : "01fb9e35f8a73c128b73e8fde5c108228060d68f11a69359ee0fb9bfd84e7ecde6d19957ccbbe75b075b3baf1cac6126b6e80b5770258f4cec29fbde92337faeec74c851610658a40f5ae74aa3a4babd5751bd827a6ccc1fe069468ef487cb90a8c452f6f90ab0b6c818f19b5d17befd85de199d533893a359eb25e7804c8b5d7514d784c8e0e52dabae6e89a9d6ed9c84388b228e7cdee09462488c636a87931d656eb8b40f82a507008ccacbee05000000",
- * "txProofs" : [{
- * "leaf" : "642c15c62553edd8fd9af9a6f754f3c7a6c03faacd0c9b9d5b7d11052c6c6fe8",
- * "levels" : [
- * "0139b79af823a92aa72ced2c6d9e7f7f4687de5b5af7fab0ad205d3e54bda3f3ae"
- * ]
- * }]
- * }
- * }
- * 3. The miner is mining the block using "msg", "b", "pk" as it happens now. If block is found, the miner is
- * posting the transaction to the network. However, if real difficulty of the solution is not enough to form a
- * block but enough for a share, then the miner can post the share to the pool. The share consists of "msg", "b",
- * "pk", solution and the "proof".
- *
- * 4. The pool checks that the share is valid. In particular, the pool checks that:
- * a) the "msgPreimage" (which is a header without a PoW solution) along with the PoW form a valid header
- * with enough difficulty
- * b) the header contains transaction by using "proof"
- *
- * The code below is about step 4b only.
- */
- property("Example client code for tx proof") {
- implicit val hashFn: Blake2b256.type = Blake2b256
-
- val msgPreimageBase16 = "01fb9e35f8a73c128b73e8fde5c108228060d68f11a69359ee0fb9bfd84e7ecde6d19957ccbbe75b075b3baf1cac6126b6e80b5770258f4cec29fbde92337faeec74c851610658a40f5ae74aa3a4babd5751bd827a6ccc1fe069468ef487cb90a8c452f6f90ab0b6c818f19b5d17befd85de199d533893a359eb25e7804c8b5d7514d784c8e0e52dabae6e89a9d6ed9c84388b228e7cdee09462488c636a87931d656eb8b40f82a507008ccacbee05000000"
- val msgPreimage = Base16.decode(msgPreimageBase16).get
-
- val msg = "6cb37d0a202bc2984f43de003cbc5558804db45798d0fc8faae7390b96d42d15"
-
- //hash of "msgPreimage" (which is a header without PoW) should be equal to "msg"
- Base16.encode(hashFn(msgPreimage)) == msg
-
- //Transactions Merkle tree digest is in bytes 65-96 (inclusive) of the unproven header
- val txsRoot = msgPreimage.slice(65, 97)
-
- //txId is a "leaf" in a Merkle proof
- val txId = "642c15c62553edd8fd9af9a6f754f3c7a6c03faacd0c9b9d5b7d11052c6c6fe8"
-
- // Merkle roof is constructed by given leaf data, leaf hash sibling and also siblings for parent nodes. Using this
- // data, it is possible to compute nodes on the path to root hash, and the hash itself. The picture of a proof
- // given below. In the picture, "^^" is leaf data(to compute leaf hash from), "=" values are to be computed,
- // "*" values are to be stored.
- //
- // ........= Root
- // ..... / \
- // .... * =
- // ....... / \
- // ...... * =
- // ......... /.\
- // .........* =
- // ............ ^^
- //
- // Merkle proof element is encoded in the following way:
- // - first, 1 byte showing whether COMPUTED value is on the right (1) or on the left (0)
- // - second, 32 bytes of stored value
-
- // To check the proof, first, hash of the leaf should be computed with the 1-byte zero prefix
- // (i.e. blake2b256(0 ++ leaf). Then, for each level, if the first byte is "right" (1) then
- // computed hash for the next level is blake2b256(1 ++ COMPUTED ++ stored hash (last 32 bytes of the level),
- // where COMPUTED is the value computed on the previous step (and "1" is internal node prefix).
- // A value computed on the last step is to be compared with expected root hash value.
-
- val levelsEncoded = Seq("0139b79af823a92aa72ced2c6d9e7f7f4687de5b5af7fab0ad205d3e54bda3f3ae")
-
- val levels = levelsEncoded.map { le =>
- val leBytes = Base16.decode(le).get
- val side: Byte = leBytes.head
- val digest = leBytes.tail
- (Digest32 @@ digest, Side @@ side)
- }
-
- val merkleProof = MerkleProof[Digest32](LeafData @@ Base16.decode(txId).get, levels)
-
- merkleProof.valid(Digest32 @@ txsRoot) shouldBe true
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/BlocksApiRouteSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/BlocksApiRouteSpec.scala
deleted file mode 100644
index 7edef059f5..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/BlocksApiRouteSpec.scala
+++ /dev/null
@@ -1,137 +0,0 @@
-package org.ergoplatform.http.routes
-
-import akka.http.scaladsl.model.{ContentTypes, HttpEntity, StatusCodes, UniversalEntity}
-import akka.http.scaladsl.server.Route
-import akka.http.scaladsl.testkit.ScalatestRouteTest
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.Json
-import io.circe.syntax._
-import org.ergoplatform.http.api.BlocksApiRoute
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.settings.Algos
-import org.ergoplatform.utils.Stubs
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-import scorex.util.ModifierId
-
-class BlocksApiRouteSpec
- extends AnyFlatSpec
- with Matchers
- with ScalatestRouteTest
- with FailFastCirceSupport
- with Stubs {
-
- val prefix = "/blocks"
-
- val route: Route = BlocksApiRoute(nodeViewRef, digestReadersRef, settings).route
-
- val headerIdBytes: ModifierId = history.lastHeaders(1).headers.head.id
- val headerIdString: String = Algos.encode(headerIdBytes)
-
- it should "get last blocks" in {
- Get(prefix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- history
- .headerIdsAt(0, 50)
- .map(Algos.encode)
- .asJson shouldEqual responseAs[Json]
- }
- }
-
- it should "post block correctly" in {
- val (st, bh) = createUtxoState(settings)
- val block: ErgoFullBlock = validFullBlock(parentOpt = None, st, bh)
- val blockJson: UniversalEntity =
- HttpEntity(block.asJson.toString).withContentType(ContentTypes.`application/json`)
- Post(prefix, blockJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- }
- }
-
- it should "get last headers" in {
- Get(prefix + "/lastHeaders/1") ~> route ~> check {
- status shouldBe StatusCodes.OK
- history
- .lastHeaders(1)
- .headers
- .map(_.asJson)
- .asJson shouldEqual responseAs[Json]
- }
- }
-
- it should "get block at height" in {
- Get(prefix + "/at/0") ~> route ~> check {
- status shouldBe StatusCodes.OK
- history
- .headerIdsAtHeight(0)
- .map(Algos.encode)
- .asJson shouldEqual responseAs[Json]
- }
- }
-
- it should "get chain slice" in {
- Get(prefix + "/chainSlice?fromHeight=0") ~> route ~> check {
- status shouldBe StatusCodes.OK
- chain.map(_.header).asJson shouldEqual responseAs[Json]
- }
- Get(prefix + "/chainSlice?fromHeight=2&toHeight=4") ~> route ~> check {
- status shouldBe StatusCodes.OK
- chain.slice(2, 4).map(_.header).asJson shouldEqual responseAs[Json]
- }
- }
-
- it should "get block by header id" in {
- Get(prefix + "/" + headerIdString) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val expected = history
- .typedModifierById[Header](headerIdBytes)
- .flatMap(history.getFullBlock)
- .map(_.asJson)
- .get
-
- responseAs[Json] shouldEqual expected
- }
- }
-
- it should "get blocks by header ids" in {
- val headerIdsBytes = history.lastHeaders(10).headers
- val headerIdsString: Seq[String] = headerIdsBytes.map(h => Algos.encode(h.id))
-
- Post(prefix + "/headerIds", headerIdsString.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
-
- val expected = headerIdsBytes
- .map(_.id)
- .flatMap(headerId =>
- history.typedModifierById[Header](headerId).flatMap(history.getFullBlock)
- )
-
- responseAs[Seq[ErgoFullBlock]] shouldEqual expected
- }
- }
-
- it should "get header by header id" in {
- Get(prefix + "/" + headerIdString + "/header") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val expected = history
- .typedModifierById[Header](headerIdBytes)
- .flatMap(history.getFullBlock)
- .map(_.header.asJson)
- .get
-
- responseAs[Json] shouldEqual expected
- }
- }
-
- it should "get transactions by header id" in {
- Get(prefix + "/" + headerIdString + "/transactions") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val header = history.typedModifierById[Header](headerIdBytes).value
- val fullBlock = history.getFullBlock(header).value
- val expected = fullBlock.blockTransactions.asJson
- responseAs[Json] shouldEqual expected
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/EmissionApiRouteSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/EmissionApiRouteSpec.scala
deleted file mode 100644
index 7d89b239a5..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/EmissionApiRouteSpec.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.ergoplatform.http.routes
-
-import akka.http.scaladsl.model.StatusCodes
-import akka.http.scaladsl.server.Route
-import akka.http.scaladsl.testkit.{RouteTestTimeout, ScalatestRouteTest}
-import akka.testkit.TestDuration
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.Json
-import io.circe.syntax._
-import org.ergoplatform.http.api.EmissionApiRoute
-import org.ergoplatform.mining.emission.EmissionRules
-import org.ergoplatform.settings.{ErgoSettings, ReemissionSettings}
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-import scala.concurrent.duration._
-
-class EmissionApiRouteSpec extends AnyFlatSpec
- with Matchers
- with ScalatestRouteTest
- with FailFastCirceSupport {
-
- val prefix = "/emission/at"
-
- implicit val timeout: RouteTestTimeout = RouteTestTimeout(15.seconds.dilated)
-
- val ergoSettings: ErgoSettings = ErgoSettings.read()
- val coinEmission: EmissionRules = ergoSettings.chainSettings.emissionRules
-
- val reemissionSettings: ReemissionSettings = ergoSettings.chainSettings.reemission
-
- val route: Route = EmissionApiRoute(ergoSettings).route
-
- it should "get correct emission values" in {
- Get(prefix + "/1") ~> route ~> check {
- status shouldBe StatusCodes.OK
- EmissionApiRoute.emissionInfoAtHeight(1, coinEmission, reemissionSettings).asJson shouldEqual responseAs[Json]
- }
-
- Get(prefix + "/10000") ~> route ~> check {
- status shouldBe StatusCodes.OK
- EmissionApiRoute.emissionInfoAtHeight(10000, coinEmission, reemissionSettings).asJson shouldEqual responseAs[Json]
- }
-
- Get(prefix + "/1000000") ~> route ~> check {
- status shouldBe StatusCodes.OK
- EmissionApiRoute.emissionInfoAtHeight(1000000, coinEmission, reemissionSettings).asJson shouldEqual responseAs[Json]
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/ErgoPeersApiRouteSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/ErgoPeersApiRouteSpec.scala
deleted file mode 100644
index de1a6edc5d..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/ErgoPeersApiRouteSpec.scala
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.ergoplatform.http.routes
-
-import akka.actor.Actor
-import akka.http.scaladsl.model.StatusCodes
-import akka.http.scaladsl.server.Route
-import akka.http.scaladsl.testkit.{RouteTestTimeout, ScalatestRouteTest}
-import akka.testkit.{TestDuration, TestProbe}
-import akka.util.Timeout
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.Json
-import org.ergoplatform.http.api.ErgoPeersApiRoute
-import org.ergoplatform.utils.Stubs
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-import scorex.core.network.NetworkController.ReceivableMessages.GetConnectedPeers
-import scorex.core.network.peer.PeerManager.ReceivableMessages.GetAllPeers
-import scorex.core.settings.RESTApiSettings
-
-import java.net.InetSocketAddress
-import scala.concurrent.Future
-import scala.concurrent.duration._
-
-class ErgoPeersApiRouteSpec extends AnyFlatSpec
- with Matchers
- with ScalatestRouteTest
- with FailFastCirceSupport
- with ScalaCheckPropertyChecks
- with Stubs {
-
- implicit val actorTimeout: Timeout = Timeout(15.seconds.dilated)
- implicit val routeTimeout: RouteTestTimeout = RouteTestTimeout(15.seconds.dilated)
-
- val restApiSettings = RESTApiSettings(new InetSocketAddress("localhost", 8080), None, None, 10.seconds, None)
- val peerManagerProbe = TestProbe()
-
- it should "return all peers" in {
- forAll(connectedPeerGen(Actor.noSender)) { peer =>
- val networkControllerProbe = TestProbe()
- val route: Route = ErgoPeersApiRoute(peerManagerProbe.ref, networkControllerProbe.ref, null, null, restApiSettings).route
- Future {
- peerManagerProbe.expectMsg(GetAllPeers)
- peerManagerProbe.reply(Map(peer.connectionId.remoteAddress -> peer.peerInfo.get))
- }
-
- Get("/peers/all") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received connected peers: $json")
- val c = json.asArray.get.head.hcursor
- c.downField("address").as[String] shouldEqual Right(peer.connectionId.remoteAddress.toString)
- peer.peerInfo.get.peerSpec.publicUrlOpt.foreach { restApiUrl =>
- c.downField("restApiUrl").as[String] shouldEqual Right(restApiUrl.toString)
- }
- c.downField("lastMessage").as[Long] shouldEqual Right(0L)
- c.downField("lastHandshake").as[Long] shouldEqual Right(0L)
- c.downField("name").as[String] shouldEqual Right(peer.peerInfo.get.peerSpec.nodeName)
- c.downField("connectionType").as[String] shouldEqual Right("Incoming")
- }
- }
- }
-
- it should "return connected peers" in {
- forAll(connectedPeerGen(Actor.noSender)) { peer =>
- val networkControllerProbe = TestProbe()
- val route: Route = ErgoPeersApiRoute(peerManagerProbe.ref, networkControllerProbe.ref, null, null, restApiSettings).route
- Future {
- networkControllerProbe.expectMsg(GetConnectedPeers)
- networkControllerProbe.reply(Seq(peer))
- }
-
- Get("/peers/connected") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received connected peers: $json")
- val c = json.asArray.get.head.hcursor
- peer.peerInfo.get.peerSpec.address.foreach { address =>
- c.downField("address").as[String] shouldEqual Right(address.toString)
- }
- peer.peerInfo.get.peerSpec.publicUrlOpt.foreach { restApiUrl =>
- c.downField("restApiUrl").as[String] shouldEqual Right(restApiUrl.toString)
- }
- c.downField("lastMessage").as[Long] shouldEqual Right(0L)
- c.downField("lastHandshake").as[Long] shouldEqual Right(0L)
- c.downField("name").as[String] shouldEqual Right(peer.peerInfo.get.peerSpec.nodeName)
- c.downField("connectionType").as[String] shouldEqual Right("Incoming")
- }
- }
- }
-}
-
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/InfoApiRoutesSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/InfoApiRoutesSpec.scala
deleted file mode 100644
index 706ff37ddd..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/InfoApiRoutesSpec.scala
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.ergoplatform.http.routes
-
-import akka.actor.ActorRef
-import akka.http.scaladsl.model.StatusCodes
-import akka.http.scaladsl.server.Route
-import akka.http.scaladsl.testkit.{RouteTestTimeout, ScalatestRouteTest}
-import akka.pattern.ask
-import akka.testkit.TestDuration
-import akka.util.Timeout
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.Json
-import org.ergoplatform.Version
-import org.ergoplatform.http.api.InfoApiRoute
-import org.ergoplatform.local.ErgoStatsCollector.NodeInfo.difficultyEncoder
-import org.ergoplatform.local.ErgoStatsCollector.{GetNodeInfo, NodeInfo}
-import org.ergoplatform.local.ErgoStatsCollectorRef
-import org.ergoplatform.mining.difficulty.DifficultySerializer
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.ChangedHistory
-import org.ergoplatform.nodeView.history.ErgoHistory.Difficulty
-import org.ergoplatform.utils.Stubs
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-import scala.concurrent.duration._
-import scala.concurrent.{Await, Future}
-
-class InfoApiRoutesSpec extends AnyFlatSpec
- with Matchers
- with ScalatestRouteTest
- with FailFastCirceSupport
- with Stubs {
-
- implicit val actorTimeout: Timeout = Timeout(15.seconds.dilated)
- implicit val routeTimeout: RouteTestTimeout = RouteTestTimeout(15.seconds.dilated)
- val statsCollector: ActorRef = ErgoStatsCollectorRef(nodeViewRef, networkControllerRef, null, settings)
- val route: Route = InfoApiRoute(statsCollector, settings.scorexSettings.restApi).route
- val requiredDifficulty = BigInt(1)
-
- override def beforeAll: Unit = {
- Await.ready(initDifficulty(requiredDifficulty), actorTimeout.duration)
- }
-
- it should "return info" in {
- Get("/info") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received node info: $json")
- val c = json.hcursor
- c.downField("name").as[String] shouldEqual Right(settings.scorexSettings.network.nodeName)
- c.downField("appVersion").as[String] shouldEqual Right(Version.VersionString)
- c.downField("stateType").as[String] shouldEqual Right(settings.nodeSettings.stateType.stateTypeName)
- c.downField("isMining").as[Boolean] shouldEqual Right(settings.nodeSettings.mining)
- (System.currentTimeMillis() - c.downField("launchTime").as[Long].toOption.getOrElse(0L)) < 2000 shouldBe true
- c.downField("eip27Supported").as[Boolean] shouldEqual Right(true)
- c.downField("restApiUrl").as[String] shouldEqual Right("https://example.com:80")
- }
- }
-
- it should "should return non-exponential difficulty in json response" in {
- Get("/info") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- val res = json.toString
- log.info(s"Received node info: $res")
- res should include regex """\"difficulty\" : \d+,"""
- }
- }
-
- "difficulty" should "be encoded with non-exponential form " in {
- val res = difficultyEncoder(requiredDifficulty)
- res.toString shouldEqual requiredDifficulty.toString
- }
-
- private def initDifficulty(difficulty: Difficulty): Future[Option[Difficulty]] = {
- val emptyHistory = generateHistory(
- verifyTransactions = settings.nodeSettings.verifyTransactions,
- stateType = settings.nodeSettings.stateType,
- poPoWBootstrap = settings.nodeSettings.nipopowSettings.nipopowBootstrap,
- blocksToKeep = settings.nodeSettings.blocksToKeep
- )
- val nBits = DifficultySerializer.encodeCompactBits(difficulty)
- val chain = genChain(height = 5, emptyHistory, Header.InitialVersion, nBits)
- val history = applyChain(emptyHistory, chain)
- val generatedDifficulty = history.bestFullBlockOpt
- .map(_.header.requiredDifficulty)
- .map(difficultyEncoder.apply)
- log.info(s"Generated difficulty: $generatedDifficulty")
- statsCollector ! ChangedHistory(history)
- (statsCollector ? GetNodeInfo).mapTo[NodeInfo].map { nodeInfo =>
- val difficulty = nodeInfo.bestFullBlockOpt.map(_.header.requiredDifficulty)
- log.info(s"Set difficulty to: $difficulty")
- difficulty
- }
- }
-
-}
-
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/MiningApiRouteSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/MiningApiRouteSpec.scala
deleted file mode 100644
index dee8e45a3f..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/MiningApiRouteSpec.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.ergoplatform.http.routes
-
-import akka.http.scaladsl.model.StatusCodes
-import akka.http.scaladsl.server.Route
-import akka.http.scaladsl.testkit.ScalatestRouteTest
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.Json
-import io.circe.syntax._
-import org.ergoplatform.http.api.MiningApiRoute
-import org.ergoplatform.mining.AutolykosSolution
-import org.ergoplatform.settings.ErgoSettings
-import org.ergoplatform.utils.Stubs
-import org.ergoplatform.utils.generators.ErgoGenerators
-import org.ergoplatform.{ErgoTreePredef, Pay2SAddress}
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-import scala.util.Try
-
-class MiningApiRouteSpec
- extends AnyFlatSpec
- with ErgoGenerators
- with Matchers
- with ScalatestRouteTest
- with Stubs
- with FailFastCirceSupport {
-
- val prefix = "/mining"
-
- val localSetting: ErgoSettings = settings.copy(nodeSettings = settings.nodeSettings.copy(useExternalMiner = true))
- val route: Route = MiningApiRoute(minerRef, localSetting).route
-
- val solution = AutolykosSolution(genECPoint.sample.get, genECPoint.sample.get, Array.fill(32)(9: Byte), BigInt(0))
-
- it should "return requested candidate" in {
- Get(prefix + "/candidate") ~> route ~> check {
- status shouldBe StatusCodes.OK
- Try(responseAs[Json]) shouldBe 'success
- }
- }
-
- it should "process external solution" in {
- Post(prefix + "/solution", solution.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- }
- }
-
- it should "display miner pk" in {
- Get(prefix + "/rewardAddress") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val script = ErgoTreePredef.rewardOutputScript(settings.chainSettings.monetary.minerRewardDelay, pk)
- val addressStr = Pay2SAddress(script)(settings.addressEncoder).toString()
- responseAs[Json].hcursor.downField("rewardAddress").as[String] shouldEqual Right(addressStr)
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/NipopowApiRoutesSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/NipopowApiRoutesSpec.scala
deleted file mode 100644
index 2d62e20a12..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/NipopowApiRoutesSpec.scala
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.ergoplatform.http.routes
-
-import akka.http.scaladsl.model.StatusCodes
-import akka.http.scaladsl.server.{Route, ValidationRejection}
-import akka.http.scaladsl.testkit.ScalatestRouteTest
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.Json
-import org.ergoplatform.http.api.NipopowApiRoute
-import org.ergoplatform.utils.Stubs
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class NipopowApiRoutesSpec extends AnyFlatSpec
- with Matchers
- with ScalatestRouteTest
- with FailFastCirceSupport
- with Stubs {
-
- private val route: Route = NipopowApiRoute(nodeViewRef, utxoReadersRef, settings).route
-
- it should "return proof for min superchain & suffix length" in {
- Get("/nipopow/proof/1/1") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received nipopow proof response : $json")
- val c = json.hcursor
- c.downField("prefix").as[List[Json]].right.get shouldNot be(empty)
- }
- }
-
- it should "proof request with invalid minimum and suffix length" in {
- Get("/nipopow/proof/12/24") ~> route ~> check {
- status shouldBe StatusCodes.BadRequest
- }
- }
-
- it should "proof request with missing headerId" in {
- Get("/nipopow/proof/1/1/05bf63aa1ecfc9f4e3fadc993f87b33edb4d58e151c1891816d734dd5a0e2e09") ~> route ~> check {
- status shouldBe StatusCodes.BadRequest
- }
- }
-
- it should "proof request with invalid headerId" in {
- Get("/nipopow/proof/1/1/x") ~> route ~> check {
- rejection shouldEqual ValidationRejection("Wrong modifierId format", None)
- }
- }
-
- it should "return proof for min superchain & suffix length & header id" in {
- val existingHeaderId = history.bestHeaderOpt.get.id
- Get(s"/nipopow/proof/1/1/$existingHeaderId") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received nipopow proof response : $json")
- val c = json.hcursor
- c.downField("prefix").as[List[Json]].right.get shouldNot be(empty)
- }
- }
-
- it should "get popow header by id" in {
- val existingHeaderId = history.bestHeaderOpt.get.id
- Get(s"/nipopow/popowHeaderById/$existingHeaderId") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received popow header response : $json")
- val c = json.hcursor
- c.downField("interlinks").as[List[Json]].right.get shouldNot be(empty)
- }
- }
-
- it should "get popow header by height" in {
- Get(s"/nipopow/popowHeaderByHeight/2") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received popow header response : $json")
- val c = json.hcursor
- c.downField("interlinks").as[List[Json]].right.get shouldNot be(empty)
- }
- }
-
-}
-
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala
deleted file mode 100644
index fb4956190f..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala
+++ /dev/null
@@ -1,275 +0,0 @@
-package org.ergoplatform.http.routes
-
-import akka.http.scaladsl.model.StatusCodes
-import akka.http.scaladsl.server.{Route, ValidationRejection}
-import akka.http.scaladsl.testkit.{RouteTestTimeout, ScalatestRouteTest}
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.Json
-import io.circe.syntax._
-import org.ergoplatform.ErgoBox
-import org.ergoplatform.http.api.ScanEntities.{ScanIdBoxId, ScanIdWrapper}
-import org.ergoplatform.http.api.{ApiCodecs, ScanApiRoute}
-import org.ergoplatform.nodeView.wallet.scanning._
-import org.ergoplatform.settings.{Args, ErgoSettings}
-import org.ergoplatform.utils.Stubs
-import org.ergoplatform.wallet.Constants.ScanId
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-import scorex.crypto.authds.ADKey
-import scorex.utils.Random
-import sigmastate.Values.ByteArrayConstant
-
-import scala.concurrent.duration._
-import scala.util.Try
-
-class ScanApiRouteSpec extends AnyFlatSpec
- with Matchers
- with ScalatestRouteTest
- with Stubs
- with FailFastCirceSupport
- with ApiCodecs {
-
- import ScanJsonCodecs.{scanDecoder, scanReqEncoder}
- import ScanIdWrapper.{scanIdWrapperEncoder, scanIdWrapperDecoder}
-
- implicit val timeout: RouteTestTimeout = RouteTestTimeout(145.seconds)
-
- val prefix = "/scan"
-
- val ergoSettings: ErgoSettings = ErgoSettings.read(
- Args(userConfigPathOpt = Some("src/test/resources/application.conf"), networkTypeOpt = None))
- val route: Route = ScanApiRoute(utxoReadersRef, ergoSettings).route
-
- private val predicate0 = ContainsScanningPredicate(ErgoBox.R4, ByteArrayConstant(Array(0: Byte, 1: Byte)))
- private val predicate1 = ContainsScanningPredicate(ErgoBox.R4, ByteArrayConstant(Array(1: Byte, 1: Byte)))
-
- val appRequest = ScanRequest("demo", predicate0, Some(ScanWalletInteraction.Off), Some(false))
- val appRequest2 = ScanRequest("demo2", predicate1, Some(ScanWalletInteraction.Off), None)
-
- it should "register a scan" in {
- Post(prefix + "/register", appRequest.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- Try(responseAs[ScanIdWrapper]) shouldBe 'success
- }
- }
-
- it should "deregister a scan" in {
- var scanId: ScanIdWrapper = ScanIdWrapper(ScanId @@ (-1000: Short)) // improper value
-
- // first, register an app
- Post(prefix + "/register", appRequest.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = Try(responseAs[ScanIdWrapper])
- response shouldBe 'success
- scanId = response.get
- }
-
- // then remove it
- Post(prefix + "/deregister", scanId.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- Try(responseAs[ScanIdWrapper]) shouldBe 'success
- }
-
- // second time it should be not successful
- Post(prefix + "/deregister", scanId.asJson) ~> route ~> check {
- status shouldBe StatusCodes.BadRequest
- }
- }
-
- it should "list registered scans" in {
- // register two apps
- Post(prefix + "/register", appRequest.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = Try(responseAs[ScanIdWrapper])
- response shouldBe 'success
- }
-
- Post(prefix + "/register", appRequest2.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = Try(responseAs[ScanIdWrapper])
- response shouldBe 'success
- }
-
- Get(prefix + "/listAll") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = Try(responseAs[Seq[Scan]])
- response shouldBe 'success
- val apps = response.get
-
- apps.map(_.scanName).contains(appRequest.scanName) shouldBe true
- apps.map(_.scanName).contains(appRequest2.scanName) shouldBe true
- }
- }
-
- it should "list unspent boxes for a scan with lower constraint" in {
- val minConfirmations = 15
- val minInclusionHeight = 20
-
- val suffix = s"/unspentBoxes/101?minConfirmations=$minConfirmations&minInclusionHeight=$minInclusionHeight"
-
- Get(prefix + suffix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = Try(responseAs[List[Json]])
- response shouldBe 'success
- response.get.nonEmpty shouldBe true // there are boxes that has confirmations > 15 and inclusionHeight > 20
- response.get.foreach { json =>
- json.hcursor.downField("confirmationsNum").as[Int].forall(_ >= minConfirmations) shouldBe true
- json.hcursor.downField("inclusionHeight").as[Int].forall(_ >= minInclusionHeight) shouldBe true
- }
-
- // unconfirmed box not returned
- response.get.flatMap(_.hcursor.downField("confirmationsNum").as[Option[Int]].toOption)
- .exists(_.isDefined == false) shouldBe false
- }
- }
-
-
- it should "list unspent boxes for a scan with upper constraint" in {
- val maxConfirmations = 15
- val maxInclusionHeight = 20
-
- val suffix = s"/unspentBoxes/101?maxConfirmations=$maxConfirmations&maxInclusionHeight=$maxInclusionHeight"
-
- Get(prefix + suffix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = Try(responseAs[List[Json]])
- response shouldBe 'success
- response.get.nonEmpty shouldBe true // there are boxes that has confirmations < 15 and inclusionHeight < 20
- response.get.foreach { json =>
- json.hcursor.downField("confirmationsNum").as[Int].forall(_ <= maxConfirmations) shouldBe true
- json.hcursor.downField("inclusionHeight").as[Int].forall(_ <= maxInclusionHeight) shouldBe true
- }
- // unconfirmed box not returned
- response.get.flatMap(_.hcursor.downField("confirmationsNum").as[Option[Int]].toOption)
- .exists(_.isDefined == false) shouldBe false
- }
- }
-
-
- it should "list unspent boxes for a scan with upper and lower constraints" in {
- val confirmations = 15
- val inclusionHeight = 20
-
- val suffix = s"/unspentBoxes/101?minConfirmations=$confirmations&minInclusionHeight=$inclusionHeight&maxConfirmations=$confirmations&maxInclusionHeight=$inclusionHeight"
-
- Get(prefix + suffix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = Try(responseAs[List[Json]])
- response shouldBe 'success
- response.get.nonEmpty shouldBe false // there are no boxes with confirmations and inclusionHeight within range
- }
- }
-
- it should "list unspent and unconfirmed boxes for a scan with lower constraint" in {
- val minConfirmations = -1
- val minInclusionHeight = 0
-
- val suffix = s"/unspentBoxes/101?minConfirmations=$minConfirmations&minInclusionHeight=$minInclusionHeight"
-
- Get(prefix + suffix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = Try(responseAs[List[Json]])
- response shouldBe 'success
- response.get.nonEmpty shouldBe true
-
- // unconfirmed box returned
- response.get.flatMap(_.hcursor.downField("confirmationsNum").as[Option[Int]].toOption)
- .exists(_.isDefined == false) shouldBe true
- }
- }
-
- it should "list spent boxes for a scan with lower constraint" in {
- val minConfirmations = 15
- val minInclusionHeight = 20
-
- val suffix = s"/spentBoxes/101?minConfirmations=$minConfirmations&minInclusionHeight=$minInclusionHeight"
-
- Get(prefix + suffix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = Try(responseAs[List[Json]])
- response shouldBe 'success
- response.get.nonEmpty shouldBe true
- response.get.foreach { json =>
- json.hcursor.downField("inclusionHeight").as[Int].forall(_ >= minInclusionHeight) shouldBe true
- }
- response.get.foreach { json =>
- json.hcursor.downField("spent").as[Boolean].forall(_ == true) shouldBe true
- }
-
- // unconfirmed box not returned
- response.get.flatMap(_.hcursor.downField("confirmationsNum").as[Option[Int]].toOption)
- .exists(_.isDefined == false) shouldBe false
- }
- }
-
- it should "list spent boxes for a scan with upper constraint" in {
- val maxConfirmations = 15
- val maxInclusionHeight = 20
-
- val suffix = s"/spentBoxes/101?maxConfirmations=$maxConfirmations&maxInclusionHeight=$maxInclusionHeight"
-
- Get(prefix + suffix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = Try(responseAs[List[Json]])
- response shouldBe 'success
- response.get.nonEmpty shouldBe true
- response.get.foreach { json =>
- json.hcursor.downField("confirmationsNum").as[Int].forall(_ <= maxConfirmations) shouldBe true
- json.hcursor.downField("inclusionHeight").as[Int].forall(_ <= maxInclusionHeight) shouldBe true
- }
- response.get.foreach { json =>
- json.hcursor.downField("spent").as[Boolean].forall(_ == true) shouldBe true
- }
-
- // unconfirmed box not returned
- response.get.flatMap(_.hcursor.downField("confirmationsNum").as[Option[Int]].toOption)
- .exists(_.isDefined == false) shouldBe false
- }
- }
-
- it should "list spent boxes boxes for a scan with upper and lower constraints" in {
- val confirmations = 15
- val inclusionHeight = 20
-
- val suffix = s"/spentBoxes/101?minConfirmations=$confirmations&minInclusionHeight=$inclusionHeight&maxConfirmations=$confirmations&maxInclusionHeight=$inclusionHeight"
-
- Get(prefix + suffix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = Try(responseAs[List[Json]])
- response shouldBe 'success
- response.get.nonEmpty shouldBe false // there are no spent boxes with confirmations and inclusionHeight within range
- }
- }
-
- it should "fail when maxInclusionHeight is specified and we consider unconfirmed" in {
- val minConfirmations = -1
- val maxInclusionHeight = 50
-
- val suffix = s"/unspentBoxes/101?minConfirmations=$minConfirmations&maxInclusionHeight=$maxInclusionHeight"
-
- Get(prefix + suffix) ~> route ~> check {
- rejection shouldEqual ValidationRejection("maxInclusionHeight cannot be specified when we consider unconfirmed")
- }
- }
-
- it should "stop tracking a box" in {
- val scanIdBoxId = ScanIdBoxId(ScanId @@ (51: Short), ADKey @@ Random.randomBytes(32))
-
- Post(prefix + "/stopTracking", scanIdBoxId.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- }
- }
-
- it should "generate scan for p2s rule" in {
- Post(prefix + "/p2sRule", "Ms7smJmdbakqfwNo") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val res = responseAs[Json]
- res.hcursor.downField("scanId").as[Int].toOption.isDefined shouldBe true
- }
-
- Post(prefix + "/p2sRule", "s7smJmdbakqfwNo") ~> route ~> check {
- status shouldBe StatusCodes.BadRequest
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala
deleted file mode 100644
index acd2fd8de5..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala
+++ /dev/null
@@ -1,150 +0,0 @@
-package org.ergoplatform.http.routes
-
-import akka.http.scaladsl.model.StatusCodes
-import akka.http.scaladsl.server.Route
-import akka.http.scaladsl.testkit.ScalatestRouteTest
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.Json
-import org.ergoplatform.{Pay2SAddress, Pay2SHAddress}
-import org.ergoplatform.settings.{Args, ErgoSettings}
-import org.ergoplatform.utils.Stubs
-import io.circe.syntax._
-import org.ergoplatform.http.api.ScriptApiRoute
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-import scorex.util.encode.Base16
-import sigmastate.SByte
-import sigmastate.Values.{CollectionConstant, ErgoTree, TrueLeaf}
-import sigmastate.serialization.{ErgoTreeSerializer, ValueSerializer}
-
-
-class ScriptApiRouteSpec extends AnyFlatSpec
- with Matchers
- with ScalatestRouteTest
- with Stubs
- with FailFastCirceSupport {
-
- val prefix = "/script"
-
- val ergoSettings: ErgoSettings = ErgoSettings.read(
- Args(userConfigPathOpt = Some("src/test/resources/application.conf"), networkTypeOpt = None))
- val route: Route = ScriptApiRoute(digestReadersRef, settings).route
-
- val scriptSource: String =
- """
- |{
- | val myPk = PK("3WwUerNahQR1YXyq8AKi5UkKsYeJ99zxrqNqt3BCG4xSGeTERHiQ")
- | HEIGHT < 9197 && myPk.isProven
- |}
- |""".stripMargin
-
- val scriptSourceSigProp: String =
- """
- |{
- | PK("3WwUerNahQR1YXyq8AKi5UkKsYeJ99zxrqNqt3BCG4xSGeTERHiQ")
- |}
- |""".stripMargin
-
- it should "execute script with context" in {
- val suffix = "/executeWithContext"
- val stream = ClassLoader.getSystemClassLoader.getResourceAsStream("execute-script.json")
- val req = scala.io.Source.fromInputStream(stream).getLines().mkString("\n")
- val assertion = (json: Json) => {
- status shouldBe StatusCodes.OK
- val value = json.hcursor.downField("value").downField("op").as[Int].right.get
- val condition = json.hcursor.downField("value").downField("condition").as[Boolean].right.get
- val cost = json.hcursor.downField("cost").as[Int].right.get
- value shouldEqual -45
- condition shouldEqual true
- cost shouldEqual 6
- }
- val json = io.circe.parser.parse(req)
- Post(prefix + suffix, json) ~> route ~> check(assertion(responseAs[Json]))
- }
-
- it should "generate valid P2SAddress form source" in {
- val suffix = "/p2sAddress"
- val assertion = (json: Json) => {
- status shouldBe StatusCodes.OK
- val addressStr = json.hcursor.downField("address").as[String].right.get
- addressEncoder.fromString(addressStr).get.addressTypePrefix shouldEqual Pay2SAddress.addressTypePrefix
- }
- Post(prefix + suffix, Json.obj("source" -> scriptSource.asJson)) ~> route ~> check(assertion(responseAs[Json]))
- Post(prefix + suffix, Json.obj("source" -> scriptSourceSigProp.asJson)) ~> route ~>
- check(assertion(responseAs[Json]))
- }
-
- it should "generate valid P2SHAddress form source" in {
- val suffix = "/p2shAddress"
- val assertion = (json: Json) => {
- status shouldBe StatusCodes.OK
- val addressStr = json.hcursor.downField("address").as[String].right.get
- addressEncoder.fromString(addressStr).get.addressTypePrefix shouldEqual Pay2SHAddress.addressTypePrefix
- }
- Post(prefix + suffix, Json.obj("source" -> scriptSource.asJson)) ~> route ~> check(assertion(responseAs[Json]))
- Post(prefix + suffix, Json.obj("source" -> scriptSourceSigProp.asJson)) ~> route ~>
- check(assertion(responseAs[Json]))
- }
-
- it should "get through address <-> ergoTree round-trip" in {
- val suffix = "addressToTree"
-
- val assertion = (json: Json, address: String) => {
- status shouldBe StatusCodes.OK
- val treeStr = json.hcursor.downField("tree").as[String].right.get
-
- val tree = ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(Base16.decode(treeStr).get)
-
- val addr = addressEncoder.fromProposition(tree).get
-
- addressEncoder.toString(addr) shouldBe address
- }
-
- val p2pk = "3WvsT2Gm4EpsM9Pg18PdY6XyhNNMqXDsvJTbbf6ihLvAmSb7u5RN"
- Get(s"$prefix/$suffix/$p2pk") ~> route ~> check(assertion(responseAs[Json], p2pk))
-
- val script = TrueLeaf
- val tree = ErgoTree.fromProposition(script)
-
- val p2sh = Pay2SHAddress.apply(tree).toString()
- p2sh shouldBe "rbcrmKEYduUvADj9Ts3dSVSG27h54pgrq5fPuwB"
- Get(s"$prefix/$suffix/$p2sh") ~> route ~> check(assertion(responseAs[Json], p2sh))
-
- val p2s = addressEncoder.toString(addressEncoder.fromProposition(tree).get)
- p2s shouldBe "Ms7smJwLGbUAjuWQ"
- Get(s"$prefix/$suffix/$p2s") ~> route ~> check(assertion(responseAs[Json], p2s))
- }
-
- it should "address <-> bytes roundtrip via addressToBytes" in {
- val suffix = "addressToBytes"
-
- val assertion = (json: Json, address: String) => {
- status shouldBe StatusCodes.OK
- val vs = json.hcursor.downField("bytes").as[String].right.get
- val vbs = Base16.decode(vs).get
-
- val bac = ValueSerializer.deserialize(vbs).asInstanceOf[CollectionConstant[SByte.type]]
-
- val bs = bac.value.toArray.map(_.byteValue())
-
- val tree = ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bs)
-
- val addr = addressEncoder.fromProposition(tree).get
-
- addressEncoder.toString(addr) shouldBe address
- }
-
- val p2pk = "3WvsT2Gm4EpsM9Pg18PdY6XyhNNMqXDsvJTbbf6ihLvAmSb7u5RN"
- Get(s"$prefix/$suffix/$p2pk") ~> route ~> check(assertion(responseAs[Json], p2pk))
-
- val p2sh = "rbcrmKEYduUvADj9Ts3dSVSG27h54pgrq5fPuwB"
- Get(s"$prefix/$suffix/$p2sh") ~> route ~> check(assertion(responseAs[Json], p2sh))
-
- val script = TrueLeaf
- val tree = ErgoTree.fromProposition(script)
- val p2s = addressEncoder.toString(addressEncoder.fromProposition(tree).get)
- p2s shouldBe "Ms7smJwLGbUAjuWQ"
- Get(s"$prefix/$suffix/$p2s") ~> route ~> check(assertion(responseAs[Json], p2s))
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/TransactionApiRouteSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/TransactionApiRouteSpec.scala
deleted file mode 100644
index 1e7860907f..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/TransactionApiRouteSpec.scala
+++ /dev/null
@@ -1,303 +0,0 @@
-package org.ergoplatform.http.routes
-
-import akka.actor.{Actor, Props}
-import akka.http.scaladsl.model.StatusCodes
-import akka.http.scaladsl.server.Route
-import akka.http.scaladsl.testkit.ScalatestRouteTest
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.Json
-import io.circe.syntax._
-import org.ergoplatform.ErgoBox.{AdditionalRegisters, NonMandatoryRegisterId, TokenId}
-import org.ergoplatform.http.api.{ApiCodecs, TransactionsApiRoute}
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.nodeView.ErgoReadersHolder.{GetDataFromHistory, GetReaders, Readers}
-import org.ergoplatform.settings.Constants
-import org.ergoplatform.utils.Stubs
-import org.ergoplatform.{DataInput, ErgoBox, ErgoBoxCandidate, Input}
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-import scorex.core.settings.RESTApiSettings
-import scorex.util.encode.Base16
-import sigmastate.SType
-import sigmastate.Values.{ByteArrayConstant, EvaluatedValue}
-import sigmastate.eval.Extensions._
-import sigmastate.eval._
-import sigma.Extensions._
-
-import java.net.InetSocketAddress
-import scala.concurrent.duration._
-
-class TransactionApiRouteSpec extends AnyFlatSpec
- with Matchers
- with ScalatestRouteTest
- with Stubs
- with ApiCodecs
- with FailFastCirceSupport {
-
- val prefix = "/transactions"
-
- val restApiSettings = RESTApiSettings(new InetSocketAddress("localhost", 8080), None, None, 10.seconds, None)
- val route: Route = TransactionsApiRoute(utxoReadersRef, nodeViewRef, settings).route
-
- val inputBox: ErgoBox = utxoState.takeBoxes(1).head
- val input = Input(inputBox.id, emptyProverResult)
- val dataInput = DataInput(input.boxId)
-
- val absentModifierId = "0000000000000000000000000000000000000000000000000000000000000000"
- val tokens = List[(TokenId, Long)](inputBox.id.toTokenId -> 10)
- val registers =
- Map(
- ErgoBox.R4 -> ByteArrayConstant("name".getBytes("UTF-8")),
- ErgoBox.R5 -> ByteArrayConstant("4".getBytes("UTF-8")),
- )
-
- val output: ErgoBoxCandidate =
- new ErgoBoxCandidate(inputBox.value, Constants.TrueLeaf, creationHeight = 0, tokens.toColl, registers)
- val tx: ErgoTransaction = ErgoTransaction(IndexedSeq(input), IndexedSeq(dataInput), IndexedSeq(output))
-
- val chainedInput = Input(tx.outputs.head.id, emptyProverResult)
- val chainedTx: ErgoTransaction = ErgoTransaction(IndexedSeq(chainedInput), IndexedSeq(output))
-
- val chainedRoute: Route = {
- //constructing memory pool and node view with the transaction tx included
- val mp2 = memPool.put(UnconfirmedTransaction(tx, None))
- class UtxoReadersStub2 extends Actor {
- def receive: PartialFunction[Any, Unit] = {
- case GetReaders => sender() ! Readers(history, utxoState, mp2, wallet)
- case GetDataFromHistory(f) => sender() ! f(history)
- }
- }
- val readers2 = system.actorOf(Props(new UtxoReadersStub2))
- TransactionsApiRoute(readers2, nodeViewRef, settings).route
- }
-
- it should "post transaction" in {
- Post(prefix, tx.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[String] shouldEqual tx.id
- }
- }
-
- it should "fail when posting invalid transaction" in {
- val failingNodeViewRef = system.actorOf(NodeViewStub.failingProps())
- val failingRoute: Route = TransactionsApiRoute(digestReadersRef, failingNodeViewRef, settings).route
-
- Post(prefix, tx.asJson) ~> failingRoute ~> check {
- status shouldBe StatusCodes.BadRequest
- }
- }
-
- it should "post chained transactions" in {
- Post(prefix, chainedTx.asJson) ~> route ~> check {
- status shouldBe StatusCodes.BadRequest
- }
-
- Post(prefix, tx.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[String] shouldEqual tx.id
- }
-
- Post(prefix, chainedTx.asJson) ~> chainedRoute ~> check {
- status shouldBe StatusCodes.OK
- responseAs[String] shouldEqual chainedTx.id
- }
- }
-
- it should "check transaction" in {
- Post(prefix + "/check", tx.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[String] shouldEqual tx.id
- }
- //second attempt should be fine also
- Post(prefix + "/check", tx.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[String] shouldEqual tx.id
- }
-
- Post(prefix + "/check", chainedTx.asJson) ~> route ~> check {
- status shouldBe StatusCodes.BadRequest
- }
-
- Post(prefix + "/check", chainedTx.asJson) ~> chainedRoute ~> check {
- status shouldBe StatusCodes.OK
- responseAs[String] shouldEqual chainedTx.id
- }
- }
-
- it should "get unconfirmed txs from mempool" in {
- Get(prefix + "/unconfirmed") ~> route ~> check {
- status shouldBe StatusCodes.OK
- memPool.take(50).map(_.transaction).toSeq shouldBe responseAs[Seq[ErgoTransaction]]
- }
- }
-
- it should "get unconfirmed from mempool using limit and offset" in {
- val limit = 10
- val offset = 20
- Get(prefix + s"/unconfirmed?limit=$limit&offset=$offset") ~> route ~> check {
- status shouldBe StatusCodes.OK
- memPool.getAll.slice(offset, offset + limit).map(_.transaction) shouldBe responseAs[Seq[ErgoTransaction]]
- }
- }
-
- it should "return unconfirmed tx by output ergoTree from mempool" in {
- val searchedBox = txs.head.outputs.head.ergoTree.bytesHex
- Post(prefix + s"/unconfirmed/byErgoTree", searchedBox) ~> route ~> check {
- val expectedTxs = memPool.getAll.toSet.filter(_.transaction.outputs.exists(_.ergoTree.bytesHex == searchedBox))
- val actualTxs = responseAs[Set[ErgoTransaction]]
- status shouldBe StatusCodes.OK
- expectedTxs.map(_.id) shouldBe actualTxs.map(_.id)
- actualTxs.forall(tx => tx.outputs.map(_.ergoTree.bytesHex).contains(searchedBox)) shouldBe true
- }
- }
-
- it should "return unconfirmed tx by input ergoTree from mempool" in {
- val searchedBox = inputBox.ergoTree.bytesHex
- Post(prefix + s"/unconfirmed/byErgoTree", searchedBox) ~> chainedRoute ~> check {
- status shouldBe StatusCodes.OK
- val txs = responseAs[Set[ErgoTransaction]]
- txs.forall { tx =>
- tx.inputs.map(_.boxId).exists(_.sameElements(inputBox.id)) ||
- tx.outputs.map(_.ergoTree.bytesHex).contains(searchedBox)
- } shouldBe true
- }
- }
-
- it should "return unconfirmed tx by absent ergoTree from mempool" in {
- Post(prefix + s"/unconfirmed/byErgoTree", absentModifierId) ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Seq[ErgoTransaction]] shouldBe List.empty
- }
- }
-
- it should "return unconfirmed tx by id from mempool" in {
- Get(prefix + s"/unconfirmed/byTransactionId/${txs.head.id}") ~> route ~> check {
- status shouldBe StatusCodes.OK
- memPool.modifierById(txs.head.id).get shouldBe responseAs[ErgoTransaction]
- }
- }
-
- it should "return unconfirmed tx by absent id from mempool" in {
- Get(prefix + s"/unconfirmed/byTransactionId/$absentModifierId") ~> route ~> check {
- status shouldBe StatusCodes.NotFound
- }
- }
-
- it should "return 200 if unconfirmed tx is present" in {
- Head(prefix + s"/unconfirmed/${txs.head.id}") ~> route ~> check {
- status shouldBe StatusCodes.OK
- }
- }
-
- it should "return 404 if unconfirmed absent tx is present" in {
- Head(prefix + s"/unconfirmed/$absentModifierId") ~> route ~> check {
- status shouldBe StatusCodes.NotFound
- }
- }
-
- it should "return unconfirmed input by boxId from mempool" in {
- val searchedBox = inputBox.id
- val searchedBoxEncoded = Base16.encode(searchedBox)
- Get(prefix + s"/unconfirmed/inputs/byBoxId/$searchedBoxEncoded") ~> chainedRoute ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("boxId").as[String] shouldEqual Right(searchedBoxEncoded)
- }
- }
-
- it should "return unconfirmed output by boxId from mempool" in {
- val searchedBox = txs.head.outputs.head.id
- val searchedBoxEncoded = Base16.encode(searchedBox)
- Get(prefix + s"/unconfirmed/outputs/byBoxId/$searchedBoxEncoded") ~> chainedRoute ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("boxId").as[String] shouldEqual Right(searchedBoxEncoded)
- }
- }
-
- it should "return unconfirmed output by ergoTree from mempool" in {
- val searchedBox = txs.head.outputs.head
- val searchedTree = searchedBox.ergoTree.bytesHex
- Post(prefix + s"/unconfirmed/outputs/byErgoTree", searchedTree) ~> route ~> check {
- val expectedOutputIds =
- memPool.getAll
- .flatMap(_.transaction.outputs)
- .filter(_.ergoTree.bytesHex == searchedTree)
- .map(b => Base16.encode(b.id)).take(50).toList
- status shouldBe StatusCodes.OK
- val actualOutputIds = responseAs[List[Json]].map(_.hcursor.downField("boxId").as[String].right.get)
- actualOutputIds shouldEqual expectedOutputIds
- }
- }
-
- it should "return unconfirmed output by tokenId from mempool" in {
- val searchedToken = tokens.head._1.toHex
- Get(prefix + s"/unconfirmed/outputs/byTokenId/$searchedToken") ~> chainedRoute ~> check {
- status shouldBe StatusCodes.OK
- val actualOutputIds = responseAs[List[Json]].map(_.hcursor.downField("boxId").as[String].right.get)
- actualOutputIds.nonEmpty shouldBe true
- actualOutputIds shouldEqual List(Base16.encode(tx.outputs.head.id))
- }
- }
-
- it should "return unconfirmed outputs by exact same registers" in {
- val searchedRegs =
- Map(
- ErgoBox.R4 -> ByteArrayConstant("name".getBytes("UTF-8")),
- ErgoBox.R5 -> ByteArrayConstant("4".getBytes("UTF-8")),
- ).asInstanceOf[AdditionalRegisters].asJson
-
- Post(prefix + s"/unconfirmed/outputs/byRegisters", searchedRegs) ~> chainedRoute ~> check {
- status shouldBe StatusCodes.OK
- val actualBoxes = responseAs[List[Json]].flatMap(_.hcursor.downField("boxId").as[String].toOption)
- actualBoxes.head shouldEqual Base16.encode(tx.outputs.head.id)
- }
- }
-
- it should "return unconfirmed outputs by subset of registers" in {
- val searchedRegs =
- Map[NonMandatoryRegisterId, EvaluatedValue[_ <: SType]](
- ErgoBox.R4 -> ByteArrayConstant("name".getBytes("UTF-8"))
- ).asJson
-
- Post(prefix + s"/unconfirmed/outputs/byRegisters", searchedRegs) ~> chainedRoute ~> check {
- status shouldBe StatusCodes.OK
- val actualBoxes = responseAs[List[Json]].flatMap(_.hcursor.downField("boxId").as[String].toOption)
- actualBoxes.head shouldEqual Base16.encode(tx.outputs.head.id)
- }
- }
-
- it should "not return unconfirmed output by registers when one missing" in {
- val searchedRegs =
- Map(
- ErgoBox.R4 -> ByteArrayConstant("name".getBytes("UTF-8")),
- ErgoBox.R5 -> ByteArrayConstant("4".getBytes("UTF-8")),
- ErgoBox.R6 -> ByteArrayConstant("description".getBytes("UTF-8")),
- ).asInstanceOf[AdditionalRegisters].asJson
-
- Post(prefix + s"/unconfirmed/outputs/byRegisters", searchedRegs) ~> chainedRoute ~> check {
- status shouldBe StatusCodes.OK
- val actualBoxes = responseAs[List[Json]].flatMap(_.hcursor.downField("boxId").as[String].toOption)
- actualBoxes shouldEqual List.empty
- }
- }
-
- it should "not return unconfirmed outputs by registers with only key match" in {
- val searchedRegs =
- Map[NonMandatoryRegisterId, EvaluatedValue[_ <: SType]](
- ErgoBox.R4 -> ByteArrayConstant("foo".getBytes("UTF-8"))
- ).asJson
-
- Post(prefix + s"/unconfirmed/outputs/byRegisters", searchedRegs) ~> chainedRoute ~> check {
- status shouldBe StatusCodes.OK
- val actualBoxes = responseAs[List[Json]].flatMap(_.hcursor.downField("boxId").as[String].toOption)
- actualBoxes shouldEqual List.empty
- }
- }
-
- it should "not return unconfirmed outputs by empty registers" in {
- val searchedRegs = Map.empty[NonMandatoryRegisterId, EvaluatedValue[_ <: SType]].asJson
- Post(prefix + s"/unconfirmed/outputs/byRegisters", searchedRegs) ~> chainedRoute ~> check {
- status shouldBe StatusCodes.BadRequest
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/UtilsApiRouteSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/UtilsApiRouteSpec.scala
deleted file mode 100644
index ea4f0e01ba..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/UtilsApiRouteSpec.scala
+++ /dev/null
@@ -1,156 +0,0 @@
-package org.ergoplatform.http.routes
-
-import java.net.InetSocketAddress
-
-import akka.http.scaladsl.model.StatusCodes
-import akka.http.scaladsl.server.Route
-import akka.http.scaladsl.testkit.ScalatestRouteTest
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.Json
-import org.ergoplatform.utils.Stubs
-import org.ergoplatform.{P2PKAddress, Pay2SAddress, Pay2SHAddress}
-import org.ergoplatform.http.api.ErgoUtilsApiRoute
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-import scorex.core.settings.RESTApiSettings
-import scorex.util.encode.Base16
-import sigmastate.serialization.ErgoTreeSerializer
-
-import scala.concurrent.duration._
-
-class UtilsApiRouteSpec extends AnyFlatSpec
- with Matchers
- with ScalatestRouteTest
- with FailFastCirceSupport
- with Stubs {
-
- val prefix = "/utils"
-
- val restApiSettings = RESTApiSettings(new InetSocketAddress("localhost", 8080), None, None, 10.seconds, None)
- val route: Route = ErgoUtilsApiRoute(settings).route
- val p2pkaddress = P2PKAddress(defaultMinerPk)
- val p2shaddress = Pay2SHAddress(feeProp)
- val p2saddress = Pay2SAddress(feeProp)
-
- val treeSerializer: ErgoTreeSerializer = new ErgoTreeSerializer
-
- it should "derive address from ErgoTree (p2s)" in {
- val et = Base16.encode(treeSerializer.serializeErgoTree(p2saddress.script))
- Get(s"$prefix/ergoTreeToAddress/$et") ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("address").as[String] shouldEqual Right(p2saddress.toString())
- }
- }
-
- it should "validate correct p2s address" in {
- Get(s"$prefix/address/$p2saddress") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received node info: $json")
- val c = json.hcursor
- c.downField("address").as[String] shouldEqual Right(p2saddress.toString())
- c.downField("isValid").as[Boolean] shouldEqual Right(true)
- }
- }
-
- it should "validate incorrect address (p2s)" in {
- val invalidAddress = p2saddress + "aa"
- Get(s"$prefix/address/$invalidAddress") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received node info: $json")
- val c = json.hcursor
- c.downField("address").as[String] shouldEqual Right(invalidAddress)
- c.downField("isValid").as[Boolean] shouldEqual Right(false)
- c.downField("error").as[String] shouldEqual Right("requirement failed: Trying to decode mainnet address in testnet")
- }
- }
-
- //p2sh
-
- it should "derive address from ErgoTree (p2sh)" in {
- val et = Base16.encode(treeSerializer.serializeErgoTree(p2shaddress.script))
- Get(s"$prefix/ergoTreeToAddress/$et") ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("address").as[String] shouldEqual Right(p2shaddress.toString())
- }
- }
-
- it should "validate correct p2sh address" in {
- Get(s"$prefix/address/$p2shaddress") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received node info: $json")
- val c = json.hcursor
- c.downField("address").as[String] shouldEqual Right(p2shaddress.toString())
- c.downField("isValid").as[Boolean] shouldEqual Right(true)
- }
- }
-
- it should "validate incorrect address (p2sh)" in {
- val invalidAddress = p2shaddress + "aa"
- Get(s"$prefix/address/$invalidAddress") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received node info: $json")
- val c = json.hcursor
- c.downField("address").as[String] shouldEqual Right(invalidAddress)
- c.downField("isValid").as[Boolean] shouldEqual Right(false)
- c.downField("error").as[String] shouldEqual Right("requirement failed: Trying to decode mainnet address in testnet")
- }
- }
-
- //p2pk
-
- it should "do correct raw/address roundtrip (p2pk)" in {
- var raw: String = null
-
- Get(s"$prefix/addressToRaw/$p2pkaddress") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- val c = json.hcursor
- raw = c.downField("raw").as[String].toOption.get
- }
-
- Get(s"$prefix/rawToAddress/$raw") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- val c = json.hcursor
- c.downField("address").as[String] shouldEqual Right(p2pkaddress.toString())
- }
- }
-
- it should "derive address from ErgoTree (p2pk)" in {
- val et = Base16.encode(treeSerializer.serializeErgoTree(p2pkaddress.script))
- Get(s"$prefix/ergoTreeToAddress/$et") ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("address").as[String] shouldEqual Right(p2pkaddress.toString())
- }
- }
-
- it should "validate correct p2pk address" in {
- Get(s"$prefix/address/$p2pkaddress") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received node info: $json")
- val c = json.hcursor
- c.downField("address").as[String] shouldEqual Right(p2pkaddress.toString())
- c.downField("isValid").as[Boolean] shouldEqual Right(true)
- }
- }
-
- it should "validate incorrect address (p2pk)" in {
- val invalidAddress = p2pkaddress + "aa"
- Get(s"$prefix/address/$invalidAddress") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received node info: $json")
- val c = json.hcursor
- c.downField("address").as[String] shouldEqual Right(invalidAddress)
- c.downField("isValid").as[Boolean] shouldEqual Right(false)
- c.downField("error").as[String] shouldEqual Right("requirement failed: Trying to decode mainnet address in testnet")
- }
- }
-
-}
-
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/UtxoApiRouteSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/UtxoApiRouteSpec.scala
deleted file mode 100644
index b5a2fa391b..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/UtxoApiRouteSpec.scala
+++ /dev/null
@@ -1,125 +0,0 @@
-package org.ergoplatform.http.routes
-
-import akka.http.scaladsl.model.StatusCodes
-import akka.http.scaladsl.server.Route
-import akka.http.scaladsl.testkit.ScalatestRouteTest
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.Json
-import io.circe.syntax._
-import org.ergoplatform.http.api.{ApiCodecs, UtxoApiRoute}
-import org.ergoplatform.utils.Stubs
-import org.ergoplatform.wallet.boxes.ErgoBoxSerializer
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-import scorex.crypto.hash.Blake2b256
-import scorex.util.encode.Base16
-
-class UtxoApiRouteSpec
- extends AnyFlatSpec
- with Matchers
- with ScalatestRouteTest
- with Stubs
- with FailFastCirceSupport
- with ApiCodecs {
-
- val prefix = "/utxo"
-
- val route: Route =
- UtxoApiRoute(utxoReadersRef, utxoSettings.scorexSettings.restApi).route
-
- it should "get utxo box with /byId" in {
- val box = utxoState.takeBoxes(1).head
- val boxId = Base16.encode(box.id)
- Get(prefix + s"/byId/$boxId") ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("value").as[Long] shouldEqual Right(box.value)
- responseAs[Json].hcursor.downField("boxId").as[String] shouldEqual Right(boxId)
- }
- }
-
- it should "get mempool box with withPool/byId" in {
- val box = memPool.getAll.map(utx => utx.transaction).flatMap(_.outputs).head
- val boxId = Base16.encode(box.id)
- Get(prefix + s"/byId/$boxId") ~> route ~> check {
- status shouldBe StatusCodes.NotFound
- }
- Get(prefix + s"/withPool/byId/$boxId") ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("value").as[Long] shouldEqual Right(box.value)
- responseAs[Json].hcursor.downField("boxId").as[String] shouldEqual Right(boxId)
- }
- }
-
- it should "get all mempool boxes with withPool/byIds" in {
- val boxes = memPool.getAll.map(utx => utx.transaction).flatMap(_.outputs)
- val boxesEncoded = boxes.map(box => Base16.encode(box.id))
-
- Post(prefix + "/withPool/byIds", boxesEncoded.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Seq[Json]]
- .map(_.hcursor.downField("value").as[Long]) shouldEqual boxes.map(x => Right(x.value))
- responseAs[Seq[Json]]
- .map(_.hcursor.downField("boxId").as[String]) shouldEqual boxesEncoded.map(x => Right(x))
- }
- }
-
- it should "not found utxo box with /byId" in {
- val boxId = Base16.encode(Blake2b256(utxoState.takeBoxes(1).head.id))
- Get(prefix + s"/byId/$boxId") ~> route ~> check {
- status shouldBe StatusCodes.NotFound
- }
- }
-
- it should "get utxo box with /byIdBinary" in {
- val box = utxoState.takeBoxes(1).head
- val boxId = Base16.encode(box.id)
- Get(prefix + s"/byIdBinary/$boxId") ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("boxId").as[String] shouldEqual Right(boxId)
- val bytes = Base16
- .decode(responseAs[Json].hcursor.downField("bytes").as[String].toOption.get)
- .get
- val boxRestored = ErgoBoxSerializer.parseBytes(bytes)
- box shouldEqual boxRestored
- }
- }
-
- it should "not found utxo box with /byIdBinary" in {
- val boxId = Base16.encode(Blake2b256(utxoState.takeBoxes(1).head.id))
- Get(prefix + s"/byId/$boxId") ~> route ~> check {
- status shouldBe StatusCodes.NotFound
- }
- }
-
- it should "get pool box with /withPool/byIdBinary" in {
- val box = memPool.getAll.map(utx => utx.transaction).flatMap(_.outputs).head
- val boxId = Base16.encode(box.id)
- Get(prefix + s"/byIdBinary/$boxId") ~> route ~> check {
- status shouldBe StatusCodes.NotFound
- }
- Get(prefix + s"/withPool/byIdBinary/$boxId") ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("boxId").as[String] shouldEqual Right(boxId)
- val bytes = Base16
- .decode(responseAs[Json].hcursor.downField("bytes").as[String].toOption.get)
- .get
- val boxRestored = ErgoBoxSerializer.parseBytes(bytes)
- box shouldEqual boxRestored
- }
- }
-
- it should "/genesis returns 3 boxes" in {
- Get(prefix + s"/genesis") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = responseAs[List[Json]]
- response.size shouldBe 3 // 3 genesis boxes as per Ergo Whitepaper
- }
- }
-
- it should "get serialized proof for given boxes" in {
- val boxes = utxoState.takeBoxes(10).map(box => Base16.encode(box.id))
- Post(prefix + s"/getBoxesBinaryProof", boxes.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- }
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/http/routes/WalletApiRouteSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/http/routes/WalletApiRouteSpec.scala
deleted file mode 100644
index 3aa73d9dc1..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/http/routes/WalletApiRouteSpec.scala
+++ /dev/null
@@ -1,314 +0,0 @@
-package org.ergoplatform.http.routes
-
-import akka.http.scaladsl.model.StatusCodes
-import akka.http.scaladsl.server.{Route, ValidationRejection}
-import akka.http.scaladsl.testkit.{RouteTestTimeout, ScalatestRouteTest}
-import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
-import io.circe.syntax._
-import io.circe.{Decoder, Json}
-import org.ergoplatform.http.api.{ApiCodecs, WalletApiRoute}
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.nodeView.wallet.requests.{AssetIssueRequestEncoder, PaymentRequest, PaymentRequestEncoder, _}
-import org.ergoplatform.nodeView.wallet.{AugWalletTransaction, ErgoAddressJsonEncoder}
-import org.ergoplatform.settings.{Args, Constants, ErgoSettings}
-import org.ergoplatform.utils.Stubs
-import org.ergoplatform.utils.generators.ErgoTransactionGenerators
-import org.ergoplatform.{ErgoAddress, Pay2SAddress}
-import org.ergoplatform.wallet.{Constants => WalletConstants}
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-import scala.util.{Random, Try}
-import scala.concurrent.duration._
-import akka.http.scaladsl.server.MissingQueryParamRejection
-
-class WalletApiRouteSpec extends AnyFlatSpec
- with Matchers
- with ScalatestRouteTest
- with Stubs
- with FailFastCirceSupport
- with ApiCodecs {
-
- implicit val timeout: RouteTestTimeout = RouteTestTimeout(145.seconds)
-
- val prefix = "/wallet"
-
- val ergoSettings: ErgoSettings = ErgoSettings.read(
- Args(userConfigPathOpt = Some("src/test/resources/application.conf"), networkTypeOpt = None))
- val route: Route = WalletApiRoute(digestReadersRef, nodeViewRef, settings).route
- val failingNodeViewRef = system.actorOf(NodeViewStub.failingProps())
- val failingRoute: Route = WalletApiRoute(digestReadersRef, failingNodeViewRef, settings).route
-
- val utxoRoute: Route = WalletApiRoute(utxoReadersRef, nodeViewRef, settings).route
-
- implicit val paymentRequestEncoder: PaymentRequestEncoder = new PaymentRequestEncoder(ergoSettings)
- implicit val assetIssueRequestEncoder: AssetIssueRequestEncoder = new AssetIssueRequestEncoder(ergoSettings)
- implicit val requestsHolderEncoder: RequestsHolderEncoder = new RequestsHolderEncoder(ergoSettings)
- implicit val addressJsonDecoder: Decoder[ErgoAddress] = ErgoAddressJsonEncoder(settings).decoder
-
- val paymentRequest = PaymentRequest(Pay2SAddress(Constants.FalseLeaf)(addressEncoder), 100L, Seq.empty, Map.empty)
- val assetIssueRequest = AssetIssueRequest(Pay2SAddress(Constants.FalseLeaf)(addressEncoder), None, 100L, "TEST", "Test", 8)
- val requestsHolder = RequestsHolder(
- (0 to 10).flatMap(_ => Seq(paymentRequest, assetIssueRequest)),
- Some(10000L),
- Seq.empty,
- Seq.empty,
- minerRewardDelay = 720
- )(addressEncoder)
-
-
- it should "generate arbitrary transaction" in {
- Post(prefix + "/transaction/generate", requestsHolder.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- Try(responseAs[ErgoTransaction]) shouldBe 'success
- }
- }
-
- it should "get balances" in {
- Get(prefix + "/balances") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received balances: $json")
- val c = json.hcursor
- c.downField("balance").as[Long] shouldEqual Right(WalletActorStub.confirmedBalance)
- }
- }
-
- it should "get unconfirmed balances" in {
- Get(prefix + "/balances/withUnconfirmed") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val json = responseAs[Json]
- log.info(s"Received total confirmed with unconfirmed balances: $json")
- val c = json.hcursor
- c.downField("balance").as[Long] shouldEqual Right(WalletActorStub.unconfirmedBalance)
- }
- }
-
- it should "generate & send arbitrary transaction" in {
- Post(prefix + "/transaction/send", requestsHolder.asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[String] should not be empty
- }
- }
-
- it should "fail when sent transaction is invalid" in {
- Post(prefix + "/transaction/send", requestsHolder.asJson) ~> failingRoute ~> check {
- status shouldBe StatusCodes.BadRequest
- }
- }
-
- it should "sign a transaction" in {
- val digest = Random.nextBoolean()
- val (tsr, r) = if (digest) {
- (ErgoTransactionGenerators.transactionSigningRequestGen(true).sample.get, route)
- } else {
- (ErgoTransactionGenerators.transactionSigningRequestGen(utxoState).sample.get, utxoRoute)
- }
- Post(prefix + "/transaction/sign", tsr.asJson) ~> r ~> check {
- status shouldBe StatusCodes.OK
- responseAs[ErgoTransaction].id shouldBe tsr.unsignedTx.id
- }
- }
-
- it should "generate & send payment transaction" in {
- Post(prefix + "/payment/send", Seq(paymentRequest).asJson) ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[String] should not be empty
- }
- }
-
- it should "fail when payment is invalid" in {
- Post(prefix + "/payment/send", Seq(paymentRequest).asJson) ~> failingRoute ~> check {
- status shouldBe StatusCodes.BadRequest
- }
- }
-
- it should "return addresses" in {
- Get(prefix + "/addresses") ~> route ~> check {
- status shouldBe StatusCodes.OK
- }
- }
-
- it should "initialize wallet" in {
- Post(prefix + "/init", Json.obj("pass" -> "1234".asJson)) ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("mnemonic").as[String] shouldEqual Right(WalletActorStub.mnemonic)
- }
- }
-
- it should "restore wallet" in {
- Post(prefix + "/restore", Json.obj("pass" -> "1234".asJson, "mnemonic" -> WalletActorStub.mnemonic.asJson,
- "usePre1627KeyDerivation" -> false.asJson)) ~>
- route ~> check(status shouldBe StatusCodes.OK)
- }
-
- it should "not restore wallet without key derivation method specified" in {
- Post(prefix + "/restore", Json.obj("pass" -> "1234".asJson, "mnemonic" -> WalletActorStub.mnemonic.asJson)) ~>
- route ~> check(rejection shouldBe a[MissingQueryParamRejection])
- }
-
- it should "unlock wallet" in {
- Post(prefix + "/unlock", Json.obj("pass" -> "1234".asJson)) ~> route ~> check {
- status shouldBe StatusCodes.OK
- }
- }
-
- it should "check wallet" in {
- Post(prefix + "/check", Json.obj("mnemonic" -> WalletActorStub.mnemonic.asJson)) ~>
- route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("matched").as[Boolean] shouldBe Right(true)
- }
- }
-
- it should "lock wallet" in {
- Get(prefix + "/lock") ~> route ~> check {
- status shouldBe StatusCodes.OK
- }
- }
-
- it should "rescan wallet post" in {
- Post(prefix + "/rescan") ~> route ~> check {
- status shouldBe StatusCodes.OK
- }
- }
-
- it should "rescan wallet post with fromHeight" in {
- Post(prefix + "/rescan", Json.obj("fromHeight" -> 0.asJson)) ~> route ~> check {
- status shouldBe StatusCodes.OK
- }
-
- Post(prefix + "/rescan", Json.obj("fromHeight" -> (-1).asJson)) ~> route ~> check {
- rejection shouldEqual ValidationRejection("fromHeight field must be >= 0", None)
- }
- }
-
- it should "derive new key according to a provided path" in {
- Post(prefix + "/deriveKey", Json.obj("derivationPath" -> "m/1/2".asJson)) ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("address").as[String] shouldEqual Right(WalletActorStub.address.toString)
- }
- }
-
- it should "derive next key" in {
- Get(prefix + "/deriveNextKey") ~> route ~> check {
- status shouldBe StatusCodes.OK
- responseAs[Json].hcursor.downField("derivationPath").as[String] shouldEqual Right(WalletActorStub.path.encoded)
- responseAs[Json].hcursor.downField("address").as[String] shouldEqual Right(WalletActorStub.address.toString)
- }
- }
-
- it should "return wallet boxes" in {
- Get(prefix + "/boxes") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = responseAs[List[Json]]
- response.size shouldBe 3
- }
- }
-
- it should "return wallet boxes with lower constraint" in {
- val minConfirmations = 15
- val minInclusionHeight = 20
- val postfix = s"/boxes?minConfirmations=$minConfirmations&minInclusionHeight=$minInclusionHeight"
- Get(prefix + postfix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = responseAs[List[Json]]
- response.size shouldBe 2
- response.head.hcursor.downField("confirmationsNum").as[Int].forall(_ >= minConfirmations) shouldBe true
- response.head.hcursor.downField("inclusionHeight").as[Int].forall(_ >= minInclusionHeight) shouldBe true
- }
- }
-
- it should "return wallet boxes with upper constraint" in {
- val maxConfirmations = 15
- val maxInclusionHeight = 20
- val postfix = s"/boxes?maxConfirmations=$maxConfirmations&maxInclusionHeight=$maxInclusionHeight"
- Get(prefix + postfix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = responseAs[List[Json]]
- response.size shouldBe 1
- response.head.hcursor.downField("confirmationsNum").as[Int].forall(_ <= maxConfirmations) shouldBe true
- response.head.hcursor.downField("inclusionHeight").as[Int].forall(_ <= maxInclusionHeight) shouldBe true
- }
- }
-
- it should "return wallet boxes with both lower and upper constraint" in {
- val confirmations = 15
- val inclusionHeight = 20
- val postfix = s"/boxes?$confirmations&minInclusionHeight=$inclusionHeight&maxConfirmations=$confirmations&maxInclusionHeight=$inclusionHeight"
- Get(prefix + postfix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = responseAs[List[Json]]
- response.isEmpty shouldBe true
- }
- }
-
- it should "return unspent wallet boxes" in {
- val minConfirmations = 15
- val minInclusionHeight = 20
-
- val postfix = s"/boxes/unspent?minConfirmations=$minConfirmations&minInclusionHeight=$minInclusionHeight"
-
- Get(prefix + postfix) ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = responseAs[List[Json]]
- response.size shouldBe 1
- response.head.hcursor.downField("confirmationsNum").as[Int].forall(_ >= minConfirmations) shouldBe true
- response.head.hcursor.downField("inclusionHeight").as[Int].forall(_ >= minInclusionHeight) shouldBe true
- }
-
- Get(prefix + "/boxes/unspent") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = responseAs[List[Json]]
- response.size shouldBe 2
- }
- }
-
- it should "return wallet transactions" in {
- Get(prefix + "/transactions") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = responseAs[List[Json]]
- val walletTxs = WalletActorStub.walletTxs.filter { awtx =>
- awtx.wtx.scanIds.exists(_ <= WalletConstants.PaymentsScanId)
- }
-
- response.size shouldBe walletTxs.size
- responseAs[Seq[AugWalletTransaction]] shouldEqual walletTxs
- }
- }
-
- it should "return wallet transactions by scanId" in {
- Get(prefix + "/transactionsByScanId/1") ~> route ~> check {
- import AugWalletTransaction._
- status shouldBe StatusCodes.OK
- val response = responseAs[List[AugWalletTransaction]]
- val walletTxs = response.filter { awtx =>
- awtx.wtx.scanIds.contains(1.shortValue())
- }
- walletTxs.size shouldBe response.size
- }
- }
-
- it should "return wallet transactions by scanId including unconfirmed txs" in {
- Get(prefix + "/transactionsByScanId/1?includeUnconfirmed=true") ~> route ~> check {
- import AugWalletTransaction._
- status shouldBe StatusCodes.OK
- val response = responseAs[List[AugWalletTransaction]]
- val walletTxs = response.filter { awtx =>
- awtx.wtx.scanIds.contains(1.shortValue())
- }
- walletTxs.size shouldBe response.size
- walletTxs.forall(_.numConfirmations == 0) shouldBe true
- }
- }
-
- it should "get lock status" in {
- Get(prefix + "/status") ~> route ~> check {
- status shouldBe StatusCodes.OK
- val response = responseAs[Json]
- response.hcursor.downField("isUnlocked").as[Boolean] shouldBe Right(true)
- response.hcursor.downField("isInitialized").as[Boolean] shouldBe Right(true)
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala
deleted file mode 100644
index f018569c5e..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala
+++ /dev/null
@@ -1,121 +0,0 @@
-package org.ergoplatform.local
-
-import akka.actor.{ActorRef, ActorSystem}
-import akka.testkit.{TestActorRef, TestProbe}
-import org.ergoplatform.ErgoAddressEncoder
-import org.ergoplatform.modifiers.mempool.UnconfirmedTransaction
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.{FailedTransaction, RecheckMempool, SuccessfulTransaction}
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.{LocallyGeneratedTransaction, RecheckedTransactions}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.ProcessingOutcome
-import org.ergoplatform.nodeView.state.ErgoState
-import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
-import org.ergoplatform.settings.{Algos, Constants, ErgoSettings}
-import org.ergoplatform.utils.fixtures.NodeViewFixture
-import org.ergoplatform.utils.{ErgoTestHelpers, MempoolTestHelpers, NodeViewTestOps, RandomWrapper}
-import org.scalatest.flatspec.AnyFlatSpec
-import scorex.core.network.NetworkController.ReceivableMessages.SendToNetwork
-import sigmastate.Values.ErgoTree
-import sigmastate.eval.{IRContext, RuntimeIRContext}
-import sigmastate.interpreter.Interpreter.emptyEnv
-import sigmastate.lang.SigmaCompiler
-import sigmastate.lang.Terms.ValueOps
-import sigmastate.serialization.ErgoTreeSerializer
-
-import scala.concurrent.duration._
-
-class MempoolAuditorSpec extends AnyFlatSpec with NodeViewTestOps with ErgoTestHelpers with MempoolTestHelpers {
- implicit lazy val context: IRContext = new RuntimeIRContext
-
- val cleanupDuration: FiniteDuration = 200.millis
- val settingsToTest: ErgoSettings = settings.copy(
- nodeSettings = settings.nodeSettings.copy(
- mempoolCleanupDuration = cleanupDuration,
- rebroadcastCount = 1
- ))
- val fixture = new NodeViewFixture(settingsToTest, parameters)
- val newTx: Class[SuccessfulTransaction] = classOf[SuccessfulTransaction]
-
- it should "remove transactions which become invalid" in {
- import fixture._
-
- val testProbe = new TestProbe(actorSystem)
- actorSystem.eventStream.subscribe(testProbe.ref, newTx)
-
- val (us, bh) = createUtxoState(settingsToTest)
- val genesis = validFullBlock(parentOpt = None, us, bh)
- val wusAfterGenesis =
- WrappedUtxoState(us, bh, settingsToTest, parameters).applyModifier(genesis) { mod =>
- nodeViewHolderRef ! mod
- } .get
-
- applyBlock(genesis) shouldBe 'success
- getRootHash shouldBe Algos.encode(wusAfterGenesis.rootDigest)
-
- val boxes = ErgoState.newBoxes(genesis.transactions).find(_.ergoTree == Constants.TrueLeaf)
- boxes.nonEmpty shouldBe true
-
- val script = s"{sigmaProp(HEIGHT == ${genesis.height} + 1)}"
- val compiler = new SigmaCompiler(ErgoAddressEncoder.MainnetNetworkPrefix)
- val prop = compiler.compile(emptyEnv, script).buildTree
- val tree = ErgoTree.fromProposition(prop.asSigmaProp)
-
- val bs = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(tree)
- ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bs) shouldBe tree
-
- val validTx = validTransactionFromBoxes(boxes.toIndexedSeq, outputsProposition = tree)
-
- val temporarilyValidTx = validTransactionFromBoxes(validTx.outputs, outputsProposition = proveDlogGen.sample.get)
-
- subscribeEvents(classOf[FailedTransaction])
- nodeViewHolderRef ! LocallyGeneratedTransaction(UnconfirmedTransaction(validTx, None))
- testProbe.expectMsgClass(cleanupDuration, newTx)
- expectMsgType[ProcessingOutcome.Accepted]
-
- nodeViewHolderRef ! LocallyGeneratedTransaction(UnconfirmedTransaction(temporarilyValidTx, None))
- testProbe.expectMsgClass(cleanupDuration, newTx)
- expectMsgType[ProcessingOutcome.Accepted]
-
- getPoolSize shouldBe 2
-
- val _: ActorRef = MempoolAuditorRef(nodeViewHolderRef, nodeViewHolderRef, settingsToTest)
-
- Thread.sleep(200) // give transactions in the pool enough time to become candidates for re-checking
-
- // include first transaction in the block
- val block = validFullBlock(Some(genesis), wusAfterGenesis, Seq(validTx))
-
- applyBlock(block) shouldBe 'success
-
- scorex.core.utils.untilTimeout(cleanupDuration * 4, 100.millis) {
- // first tx removed from pool during node view update
- // another tx invalidated by `MempoolAuditor`
- getPoolSize shouldBe 0
- }
- }
-
- it should "rebroadcast transactions correctly" in {
-
- val (us0, bh0) = createUtxoState(settingsToTest)
- val (txs0, bh1) = validTransactionsFromBoxHolder(bh0)
- val b1 = validFullBlock(None, us0, txs0)
-
- val us = us0.applyModifier(b1, None)(_ => ()).get
-
- val bxs = bh1.boxes.values.toList.filter(_.proposition != genesisEmissionBox.proposition)
- val txs = validTransactionsFromBoxes(200000, bxs, new RandomWrapper)._1
- .map(tx => UnconfirmedTransaction(tx, None))
-
- implicit val system = ActorSystem()
- val probe = TestProbe()
-
- val auditor: ActorRef = TestActorRef(new MempoolAuditor(probe.ref, probe.ref, settingsToTest))
-
-
- auditor ! RecheckMempool(us, new FakeMempool(txs))
-
- probe.fishForMessage(3.seconds) {
- case _: SendToNetwork => true
- case _: RecheckedTransactions => false
- }.isInstanceOf[SendToNetwork] shouldBe true
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/local/NipopowVerifierSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/local/NipopowVerifierSpec.scala
deleted file mode 100644
index 21e13f95a6..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/local/NipopowVerifierSpec.scala
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.ergoplatform.local
-
-import org.ergoplatform.modifiers.history.popow.{PoPowHeader, PoPowParams}
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.utils.generators.{ChainGenerator, ErgoGenerators}
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-
-
-class NipopowVerifierSpec extends AnyPropSpec with Matchers with ChainGenerator with ErgoGenerators {
-
- private val poPowParams = PoPowParams(30, 30, continuous = false)
- val toPoPoWChain = (c: Seq[ErgoFullBlock]) => c.map(b => PoPowHeader.fromBlock(b).get)
-
- property("processes new proofs") {
- val sizes = Seq(1000)
- sizes.foreach { size =>
- val baseChain = genChain(size)
- val branchPoint = baseChain.last
- val shortChain = toPoPoWChain(baseChain)
- val longChain = toPoPoWChain(baseChain ++ genChain(5, branchPoint).tail)
- val longestChain = toPoPoWChain(baseChain ++ genChain(50, branchPoint).tail)
-
- val shortProof = nipopowAlgos.prove(shortChain)(poPowParams).get
- val longProof = nipopowAlgos.prove(longChain)(poPowParams).get
- val longestProof = nipopowAlgos.prove(longestChain)(poPowParams).get
-
- val verifier = new NipopowVerifier(Some(baseChain.head.id))
- verifier.bestChain.length shouldBe 0
-
- verifier.process(shortProof)
- verifier.bestChain.length should be > 0
-
- verifier.process(longProof)
- verifier.bestChain.last.id shouldBe longProof.headersChain.last.id
-
- verifier.process(longestProof)
- verifier.bestChain.last.id shouldBe longestProof.headersChain.last.id
-
- verifier.process(shortProof)
- verifier.bestChain.last.id shouldBe longestProof.headersChain.last.id
- }
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/mining/AutolykosPowSchemeSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/mining/AutolykosPowSchemeSpec.scala
deleted file mode 100644
index 173623f510..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/mining/AutolykosPowSchemeSpec.scala
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.ergoplatform.mining
-
-import com.google.common.primitives.Ints
-import org.ergoplatform.mining.difficulty.DifficultySerializer
-import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer}
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.scalacheck.Gen
-import scorex.crypto.hash.Blake2b256
-import scorex.testkit.utils.NoShrink
-import scorex.util.encode.Base16
-
-class AutolykosPowSchemeSpec extends ErgoPropertyTest with NoShrink {
-
- property("generated solution should be valid") {
- val pow = new AutolykosPowScheme(powScheme.k, powScheme.n)
- forAll(invalidHeaderGen,
- Gen.choose(100, 120),
- Gen.choose[Byte](1, 2)) { (inHeader, difficulty, ver) =>
- val nBits = DifficultySerializer.encodeCompactBits(difficulty)
- val h = inHeader.copy(nBits = nBits, version = ver)
- val sk = randomSecret()
- val x = randomSecret()
- val msg = pow.msgByHeader(h)
- val b = pow.getB(h.nBits)
- val hbs = Ints.toByteArray(h.height)
- val N = pow.calcN(h)
- val newHeader = pow.checkNonces(ver, hbs, msg, sk, x, b, N, 0, 1000)
- .map(s => h.copy(powSolution = s)).get
- pow.validate(newHeader) shouldBe 'success
-
- if(ver > Header.InitialVersion) {
- // We remove last byte of "msg", perform PoW and check that it fails validation
- require(HeaderSerializer.bytesWithoutPow(h).last == 0)
- val msg2 = Blake2b256(HeaderSerializer.bytesWithoutPow(h).dropRight(1))
-
- val newHeader2 = pow.checkNonces(ver, hbs, msg2, sk, x, b, N, 0, 1000)
- .map(s => h.copy(powSolution = s)).get
- pow.validate(newHeader2) shouldBe 'failure
- }
- }
- }
-
- property("calcN test vectors") {
- // mainnet parameters
- val k = 32
- val n = 26
-
- val pow = new AutolykosPowScheme(k, n)
-
- // N is always the same in Autolykos v1
- pow.calcN(1, 700000) shouldBe pow.NBase
- pow.calcN(1, 100000) shouldBe pow.NBase
- pow.calcN(1, 70000000) shouldBe pow.NBase
-
- pow.calcN(2, 500000) shouldBe pow.NBase
- pow.calcN(2, 600000) shouldBe pow.NBase
- pow.calcN(2, 600 * 1024) shouldBe 70464240
- pow.calcN(2, 650 * 1024) shouldBe 73987410
- pow.calcN(2, 700000) shouldBe 73987410
- pow.calcN(2, 788400) shouldBe 81571035 // 3 years
- pow.calcN(2, 1051200) shouldBe 104107290 // 4 years
- pow.calcN(2, 4198400) shouldBe 2143944600 // max height
- pow.calcN(2, 41984000) shouldBe 2143944600
- }
-
- property("test vectors for first increase in N value (height 614,400)") {
- import io.circe.parser._
- val pow = new AutolykosPowScheme(32, 26)
-
- val headerJson =
- """
- |{
- | "extensionId" : "00cce45975d87414e8bdd8146bc88815be59cd9fe37a125b5021101e05675a18",
- | "difficulty" : "16384",
- | "votes" : "000000",
- | "timestamp" : 4928911477310178288,
- | "size" : 223,
- | "stateRoot" : "5c8c00b8403d3701557181c8df800001b6d5009e2201c6ff807d71808c00019780",
- | "height" : 614400,
- | "nBits" : 37748736,
- | "version" : 2,
- | "id" : "5603a937ec1988220fc44fb5022fb82d5565b961f005ebb55d85bd5a9e6f801f",
- | "adProofsRoot" : "5d3f80dcff7f5e7f59007294c180808d0158d1ff6ba10000f901c7f0ef87dcff",
- | "transactionsRoot" : "f17fffacb6ff7f7f1180d2ff7f1e24ffffe1ff937f807f0797b9ff6ebdae007e",
- | "extensionHash" : "1480887f80007f4b01cf7f013ff1ffff564a0000b9a54f00770e807f41ff88c0",
- | "powSolutions" : {
- | "pk" : "03bedaee069ff4829500b3c07c4d5fe6b3ea3d3bf76c5c28c1d4dcdb1bed0ade0c",
- | "n" : "0000000000003105"
- | },
- | "adProofsId" : "dec129290a763f4de41f04e87e2b661dd59758af6bdd00dd51f5d97c3a8cb9b5",
- | "transactionsId" : "eba1dd82cf51147232e09c1f72b37c554c30f63274d5093bff36849a83472a42",
- | "parentId" : "ac2101807f0000ca01ff0119db227f202201007f62000177a080005d440896d0"
- |}
- """.stripMargin
-
- val header = Header.jsonDecoder.decodeJson(parse(headerJson).toOption.get).toOption.get
-
- header.height shouldBe 614400
-
- val msg = Base16.encode(pow.msgByHeader(header))
- msg shouldBe "548c3e602a8f36f8f2738f5f643b02425038044d98543a51cabaa9785e7e864f"
-
- pow.calcN(header) shouldBe 70464240
-
- // vector got from a miner dev
- pow.hitForVersion2(header) shouldBe toBigInt(Base16.decode("0002fcb113fe65e5754959872dfdbffea0489bf830beb4961ddc0e9e66a1412a").get)
-
- pow.getB(header.nBits) shouldBe BigInt("7067388259113537318333190002971674063283542741642755394446115914399301849")
-
- Base16.encode(groupElemToBytes(header.powSolution.pk)) shouldBe "03bedaee069ff4829500b3c07c4d5fe6b3ea3d3bf76c5c28c1d4dcdb1bed0ade0c"
-
- Base16.encode(header.powSolution.n) shouldBe "0000000000003105"
-
- pow.validate(header) shouldBe 'success
- }
-
- // testing an invalid header got from a mining pool
- property("test vector - invalid solution") {
- import io.circe.parser._
-
- val headerJson = "{\"extensionId\":\"277907e4e5e42f27e928e6101cc4fec173bee5d7728794b73d7448c339c380e5\",\"difficulty\":\"1325481984\",\"votes\":\"000000\",\"timestamp\":1611225263165,\"size\":219,\"stateRoot\":\"c0d0b5eafd07b22487dac66628669c42a242b90bef3e1fcdc76d83140d58b6bc0e\",\"height\":2870,\"nBits\":72286528,\"version\":2,\"id\":\"5b0ce6711de6b926f60b67040cc4512804517785df375d063f1bf1d75588af3a\",\"adProofsRoot\":\"49453875a43035c7640dee2f905efe06128b00d41acd2c8df13691576d4fd85c\",\"transactionsRoot\":\"770cbb6e18673ed025d386487f15d3252115d9a6f6c9b947cf3d04731dd6ab75\",\"extensionHash\":\"9bc7d54583c5d44bb62a7be0473cd78d601822a626afc13b636f2cbff0d87faf\",\"powSolutions\":{\"pk\":\"0288114b0586efea9f86e4587f2071bc1c85fb77e15eba96b2769733e0daf57903\",\"w\":\"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"n\":\"000100000580a91b\",\"d\":0},\"adProofsId\":\"4fc36d59bf26a672e01fbfde1445bd66f50e0f540f24102e1e27d0be1a99dfbf\",\"transactionsId\":\"d196ef8a7ef582ab1fdab4ef807715183705301c6ae2ff0dcbe8f1d577ba081f\",\"parentId\":\"ab19e6c7a4062979dddb534df83f236d1b949c7cef18bcf434a67e87c593eef9\"}"
-
- val json = parse(headerJson).toOption.get
-
- val header = Header.jsonDecoder.decodeJson(json).toOption.get
-
- val pow = new AutolykosPowScheme(32, 26)
-
- pow.validate(header).isSuccess shouldBe false
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/mining/CandidateGeneratorPropSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/mining/CandidateGeneratorPropSpec.scala
deleted file mode 100644
index 1c666e18e4..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/mining/CandidateGeneratorPropSpec.scala
+++ /dev/null
@@ -1,289 +0,0 @@
-package org.ergoplatform.mining
-
-import org.ergoplatform.ErgoTreePredef
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.state.ErgoStateContext
-import org.ergoplatform.settings.MonetarySettings
-import org.ergoplatform.utils.{ErgoPropertyTest, RandomWrapper}
-import org.ergoplatform.wallet.interpreter.ErgoInterpreter
-import org.scalacheck.Gen
-import sigmastate.crypto.DLogProtocol.ProveDlog
-
-import scala.concurrent.duration._
-
-class CandidateGeneratorPropSpec extends ErgoPropertyTest {
-
- val delta: Int = settings.chainSettings.monetary.minerRewardDelay
-
- private def expectedRewardOutputScriptBytes(pk: ProveDlog): Array[Byte] =
- ErgoTreePredef.rewardOutputScript(delta, pk).bytes
-
- implicit private val verifier: ErgoInterpreter = ErgoInterpreter(parameters)
-
- property("minersRewardAtHeight test vectors") {
- emission.minersRewardAtHeight(525000) shouldBe 67500000000L
- emission.minersRewardAtHeight(525600) shouldBe 67500000000L
- emission.minersRewardAtHeight(590400) shouldBe 67500000000L
- emission.minersRewardAtHeight(655200) shouldBe 66000000000L
- emission.minersRewardAtHeight(720000) shouldBe 63000000000L
- emission.minersRewardAtHeight(784800) shouldBe 60000000000L
- emission.minersRewardAtHeight(849600) shouldBe 57000000000L
- emission.minersRewardAtHeight(914400) shouldBe 54000000000L
- emission.minersRewardAtHeight(979200) shouldBe 51000000000L
- emission.minersRewardAtHeight(1044000) shouldBe 48000000000L
- emission.minersRewardAtHeight(1108800) shouldBe 45000000000L
- emission.minersRewardAtHeight(1173600) shouldBe 42000000000L
- emission.minersRewardAtHeight(1238400) shouldBe 39000000000L
- emission.minersRewardAtHeight(1303200) shouldBe 36000000000L
- emission.minersRewardAtHeight(1368000) shouldBe 33000000000L
- emission.minersRewardAtHeight(1432800) shouldBe 30000000000L
- emission.minersRewardAtHeight(1497600) shouldBe 27000000000L
- emission.minersRewardAtHeight(1562400) shouldBe 24000000000L
- emission.minersRewardAtHeight(1627200) shouldBe 21000000000L
- emission.minersRewardAtHeight(1692000) shouldBe 18000000000L
- emission.minersRewardAtHeight(1756800) shouldBe 15000000000L
- emission.minersRewardAtHeight(1821600) shouldBe 12000000000L
- emission.minersRewardAtHeight(1886400) shouldBe 9000000000L
- emission.minersRewardAtHeight(1951200) shouldBe 6000000000L
- emission.minersRewardAtHeight(2016000) shouldBe 3000000000L
- emission.minersRewardAtHeight(2080799) shouldBe 3000000000L
- emission.minersRewardAtHeight(2080800) shouldBe 0L
- }
-
- property("collect reward from emission box only") {
- val us = createUtxoState(settings)._1
- us.emissionBoxOpt should not be None
- val expectedReward = emission.minersRewardAtHeight(us.stateContext.currentHeight)
-
- val incorrectTxs =
- CandidateGenerator.collectEmission(us, proveDlogGen.sample.get, emptyStateContext).toSeq
- val txs = CandidateGenerator.collectEmission(us, defaultMinerPk, emptyStateContext).toSeq
-
- txs.size shouldBe 1
- val emissionTx = txs.head
- emissionTx.outputs.length shouldBe 2
- emissionTx.outputs.last.value shouldBe expectedReward
- emissionTx.outputs.last.propositionBytes shouldEqual expectedRewardOutputScriptBytes(
- defaultMinerPk
- )
-
- us.applyModifier(validFullBlock(None, us, incorrectTxs), None)(_ => ()) shouldBe 'failure
- us.applyModifier(validFullBlock(None, us, txs), None)(_ => ()) shouldBe 'success
- }
-
- property("collect reward from transaction fees only") {
- val bh = boxesHolderGen.sample.get
- val us = createUtxoState(bh, parameters)
- val height = us.stateContext.currentHeight
- val blockTx = validTransactionFromBoxes(
- bh.boxes.take(2).values.toIndexedSeq,
- outputsProposition = feeProp
- )
-
- val txs =
- CandidateGenerator.collectFees(height, Seq(blockTx), defaultMinerPk, emptyStateContext).toSeq
- val incorrect = CandidateGenerator
- .collectFees(height, Seq(blockTx), proveDlogGen.sample.get, emptyStateContext)
- .toSeq
- txs.length shouldBe 1
- val feeTx = txs.head
- feeTx.outputs.length shouldBe 1
- feeTx.outputs.head.value shouldBe txs.flatMap(_.outputs).map(_.value).sum
- feeTx.outputs.head.propositionBytes shouldEqual expectedRewardOutputScriptBytes(
- defaultMinerPk
- )
-
- us.applyModifier(validFullBlock(None, us, blockTx +: incorrect), None)(_ => ()) shouldBe 'failure
- us.applyModifier(validFullBlock(None, us, blockTx +: txs), None)(_ => ()) shouldBe 'success
- }
-
- property("filter out double spend txs") {
- val tx = validErgoTransactionGen.sample.get._2
- CandidateGenerator.doublespend(Seq(tx), tx) shouldBe true
-
- val inputs = validErgoTransactionGenTemplate(minAssets = 0, maxAssets = -1).sample.get._1
- val (l, r) = inputs.splitAt(50)
- val tx_1 = validTransactionFromBoxes(l)
- val tx_2 = validTransactionFromBoxes(r :+ l.last) //conflicting with tx_1
- val tx_3 = validTransactionFromBoxes(r) //conflicting with tx_2, not conflicting with tx_1
-
- CandidateGenerator.doublespend(Seq(tx_1), tx_2) shouldBe true
- CandidateGenerator.doublespend(Seq(tx_1), tx_3) shouldBe false
- CandidateGenerator.doublespend(Seq(tx_1, tx_2), tx_1) shouldBe true
- CandidateGenerator.doublespend(Seq(tx_1, tx_2), tx_2) shouldBe true
- CandidateGenerator.doublespend(Seq(tx_1, tx_3), tx) shouldBe false
- }
-
- property("should only collect valid transactions") {
- def checkCollectTxs(
- maxCost: Int,
- maxSize: Int,
- withTokens: Boolean = false
- ): Unit = {
-
- val bh = boxesHolderGen.sample.get
- val rnd = new RandomWrapper
- val us = createUtxoState(bh, parameters)
- val inputs = bh.boxes.values.toIndexedSeq.takeRight(100)
- val txsWithFees = inputs.map(i =>
- validTransactionFromBoxes(IndexedSeq(i), rnd, issueNew = withTokens, feeProp)
- )
- val head = txsWithFees.head
-
- val h = validFullBlock(None, us, bh, rnd).header
- val upcomingContext = us.stateContext.upcoming(
- h.minerPk,
- h.timestamp,
- h.nBits,
- h.votes,
- emptyVSUpdate,
- h.version
- )
- upcomingContext.currentHeight shouldBe (us.stateContext.currentHeight + 1)
-
- val fromSmallMempool = CandidateGenerator
- .collectTxs(
- defaultMinerPk,
- maxCost,
- maxSize,
- us,
- upcomingContext,
- Seq(head)
- )
- ._1
- fromSmallMempool.size shouldBe 2
- fromSmallMempool.contains(head) shouldBe true
-
- val fromBigMempool = CandidateGenerator
- .collectTxs(
- defaultMinerPk,
- maxCost,
- maxSize,
- us,
- upcomingContext,
- txsWithFees
- )
- ._1
-
- val newBoxes = fromBigMempool.flatMap(_.outputs)
- val costs: Seq[Int] = fromBigMempool.map { tx =>
- us.validateWithCost(tx, upcomingContext, Int.MaxValue, Some(verifier)).getOrElse {
- val boxesToSpend =
- tx.inputs.map(i => newBoxes.find(b => b.id sameElements i.boxId).get)
- tx.statefulValidity(boxesToSpend, IndexedSeq(), upcomingContext).get
- }
- }
-
- fromBigMempool.length should be > 2
- fromBigMempool.map(_.size).sum should be < maxSize
- costs.sum should be < maxCost
- if (!withTokens) fromBigMempool.size should be < txsWithFees.size
- }
-
- // transactions reach computation cost block limit
- checkCollectTxs(parameters.maxBlockCost, Int.MaxValue)
-
- // transactions reach block size limit
- checkCollectTxs(Int.MaxValue, 4096)
-
- // miner collects correct transactions from mempool even if they have tokens
- checkCollectTxs(Int.MaxValue, Int.MaxValue, withTokens = true)
-
- }
-
- property("should not be able to spend recent fee boxes") {
-
- val delta = 1
- val inputsNum = 2
- val feeProposition = ErgoTreePredef.feeProposition(delta)
-
- val bh = boxesHolderGen.sample.get
- var us = createUtxoState(bh, parameters)
- val height = ErgoHistory.EmptyHistoryHeight
-
- val ms = MonetarySettings(minerRewardDelay = delta)
- val st = settings.copy(chainSettings = settings.chainSettings.copy(monetary = ms))
- val sc = ErgoStateContext.empty(genesisStateDigest, st, parameters)
- val txBoxes = bh.boxes.grouped(inputsNum).map(_.values.toIndexedSeq).toSeq
-
- val blockTx =
- validTransactionFromBoxes(txBoxes.head, outputsProposition = feeProposition)
- val txs = CandidateGenerator
- .collectFees(height, Seq(blockTx), defaultMinerPk, sc)
- .toSeq
- val block = validFullBlock(None, us, blockTx +: txs)
-
- us = us.applyModifier(block, None)(_ => ()).get
-
- val blockTx2 =
- validTransactionFromBoxes(txBoxes(1), outputsProposition = feeProposition)
- val block2 = validFullBlock(Some(block), us, IndexedSeq(blockTx2))
-
- val earlySpendingTx =
- validTransactionFromBoxes(txs.head.outputs, stateCtxOpt = Some(us.stateContext))
-
- val invalidBlock2 =
- validFullBlock(Some(block), us, IndexedSeq(earlySpendingTx, blockTx2))
-
- us.applyModifier(invalidBlock2, None)(_ => ()) shouldBe 'failure
-
- us = us.applyModifier(block2, None)(_ => ()).get
-
- val earlySpendingTx2 =
- validTransactionFromBoxes(txs.head.outputs, stateCtxOpt = Some(us.stateContext))
-
- val blockTx3 =
- validTransactionFromBoxes(txBoxes(2), outputsProposition = feeProposition)
- val block3 = validFullBlock(Some(block2), us, IndexedSeq(earlySpendingTx2, blockTx3))
-
- us.applyModifier(block3, None)(_ => ()) shouldBe 'success
- }
-
- property("collect reward from both emission box and fees") {
- val (us, _) = createUtxoState(settings)
- us.emissionBoxOpt should not be None
- val expectedReward = emission.minersRewardAtHeight(us.stateContext.currentHeight)
-
- forAll(
- Gen.nonEmptyListOf(validErgoTransactionGenTemplate(minAssets = 0, propositionGen = feeProp))
- ) { btxs =>
- val blockTxs = btxs.map(_._2)
- val height = ErgoHistory.EmptyHistoryHeight
- val txs = CandidateGenerator.collectRewards(
- us.emissionBoxOpt,
- height,
- blockTxs,
- defaultMinerPk,
- emptyStateContext
- )
- txs.length shouldBe 2
-
- val emissionTx = txs.head
- emissionTx.outputs.length shouldBe 2
- emissionTx.outputs.last.value shouldBe expectedReward
- emissionTx.outputs.last.propositionBytes shouldEqual expectedRewardOutputScriptBytes(
- defaultMinerPk
- )
-
- val feeTx = txs.last
- feeTx.outputs.length shouldBe 1
- feeTx.outputs.head.value shouldBe blockTxs.flatMap(_.outputs).map(_.value).sum
- feeTx.outputs.head.propositionBytes shouldEqual expectedRewardOutputScriptBytes(
- defaultMinerPk
- )
- }
- }
-
- property("it should calculate average block mining time from creation timestamps") {
- val timestamps1 = System.currentTimeMillis()
- val timestamps2 = timestamps1 + 100
- val timestamps3 = timestamps2 + 200
- val timestamps4 = timestamps3 + 300
- val avgMiningTime = {
- CandidateGenerator.getBlockMiningTimeAvg(
- Vector(timestamps1, timestamps2, timestamps3, timestamps4)
- )
- }
- avgMiningTime shouldBe 200.millis
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala
deleted file mode 100644
index 148d5ebffb..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala
+++ /dev/null
@@ -1,258 +0,0 @@
-package org.ergoplatform.mining
-
-import akka.actor.{ActorRef, ActorSystem}
-import akka.pattern.{StatusReply, ask}
-import akka.testkit.{TestKit, TestProbe}
-import akka.util.Timeout
-import org.bouncycastle.util.BigIntegers
-import org.ergoplatform.mining.CandidateGenerator.{Candidate, GenerateCandidate}
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.FullBlockApplied
-import org.ergoplatform.nodeView.ErgoReadersHolder.{GetReaders, Readers}
-import org.ergoplatform.nodeView.history.ErgoHistoryReader
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.nodeView.{ErgoNodeViewRef, ErgoReadersHolderRef}
-import org.ergoplatform.settings.ErgoSettings
-import org.ergoplatform.utils.ErgoTestHelpers
-import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, ErgoTreePredef, Input}
-import org.scalatest.concurrent.Eventually
-import org.scalatest.flatspec.AnyFlatSpec
-import sigmastate.crypto.DLogProtocol
-import sigmastate.crypto.DLogProtocol.DLogProverInput
-
-import scala.concurrent.duration._
-
-class CandidateGeneratorSpec extends AnyFlatSpec with ErgoTestHelpers with Eventually {
-
- implicit private val timeout: Timeout = defaultTimeout
-
- private val newBlockSignal: Class[FullBlockApplied] = classOf[FullBlockApplied]
- private val newBlockDelay: FiniteDuration = 30.seconds
- private val candidateGenDelay: FiniteDuration = 3.seconds
- private val blockValidationDelay: FiniteDuration = 2.seconds
-
- val defaultSettings: ErgoSettings = {
- val empty = ErgoSettings.read()
- val nodeSettings = empty.nodeSettings.copy(
- mining = true,
- stateType = StateType.Utxo,
- internalMinerPollingInterval = 1.second,
- offlineGeneration = true,
- verifyTransactions = true
- )
- val chainSettings = empty.chainSettings.copy(blockInterval = 1.seconds)
- empty.copy(nodeSettings = nodeSettings, chainSettings = chainSettings)
- }
-
- it should "provider candidate to internal miner and verify and apply his solution" in new TestKit(
- ActorSystem()
- ) {
- val testProbe = new TestProbe(system)
- system.eventStream.subscribe(testProbe.ref, newBlockSignal)
-
- val viewHolderRef: ActorRef = ErgoNodeViewRef(defaultSettings)
- val readersHolderRef: ActorRef = ErgoReadersHolderRef(viewHolderRef)
-
- val candidateGenerator: ActorRef =
- CandidateGenerator(
- defaultMinerSecret.publicImage,
- readersHolderRef,
- viewHolderRef,
- defaultSettings
- )
- ErgoMiningThread(defaultSettings, candidateGenerator, defaultMinerSecret.w)
-
- // after applying solution from miner
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- system.terminate()
- }
-
- it should "let multiple miners compete" in new TestKit(ActorSystem()) {
- val testProbe = new TestProbe(system)
- system.eventStream.subscribe(testProbe.ref, newBlockSignal)
-
- val viewHolderRef: ActorRef = ErgoNodeViewRef(defaultSettings)
- val readersHolderRef: ActorRef = ErgoReadersHolderRef(viewHolderRef)
-
- val candidateGenerator: ActorRef =
- CandidateGenerator(
- defaultMinerSecret.publicImage,
- readersHolderRef,
- viewHolderRef,
- defaultSettings
- )
-
- val m1 = ErgoMiningThread(defaultSettings, candidateGenerator, defaultMinerSecret.w)
- val m2 = ErgoMiningThread(defaultSettings, candidateGenerator, defaultMinerSecret.w)
- val m3 = ErgoMiningThread(defaultSettings, candidateGenerator, defaultMinerSecret.w)
-
- // after applying solution from miner
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
-
- m1.tell(ErgoMiningThread.GetSolvedBlocksCount, testProbe.ref)
-
- val m1Count =
- testProbe.expectMsgClass(50.millis, classOf[ErgoMiningThread.SolvedBlocksCount])
- m2.tell(ErgoMiningThread.GetSolvedBlocksCount, testProbe.ref)
-
- val m2Count =
- testProbe.expectMsgClass(50.millis, classOf[ErgoMiningThread.SolvedBlocksCount])
- m3.tell(ErgoMiningThread.GetSolvedBlocksCount, testProbe.ref)
-
- val m3Count =
- testProbe.expectMsgClass(50.millis, classOf[ErgoMiningThread.SolvedBlocksCount])
-
- List(m1Count, m2Count, m3Count).map(_.count).sum should be >= 3
- system.terminate()
- }
-
- it should "cache candidate until newly mined block is applied" in new TestKit(
- ActorSystem()
- ) {
- val testProbe = new TestProbe(system)
- system.eventStream.subscribe(testProbe.ref, newBlockSignal)
-
- val viewHolderRef: ActorRef = ErgoNodeViewRef(defaultSettings)
- val readersHolderRef: ActorRef = ErgoReadersHolderRef(viewHolderRef)
-
- val candidateGenerator: ActorRef =
- CandidateGenerator(
- defaultMinerSecret.publicImage,
- readersHolderRef,
- viewHolderRef,
- defaultSettings
- )
-
- expectNoMessage(1.second)
- candidateGenerator.tell(GenerateCandidate(Seq.empty, reply = true), testProbe.ref)
-
- val block = testProbe.expectMsgPF(candidateGenDelay) {
- case StatusReply.Success(candidate: Candidate) =>
- defaultSettings.chainSettings.powScheme
- .proveCandidate(candidate.candidateBlock, defaultMinerSecret.w, 0, 1000)
- .get
- }
-
- // now block should be cached
- (0 to 20).foreach { _ =>
- candidateGenerator.tell(GenerateCandidate(Seq.empty, reply = true), testProbe.ref)
- testProbe.expectMsgClass(5.millis, classOf[StatusReply[_]])
- }
-
- candidateGenerator.tell(block.header.powSolution, testProbe.ref)
- testProbe.expectMsg(blockValidationDelay, StatusReply.success(()))
- // after applying solution
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- system.terminate()
- }
-
- it should "pool transactions should be removed from pool when block is mined" in new TestKit(
- ActorSystem()
- ) {
- val testProbe = new TestProbe(system)
- system.eventStream.subscribe(testProbe.ref, newBlockSignal)
- val viewHolderRef: ActorRef = ErgoNodeViewRef(defaultSettings)
- val readersHolderRef: ActorRef = ErgoReadersHolderRef(viewHolderRef)
-
- val candidateGenerator: ActorRef =
- CandidateGenerator(
- defaultMinerSecret.publicImage,
- readersHolderRef,
- viewHolderRef,
- defaultSettings
- )
-
- val readers: Readers = await((readersHolderRef ? GetReaders).mapTo[Readers])
-
- val history: ErgoHistoryReader = readers.h
- val startBlock: Option[Header] = history.bestHeaderOpt
-
- // generate block to use reward as our tx input
- candidateGenerator.tell(GenerateCandidate(Seq.empty, reply = true), testProbe.ref)
- testProbe.expectMsgPF(candidateGenDelay) {
- case StatusReply.Success(candidate: Candidate) =>
- val block = defaultSettings.chainSettings.powScheme
- .proveCandidate(candidate.candidateBlock, defaultMinerSecret.w, 0, 1000)
- .get
- // let's pretend we are mining at least a bit so it is realistic
- expectNoMessage(200.millis)
- candidateGenerator.tell(block.header.powSolution, testProbe.ref)
-
- // we fish either for ack or SSM as the order is non-deterministic
- testProbe.fishForMessage(blockValidationDelay) {
- case StatusReply.Success(()) =>
- testProbe.expectMsgPF(candidateGenDelay) {
- case FullBlockApplied(header) if header.id != block.header.parentId =>
- }
- true
- case FullBlockApplied(header) if header.id != block.header.parentId =>
- testProbe.expectMsg(StatusReply.Success(()))
- true
- }
- }
-
- // build new transaction that uses miner's reward as input
- val prop: DLogProtocol.ProveDlog =
- DLogProverInput(BigIntegers.fromUnsignedByteArray("test".getBytes())).publicImage
- val newlyMinedBlock = readers.h.bestFullBlockOpt.get
- val rewardBox: ErgoBox = newlyMinedBlock.transactions.last.outputs.last
- rewardBox.propositionBytes shouldBe ErgoTreePredef
- .rewardOutputScript(emission.settings.minerRewardDelay, defaultMinerPk)
- .bytes
- val input = Input(rewardBox.id, emptyProverResult)
-
- val outputs = IndexedSeq(
- new ErgoBoxCandidate(rewardBox.value, prop, readers.s.stateContext.currentHeight)
- )
- val unsignedTx = new UnsignedErgoTransaction(IndexedSeq(input), IndexedSeq(), outputs)
-
- val tx = ErgoTransaction(
- defaultProver
- .sign(unsignedTx, IndexedSeq(rewardBox), IndexedSeq(), readers.s.stateContext)
- .get
- )
-
- testProbe.expectNoMessage(200.millis)
- // mine a block with that transaction
- candidateGenerator.tell(GenerateCandidate(Seq(tx), reply = true), testProbe.ref)
- testProbe.expectMsgPF(candidateGenDelay) {
- case StatusReply.Success(candidate: Candidate) =>
- val block = defaultSettings.chainSettings.powScheme
- .proveCandidate(candidate.candidateBlock, defaultMinerSecret.w, 0, 1000)
- .get
- testProbe.expectNoMessage(200.millis)
- candidateGenerator.tell(block.header.powSolution, testProbe.ref)
-
- // we fish either for ack or SSM as the order is non-deterministic
- testProbe.fishForMessage(blockValidationDelay) {
- case StatusReply.Success(()) =>
- testProbe.expectMsgPF(candidateGenDelay) {
- case FullBlockApplied(header) if header.id != block.header.parentId =>
- }
- true
- case FullBlockApplied(header) if header.id != block.header.parentId =>
- testProbe.expectMsg(StatusReply.Success(()))
- true
- }
- }
-
- // new transaction should be cleared from pool after applying new block
- await((readersHolderRef ? GetReaders).mapTo[Readers]).m.size shouldBe 0
-
- // validate total amount of transactions created
- val blocks: IndexedSeq[ErgoFullBlock] = readers.h
- .chainToHeader(startBlock, readers.h.bestHeaderOpt.get)
- ._2
- .headers
- .flatMap(readers.h.getFullBlock)
- val txs: Seq[ErgoTransaction] = blocks.flatMap(_.blockTransactions.transactions)
- txs should have length 3 // 2 rewards and one regular tx
- system.terminate()
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/mining/ErgoMinerSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/mining/ErgoMinerSpec.scala
deleted file mode 100644
index 25258277e3..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/mining/ErgoMinerSpec.scala
+++ /dev/null
@@ -1,432 +0,0 @@
-package org.ergoplatform.mining
-
-import akka.actor.{ActorRef, ActorSystem}
-import akka.pattern.{StatusReply, ask}
-import akka.testkit.{TestKit, TestProbe}
-import akka.util.Timeout
-import org.bouncycastle.util.BigIntegers
-import org.ergoplatform.mining.CandidateGenerator.{Candidate, GenerateCandidate}
-import org.ergoplatform.mining.ErgoMiner.StartMining
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction, UnsignedErgoTransaction}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.FullBlockApplied
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedTransaction
-import org.ergoplatform.nodeView.ErgoReadersHolder.{GetReaders, Readers}
-import org.ergoplatform.nodeView.history.ErgoHistoryReader
-import org.ergoplatform.nodeView.state._
-import org.ergoplatform.nodeView.wallet._
-import org.ergoplatform.nodeView.{ErgoNodeViewRef, ErgoReadersHolderRef}
-import org.ergoplatform.settings.ErgoSettings
-import org.ergoplatform.utils.ErgoTestHelpers
-import org.ergoplatform.utils.generators.ValidBlocksGenerators
-import org.ergoplatform.wallet.interpreter.ErgoInterpreter
-import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, ErgoTreePredef, Input}
-import org.scalatest.concurrent.Eventually
-import org.scalatest.flatspec.AnyFlatSpec
-import sigmastate.SigmaAnd
-import sigmastate.Values.{ErgoTree, SigmaPropConstant}
-import sigmastate.crypto.DLogProtocol
-import sigmastate.crypto.DLogProtocol.DLogProverInput
-
-import scala.annotation.tailrec
-import scala.concurrent.ExecutionContext.Implicits.global
-import scala.concurrent.duration._
-import scala.language.postfixOps
-
-class ErgoMinerSpec extends AnyFlatSpec with ErgoTestHelpers with ValidBlocksGenerators with Eventually {
-
- implicit private val timeout: Timeout = defaultTimeout
-
- private val newBlockSignal: Class[FullBlockApplied] = classOf[FullBlockApplied]
- private val newBlockDelay: FiniteDuration = 30 seconds
- private val candidateGenDelay: FiniteDuration = 3.seconds
- private val blockValidationDelay: FiniteDuration = 2.seconds
-
- private def getWorkMessage(minerRef: ActorRef, mandatoryTransactions: Seq[ErgoTransaction]): WorkMessage =
- await(minerRef.askWithStatus(GenerateCandidate(mandatoryTransactions, reply = true)).mapTo[Candidate].map(_.externalVersion))
-
- val defaultSettings: ErgoSettings = {
- val empty = ErgoSettings.read()
-
- val nodeSettings = empty.nodeSettings.copy(mining = true,
- stateType = StateType.Utxo,
- internalMinerPollingInterval = 2.second,
- maxTransactionCost = 100000,
- offlineGeneration = true,
- verifyTransactions = true)
- val chainSettings = empty.chainSettings.copy(blockInterval = 2.seconds)
- empty.copy(nodeSettings = nodeSettings, chainSettings = chainSettings)
- }
-
- it should "not include too costly transactions" in new TestKit(ActorSystem()) {
- val testProbe = new TestProbe(system)
- system.eventStream.subscribe(testProbe.ref, newBlockSignal)
- val ergoSettings: ErgoSettings = defaultSettings.copy(directory = createTempDir.getAbsolutePath)
- val complexScript: ErgoTree = (0 until 100).foldLeft(SigmaAnd(SigmaPropConstant(defaultMinerPk), SigmaPropConstant(defaultMinerPk))) { (l, _) =>
- SigmaAnd(SigmaPropConstant(defaultMinerPk), l)
- }
- complexScript.complexity shouldBe 28077
-
- val nodeViewHolderRef: ActorRef = ErgoNodeViewRef(ergoSettings)
- val readersHolderRef: ActorRef = ErgoReadersHolderRef(nodeViewHolderRef)
-
- val minerRef: ActorRef = ErgoMiner(
- ergoSettings,
- nodeViewHolderRef,
- readersHolderRef,
- Some(defaultMinerSecret)
- )
- expectNoMessage(1 second)
- val r: Readers = await((readersHolderRef ? GetReaders).mapTo[Readers])
-
- minerRef ! StartMining
-
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
-
- val boxToSpend: ErgoBox = r.h.bestFullBlockOpt.get.transactions.last.outputs.last
- boxToSpend.propositionBytes shouldBe ErgoTreePredef.rewardOutputScript(emission.settings.minerRewardDelay, defaultMinerPk).bytes
-
- val input = Input(boxToSpend.id, emptyProverResult)
-
- // create transaction with output with costly proposition
- val output = new ErgoBoxCandidate(boxToSpend.value / 10, complexScript, r.s.stateContext.currentHeight)
- val outputs = (0 until 10).map(_ => output)
- val unsignedTx = new UnsignedErgoTransaction(IndexedSeq(input), IndexedSeq(), outputs)
- val tx = defaultProver.sign(unsignedTx, IndexedSeq(boxToSpend), IndexedSeq(), r.s.stateContext).get
- nodeViewHolderRef ! LocallyGeneratedTransaction(UnconfirmedTransaction(ErgoTransaction(tx), None))
- expectNoMessage(1 seconds)
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- await((readersHolderRef ? GetReaders).mapTo[Readers]).m.size shouldBe 0
-
- //check that tx is included into UTXO set
- val state = await((readersHolderRef ? GetReaders).mapTo[Readers]).s.asInstanceOf[UtxoState]
- tx.outputs.foreach(o => state.boxById(o.id).get shouldBe o)
-
- // try to spend all the boxes with complex scripts
- val costlyInputs = tx.outputs.map(o => Input(o.id, emptyProverResult))
- val costlyOut = new ErgoBoxCandidate(tx.outputs.map(_.value).sum, complexScript, r.s.stateContext.currentHeight)
- val unsignedComplexTx = new UnsignedErgoTransaction(costlyInputs, IndexedSeq(), IndexedSeq(costlyOut))
- val costlyTx = defaultProver.sign(unsignedComplexTx, tx.outputs, IndexedSeq(), r.s.stateContext).get
-
- val txCost =
- state.validateWithCost(
- ErgoTransaction(costlyTx.inputs, costlyTx.dataInputs, costlyTx.outputCandidates),
- r.s.stateContext,
- costLimit = 440000,
- None
- ).get
- txCost shouldBe 439080
-
- // send costly transaction to the mempool
- nodeViewHolderRef ! LocallyGeneratedTransaction(UnconfirmedTransaction(ErgoTransaction(costlyTx), None))
-
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
-
- // costly tx was removed from mempool
- expectNoMessage(1 second)
- await((readersHolderRef ? GetReaders).mapTo[Readers]).m.size shouldBe 0
- // costly tx was not included
- val state2 = await((readersHolderRef ? GetReaders).mapTo[Readers]).s.asInstanceOf[UtxoState]
- tx.outputs.foreach(o => state2.boxById(o.id) should not be None)
- costlyTx.outputs.foreach(o => state2.boxById(o.id) shouldBe None)
- }
-
- it should "not freeze while mempool is full" in new TestKit(ActorSystem()) {
- // generate amount of transactions, twice more than can fit in one block
- val desiredSize: Int = Math.ceil((parameters.maxBlockCost / ErgoInterpreter.interpreterInitCost) * 1.2).toInt
- val ergoSettings: ErgoSettings = defaultSettings.copy(directory = createTempDir.getAbsolutePath)
-
- val testProbe = new TestProbe(system)
- system.eventStream.subscribe(testProbe.ref, newBlockSignal)
-
- val nodeViewHolderRef: ActorRef = ErgoNodeViewRef(ergoSettings)
- val readersHolderRef: ActorRef = ErgoReadersHolderRef(nodeViewHolderRef)
- expectNoMessage(1 second)
- val r: Readers = requestReaders
- val wallet: ErgoWalletReader = r.w
-
- val minerRef: ActorRef = ErgoMiner(
- ergoSettings,
- nodeViewHolderRef,
- readersHolderRef,
- Some(defaultMinerSecret)
- )
- minerRef ! StartMining
-
- // wait for 1 block to be generated
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
-
- @tailrec
- def loop(toSend: Int): Unit = {
- val toSpend: Seq[ErgoBox] = await(
- wallet.walletBoxes(unspentOnly = false, considerUnconfirmed = false)
- ).map(_.trackedBox.box).toList
- log.debug(s"Generate more transactions from ${toSpend.length} boxes. $toSend remains," +
- s"pool size: ${requestReaders.m.size}")
- val txs: Seq[ErgoTransaction] = toSpend.take(toSend) map { boxToSend =>
- val inputs = IndexedSeq(Input(boxToSend.id, emptyProverResult))
-
- val feeBox = new ErgoBoxCandidate(boxToSend.value / desiredSize, feeProp, r.s.stateContext.currentHeight)
- val outputs = (1 until desiredSize).map { _ =>
- new ErgoBoxCandidate(boxToSend.value / desiredSize, defaultMinerPk, r.s.stateContext.currentHeight)
- }
- val unsignedTx = new UnsignedErgoTransaction(inputs, IndexedSeq(), feeBox +: outputs)
- ErgoTransaction(
- defaultProver.sign(
- unsignedTx,
- IndexedSeq(boxToSend),
- IndexedSeq(),
- r.s.stateContext
- ).get
- )
- }
-
- txs.map(tx => UnconfirmedTransaction(tx, None)).foreach(nodeViewHolderRef ! LocallyGeneratedTransaction(_))
-
- if (toSend > toSpend.size) {
- // wait for the next block
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- loop(toSend - toSpend.size)
- }
- }
-
- def requestReaders: Readers = await((readersHolderRef ? GetReaders).mapTo[Readers])
-
- // Generate and send `desiredSize` transactions to mempool
- loop(desiredSize)
-
- implicit val patienceConfig: PatienceConfig = PatienceConfig(10.second, 100.millis)
- eventually {
- requestReaders.m.size should be > 10
- }
-
- // wait for mempool to be cleaned
- scorex.core.utils.untilTimeout(5.minute, 500.millis) {
- log.debug(s"Wait until transactions in mempool will be included into blocks. Currents size: ${requestReaders.m.size}")
- requestReaders.m.size shouldBe 0
- system.terminate()
- }
- }
-
- it should "include only one transaction from 2 spending the same box" in new TestKit(ActorSystem()) {
- val testProbe = new TestProbe(system)
- system.eventStream.subscribe(testProbe.ref, newBlockSignal)
- val ergoSettings: ErgoSettings = defaultSettings.copy(directory = createTempDir.getAbsolutePath)
-
- val nodeViewHolderRef: ActorRef = ErgoNodeViewRef(ergoSettings)
- val readersHolderRef: ActorRef = ErgoReadersHolderRef(nodeViewHolderRef)
-
- val minerRef: ActorRef = ErgoMiner(
- ergoSettings,
- nodeViewHolderRef,
- readersHolderRef,
- Some(defaultMinerSecret)
- )
- expectNoMessage(1 second)
- val r: Readers = await((readersHolderRef ? GetReaders).mapTo[Readers])
-
- val history: ErgoHistoryReader = r.h
- val startBlock: Option[Header] = history.bestHeaderOpt
-
- minerRef ! StartMining
-
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
-
- val prop1: DLogProtocol.ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test1".getBytes())).publicImage
- val prop2: DLogProtocol.ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test2".getBytes())).publicImage
-
- val boxToDoubleSpend: ErgoBox = r.h.bestFullBlockOpt.get.transactions.last.outputs.last
- boxToDoubleSpend.propositionBytes shouldBe ErgoTreePredef.rewardOutputScript(emission.settings.minerRewardDelay, defaultMinerPk).bytes
-
- val input = Input(boxToDoubleSpend.id, emptyProverResult)
-
- val outputs1 = IndexedSeq(new ErgoBoxCandidate(boxToDoubleSpend.value, prop1, r.s.stateContext.currentHeight))
- val unsignedTx1 = new UnsignedErgoTransaction(IndexedSeq(input), IndexedSeq(), outputs1)
- val tx1 = defaultProver.sign(unsignedTx1, IndexedSeq(boxToDoubleSpend), IndexedSeq(), r.s.stateContext).get
- val outputs2 = IndexedSeq(new ErgoBoxCandidate(boxToDoubleSpend.value, prop2, r.s.stateContext.currentHeight))
- val unsignedTx2 = new UnsignedErgoTransaction(IndexedSeq(input), IndexedSeq(), outputs2)
- val tx2 = ErgoTransaction(defaultProver.sign(unsignedTx2, IndexedSeq(boxToDoubleSpend), IndexedSeq(), r.s.stateContext).get)
-
- // As double-spending transactions are filtered out in the mempool, the only way to push them is to order to
- // include double-spending transaction directly via mandatoryTransactions argument of PrepareCandidate command
- nodeViewHolderRef ! LocallyGeneratedTransaction(UnconfirmedTransaction(ErgoTransaction(tx1), None))
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
-
- testProbe.expectNoMessage(200.millis)
- minerRef.tell(GenerateCandidate(Seq(tx2), reply = true), testProbe.ref)
- testProbe.expectMsgPF(candidateGenDelay) {
- case StatusReply.Success(candidate: Candidate) =>
- val block = defaultSettings.chainSettings.powScheme
- .proveCandidate(candidate.candidateBlock, defaultMinerSecret.w, 0, 1000)
- .get
- testProbe.expectNoMessage(200.millis)
- minerRef.tell(block.header.powSolution, testProbe.ref)
-
- // we fish either for ack or SSM as the order is non-deterministic
- testProbe.fishForMessage(blockValidationDelay) {
- case StatusReply.Success(()) =>
- testProbe.expectMsgPF(candidateGenDelay) {
- case FullBlockApplied(header) if header.id != block.header.parentId =>
- }
- true
- case FullBlockApplied(header) if header.id != block.header.parentId =>
- testProbe.expectMsg(StatusReply.Success(()))
- true
- }
- }
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
-
- await((readersHolderRef ? GetReaders).mapTo[Readers]).m.size shouldBe 0
-
- val blocks: IndexedSeq[ErgoFullBlock] = r.h.chainToHeader(startBlock, r.h.bestHeaderOpt.get)._2.headers.flatMap(r.h.getFullBlock)
- val txs: Seq[ErgoTransaction] = blocks.flatMap(_.blockTransactions.transactions)
- //Make sure that only tx got into chain
- txs.filter(tx => tx.id == tx1.id || tx.id == tx2.id) should have length 1
- system.terminate()
- }
-
- it should "prepare external candidate" in new TestKit(ActorSystem()) {
- val ergoSettings: ErgoSettings = defaultSettings.copy(directory = createTempDir.getAbsolutePath)
-
- val nodeViewHolderRef: ActorRef = ErgoNodeViewRef(ergoSettings)
- val readersHolderRef: ActorRef = ErgoReadersHolderRef(nodeViewHolderRef)
-
- def minerRef: ActorRef = ErgoMiner(
- ergoSettings,
- nodeViewHolderRef,
- readersHolderRef,
- Some(defaultMinerSecret)
- )
-
- val passiveMiner: ActorRef = minerRef
- passiveMiner ! StartMining
-
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 200.millis) // it takes a while before PK is set
- eventually(await(passiveMiner.askWithStatus(GenerateCandidate(Seq.empty, reply = true)).mapTo[Candidate]))
- system.terminate()
- }
-
- it should "include mandatory transactions" in new TestKit(ActorSystem()) {
- val testProbe = new TestProbe(system)
- system.eventStream.subscribe(testProbe.ref, newBlockSignal)
- val ergoSettings: ErgoSettings = defaultSettings.copy(directory = createTempDir.getAbsolutePath)
-
- val nodeViewHolderRef: ActorRef = ErgoNodeViewRef(ergoSettings)
- val readersHolderRef: ActorRef = ErgoReadersHolderRef(nodeViewHolderRef)
-
- val minerRef: ActorRef = ErgoMiner(
- ergoSettings,
- nodeViewHolderRef,
- readersHolderRef,
- Some(defaultMinerSecret)
- )
- expectNoMessage(1 second)
- val r: Readers = await((readersHolderRef ? GetReaders).mapTo[Readers])
-
- minerRef ! StartMining
-
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
-
- val prop1: DLogProtocol.ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test1".getBytes())).publicImage
- val prop2: DLogProtocol.ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test2".getBytes())).publicImage
-
- val mBox: ErgoBox = r.h.bestFullBlockOpt.get.transactions.last.outputs.last
- val mInput = Input(mBox.id, emptyProverResult)
-
- val outputs1 = IndexedSeq(new ErgoBoxCandidate(mBox.value, prop1, r.s.stateContext.currentHeight))
- val unsignedTx1 = new UnsignedErgoTransaction(IndexedSeq(mInput), IndexedSeq(), outputs1)
- val mandatoryTxLike1 = defaultProver.sign(unsignedTx1, IndexedSeq(mBox), IndexedSeq(), r.s.stateContext).get
- val mandatoryTx1 = ErgoTransaction(mandatoryTxLike1)
-
- val outputs2 = IndexedSeq(new ErgoBoxCandidate(mBox.value, prop2, r.s.stateContext.currentHeight))
- val unsignedTx2 = new UnsignedErgoTransaction(IndexedSeq(mInput), IndexedSeq(), outputs2)
- val mandatoryTxLike2 = defaultProver.sign(unsignedTx2, IndexedSeq(mBox), IndexedSeq(), r.s.stateContext).get
- val mandatoryTx2 = ErgoTransaction(mandatoryTxLike2)
- mandatoryTx1.bytes.sameElements(mandatoryTx2.bytes) shouldBe false
-
- val ecb = getWorkMessage(minerRef, Seq.empty)
- ecb.proofsForMandatoryTransactions.isDefined shouldBe false
-
- val ecb1 = getWorkMessage(minerRef, Seq(mandatoryTx1))
- ecb1.proofsForMandatoryTransactions.get.txProofs.length shouldBe 1
- ecb1.proofsForMandatoryTransactions.get.check() shouldBe true
-
- val ecb2 = getWorkMessage(minerRef, Seq(mandatoryTx2))
- ecb2.msg.sameElements(ecb1.msg) shouldBe false
- ecb2.proofsForMandatoryTransactions.get.txProofs.length shouldBe 1
- ecb2.proofsForMandatoryTransactions.get.check() shouldBe true
-
- val ecb3 = getWorkMessage(minerRef, Seq.empty)
- ecb3.msg.sameElements(ecb2.msg) shouldBe true
- ecb3.proofsForMandatoryTransactions.get.txProofs.length shouldBe 1
- ecb3.proofsForMandatoryTransactions.get.check() shouldBe true
-
- system.terminate()
- }
-
- it should "mine after HF" in new TestKit(ActorSystem()) {
- val forkHeight = 3
-
- val testProbe = new TestProbe(system)
- system.eventStream.subscribe(testProbe.ref, newBlockSignal)
-
- val forkSettings: ErgoSettings = {
- val empty = ErgoSettings.read()
-
- val nodeSettings = empty.nodeSettings.copy(mining = true,
- stateType = StateType.Utxo,
- internalMinerPollingInterval = 2.second,
- offlineGeneration = true,
- verifyTransactions = true)
- val chainSettings = empty.chainSettings.copy(
- blockInterval = 2.seconds,
- epochLength = forkHeight,
- voting = empty.chainSettings.voting.copy(
- version2ActivationHeight = forkHeight,
- version2ActivationDifficultyHex = "10",
- votingLength = forkHeight)
- )
- empty.copy(nodeSettings = nodeSettings, chainSettings = chainSettings, directory = createTempDir.getAbsolutePath)
- }
-
- val nodeViewHolderRef: ActorRef = ErgoNodeViewRef(forkSettings)
- val readersHolderRef: ActorRef = ErgoReadersHolderRef(nodeViewHolderRef)
-
- val minerRef: ActorRef = ErgoMiner(
- forkSettings,
- nodeViewHolderRef,
- readersHolderRef,
- Some(defaultMinerSecret)
- )
-
- minerRef ! StartMining
-
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
-
- val wm1 = getWorkMessage(minerRef, Seq.empty)
- (wm1.h.get >= forkHeight) shouldBe true
-
- testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
- implicit val patienceConfig: PatienceConfig = PatienceConfig(1.seconds, 50.millis)
- eventually {
- val wm2 = getWorkMessage(minerRef, Seq.empty)
- (wm2.h.get >= forkHeight) shouldBe true
- wm1.msg.sameElements(wm2.msg) shouldBe false
-
- val v2Block = testProbe.expectMsgClass(newBlockDelay, newBlockSignal)
-
- val h2 = v2Block.header
- h2.version shouldBe 2
- h2.minerPk shouldBe defaultMinerPk.value
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/mining/difficulty/DifficultyAdjustmentSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/mining/difficulty/DifficultyAdjustmentSpecification.scala
deleted file mode 100644
index 6c7d6528bd..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/mining/difficulty/DifficultyAdjustmentSpecification.scala
+++ /dev/null
@@ -1,190 +0,0 @@
-package org.ergoplatform.mining.difficulty
-
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.settings.ChainSettings
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.scalacheck.{Arbitrary, Gen}
-
-import scala.concurrent.duration._
-import scala.util.Try
-
-class DifficultyAdjustmentSpecification extends ErgoPropertyTest {
-
- val precision = 0.0001
- val minDiff: BigInt = (BigDecimal(1) / precision).toBigInt()
- val Epoch = 123
-
- val UseLastEpochs = 4
- val DesiredInterval: FiniteDuration = 1.minute
-
- def chainSettings(blockInterval: FiniteDuration = DesiredInterval,
- useLastEpochs: Int = UseLastEpochs,
- epochLength: Int = Epoch): ChainSettings =
- settings.chainSettings.copy(blockInterval = blockInterval, useLastEpochs = useLastEpochs, epochLength = epochLength)
-
- val control = new DifficultyAdjustment(chainSettings())
-
- property("nextRecalculationHeight vectors") {
- val epochLength = 128
- control.nextRecalculationHeight(926976, epochLength) shouldBe 926977
- control.nextRecalculationHeight(926977, epochLength) shouldBe 927105
- control.nextRecalculationHeight(926975, epochLength) shouldBe 926977
- control.nextRecalculationHeight(926950, epochLength) shouldBe 926977
- control.nextRecalculationHeight(1, epochLength) shouldBe 129
- control.nextRecalculationHeight(129, epochLength) shouldBe 257
- control.nextRecalculationHeight(256, epochLength) shouldBe 257
- }
-
- property("heightsForNextRecalculation vectors") {
- val epochLength = 128
- control.heightsForNextRecalculation(926976, epochLength) shouldBe Seq(926464, 926592, 926720, 926848, 926976)
- control.heightsForNextRecalculation(926977, epochLength) shouldBe Seq(926592, 926720, 926848, 926976, 927104)
- control.heightsForNextRecalculation(926975, epochLength) shouldBe Seq(926464, 926592, 926720, 926848, 926976)
- control.heightsForNextRecalculation(926950, epochLength) shouldBe Seq(926464, 926592, 926720, 926848, 926976)
- control.heightsForNextRecalculation(1, epochLength) shouldBe Seq(0, 128)
- control.heightsForNextRecalculation(129, epochLength) shouldBe Seq(0, 128, 256)
- control.heightsForNextRecalculation(256, epochLength) shouldBe Seq(0, 128, 256)
- }
-
- property("previousHeadersRequiredForRecalculation() should return correct heights required for recalculation") {
- val height = Epoch * (UseLastEpochs + 1) + 1
- control.previousHeightsRequiredForRecalculation(height, Epoch) shouldEqual
- Seq(height - 4 * Epoch - 1, height - 3 * Epoch - 1, height - 2 * Epoch - 1, height - Epoch - 1, height - 1)
- }
-
- property("previousHeadersRequiredForRecalculation() with Epoch = 1") {
- forAll(Gen.choose(2, 1000)) { _ =>
- val useLastEpochs = 3
- val epochLength = 1
- val control = new DifficultyAdjustment(chainSettings(1.minute, useLastEpochs, epochLength))
- val height = useLastEpochs + 1
- control.previousHeightsRequiredForRecalculation(height, epochLength) shouldEqual (0 until height)
- }
- }
-
- property("previousHeadersRequiredForRecalculation() should return previous block if there should not be difficulty recalculation") {
- control.previousHeightsRequiredForRecalculation(Epoch / 2 + 1, Epoch) shouldBe Seq(Epoch / 2)
- control.previousHeightsRequiredForRecalculation(Epoch * UseLastEpochs, Epoch) shouldBe Seq(Epoch * UseLastEpochs - 1)
- control.previousHeightsRequiredForRecalculation(Epoch * UseLastEpochs + 2, Epoch) shouldBe Seq(Epoch * UseLastEpochs + 1)
- }
-
- property("previousHeadersRequiredForRecalculation() should return as much block heights as possible") {
- control.previousHeightsRequiredForRecalculation(Epoch + 1, Epoch) shouldBe Seq(0, Epoch)
- control.previousHeightsRequiredForRecalculation(2 * Epoch + 1, Epoch) shouldBe Seq(0, Epoch, 2 * Epoch)
- control.previousHeightsRequiredForRecalculation(3 * Epoch + 1, Epoch) shouldBe Seq(0, Epoch, 2 * Epoch, 3 * Epoch)
- control.previousHeightsRequiredForRecalculation(4 * Epoch + 1, Epoch) shouldBe Seq(0, Epoch, 2 * Epoch, 3 * Epoch, 4 * Epoch)
- control.previousHeightsRequiredForRecalculation(5 * Epoch + 1, Epoch) shouldBe Seq(Epoch, 2 * Epoch, 3 * Epoch, 4 * Epoch, 5 * Epoch)
- }
-
- property("previousHeadersRequiredForRecalculation() should generate valid heights for calculate()") {
- forAll(Gen.choose(1, Int.MaxValue), defaultHeaderGen) { (height: Int, header: Header) =>
- val previousHeaders = control.previousHeightsRequiredForRecalculation(height, Epoch)
- .map(i => header.copy(timestamp = header.timestamp + i, height = i))
-
- Try(control.calculate(previousHeaders, Epoch)) shouldBe 'success
- }
- }
-
-
- property("calculate() should require correct heights") {
- forAll(Gen.choose(UseLastEpochs, 10 * UseLastEpochs), defaultHeaderGen) { (i: Int, header: Header) =>
- val previousHeaders = control.previousHeightsRequiredForRecalculation(i * Epoch + 1, Epoch)
- .map(i => header.copy(timestamp = header.timestamp + i, height = i))
- previousHeaders.length shouldBe UseLastEpochs + 1
-
- Try(control.calculate(previousHeaders, Epoch)) shouldBe 'success
- Try(control.calculate(previousHeaders.map(h => h.copy(height = h.height * 2)), Epoch)) shouldBe 'failure
- }
- }
-
- property("calculate() should decrease difficulty if block time interval is higher than expected") {
- forAll(Gen.choose(UseLastEpochs, 10 * UseLastEpochs), defaultHeaderGen) { (startEpoch: Int, header: Header) =>
- whenever(header.requiredDifficulty > 10) {
- val previousHeaders = control.previousHeightsRequiredForRecalculation(startEpoch * Epoch + 1, Epoch)
- .map(i => header.copy(timestamp = header.timestamp + DesiredInterval.toMillis * 2 * i, height = i))
- previousHeaders.length shouldBe UseLastEpochs + 1
-
- control.calculate(previousHeaders, Epoch) < header.requiredDifficulty shouldBe true
- }
- }
- }
-
-
- property("interpolate() vectors") {
- val diff = BigInt("675204474840679645414180963439886534428")
- control.interpolate(Seq((799167010, diff), (799167133, diff), (799167256, diff), (799167379, diff)), Epoch) shouldBe diff
-
- control.interpolate(Seq((123, diff), (246, diff), (369, diff), (492, diff)), Epoch) shouldBe diff
-
- control.interpolate(Vector((123, diff), (246, diff * 2), (369, diff * 2), (492, diff)), Epoch) shouldBe (diff * 3 / 2)
-
- control.interpolate(Vector((123, diff), (246, diff * 2), (369, diff * 3), (492, diff * 4)), Epoch) shouldBe BigInt("3376022374203398227070904817199432672139")
-
- }
-
- property("interpolate() for constant hashrate") {
- forAll(epochGen, diffGen) { (startEpoch: Int, diff: BigInt) =>
- val previousDifficulties = (startEpoch * Epoch until (UseLastEpochs + startEpoch) * Epoch by Epoch).map(i => (i, diff))
- val newDiff = control.interpolate(previousDifficulties, Epoch)
- (BigDecimal(newDiff - diff) / BigDecimal(diff)).toDouble should be < precision
- }
- }
-
-
- property("interpolate() for linear hashrate growth") {
- forAll(epochGen, diffGen, smallPositiveInt, smallPositiveInt) { (startEpoch, diff, epoch, useLastEpochs) =>
- whenever(useLastEpochs > 1) {
- val control = new DifficultyAdjustment(chainSettings(1.minute, useLastEpochs, epoch))
- val previousDifficulties = (startEpoch * epoch until (useLastEpochs + startEpoch) * epoch by epoch).map(i => (i, diff * i))
- val newDiff = control.interpolate(previousDifficulties, epoch)
- val expected = previousDifficulties.map(_._2).max + diff
- equalsWithPrecision(expected, newDiff)
- }
- }
- }
-
- property("calculate() for different epoch lengths and constant hashrate") {
- forAll(defaultHeaderGen, smallPositiveInt, smallPositiveInt, Gen.choose(1, 60 * 60 * 1000)) { (header: Header, epoch, useLastEpochs, interval) =>
- whenever(useLastEpochs > 1 && header.requiredDifficulty >= 1) {
- val control = new DifficultyAdjustment(chainSettings(interval.millis, useLastEpochs, epoch))
- val previousHeaders = control.previousHeightsRequiredForRecalculation(epoch * useLastEpochs + 1, epoch)
- .map(i => header.copy(timestamp = header.timestamp + i * interval, height = i))
- previousHeaders.length shouldBe useLastEpochs + 1
- control.calculate(previousHeaders, epoch) shouldBe header.requiredDifficulty
- }
- }
- }
-
- property("calculate() for different epoch lengths and linear hashrate") {
- val step = 1000
- forAll(defaultHeaderGen, smallPositiveInt, smallPositiveInt, Gen.choose(1, 60 * 60 * 1000)) { (header: Header, epoch, useLastEpochs, interval) =>
- whenever(useLastEpochs > 1) {
- val control = new DifficultyAdjustment(chainSettings(interval.millis, useLastEpochs, epoch))
- val previousHeaders = control.previousHeightsRequiredForRecalculation(epoch * useLastEpochs + 1, epoch).map { i =>
- header.copy(timestamp = header.timestamp + i * interval,
- height = i,
- nBits = DifficultySerializer.encodeCompactBits(DifficultySerializer.decodeCompactBits(header.nBits) + step))
- }
-
- previousHeaders.length shouldBe useLastEpochs + 1
- val expectedDifficulty = previousHeaders.last.requiredDifficulty + step
- val error = BigDecimal(control.calculate(previousHeaders, epoch) - expectedDifficulty) / BigDecimal(expectedDifficulty)
- error should be < BigDecimal(1) / DifficultyAdjustment.PrecisionConstant
- }
- }
- }
-
- def equalsWithPrecision(i: BigInt, j: BigInt): Unit = {
- require((BigDecimal(i - j) / BigDecimal(j)).toDouble < precision, s"$i and $j are too different")
- }
-
- def diffGen: Gen[BigInt] = for {
- rnd <- Arbitrary.arbitrary[BigInt]
- diff = if (rnd < 0) -rnd + minDiff else rnd + minDiff
- _ = assert(diff > 0, s"$diff,$minDiff,$rnd")
- } yield diff
-
-
- def epochGen: Gen[Int] = Gen.choose(1, Int.MaxValue - UseLastEpochs)
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/mining/difficulty/DifficultySerializerSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/mining/difficulty/DifficultySerializerSpecification.scala
deleted file mode 100644
index 2039994171..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/mining/difficulty/DifficultySerializerSpecification.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.ergoplatform.mining.difficulty
-
-import org.ergoplatform.utils.ErgoPropertyTest
-
-class DifficultySerializerSpecification extends ErgoPropertyTest {
-
- property("external vectors from BitcoinJ") {
- val longs = Seq(0x180130e0, 0x18019eaf, 0x1802cc47, 0x1806f0a8, 0x187c3053, 0x1a05db8b, 0x1b0404cb, 0x1c20bca7, 0x1d00ffff, 0x181bc330,
- 0x207fffff, 0x01003456, 0x01123456, 0x02008000, 0x05009234, 0x04923456, 0x04123456)
- val expected = Seq("130e0000000000000000000000000000000000000000000",
- "19eaf000000000000000000000000000000000000000000",
- "2cc47000000000000000000000000000000000000000000",
- "6f0a8000000000000000000000000000000000000000000",
- "7c3053000000000000000000000000000000000000000000",
- "5db8b0000000000000000000000000000000000000000000000",
- "404cb000000000000000000000000000000000000000000000000",
- "20bca700000000000000000000000000000000000000000000000000",
- "ffff0000000000000000000000000000000000000000000000000000",
- "1bc330000000000000000000000000000000000000000000",
- "7fffff0000000000000000000000000000000000000000000000000000000000",
- "0",
- "12",
- "80",
- "92340000",
- "-12345600",
- "12345600")
- val calculated: Seq[String] = longs.map(nBits => DifficultySerializer.decodeCompactBits(nBits).toString(16))
-
- calculated shouldEqual expected
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/AdProofSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/AdProofSpec.scala
deleted file mode 100644
index ffb09082d2..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/AdProofSpec.scala
+++ /dev/null
@@ -1,116 +0,0 @@
-package org.ergoplatform.modifiers.history
-
-import org.ergoplatform.ErgoBox
-import org.ergoplatform.modifiers.state.StateChanges
-import org.ergoplatform.settings.Algos.HF
-import org.ergoplatform.settings.Constants
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.scalacheck.Gen
-import scorex.crypto.authds._
-import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert}
-import scorex.crypto.hash.Digest32
-import scorex.util._
-import sigmastate.helpers.TestingHelpers._
-
-
-class AdProofSpec extends ErgoPropertyTest {
- val KL = 32
-
- type Digest = ADDigest
- type Proof = SerializedAdProof
-
- type PrevDigest = Digest
- type NewDigest = Digest
-
- val emptyModifierId: ModifierId = bytesToId(Array.fill(32)(0.toByte))
-
- private def insert(box: ErgoBox) = Insert(box.id, ADValue @@ box.bytes)
-
- private def createEnv(howMany: Int = 10):
- (IndexedSeq[Insert], PrevDigest, NewDigest, Proof) = {
-
- val prover = new BatchAVLProver[Digest32, HF](KL, None)
- val zeroBox = testBox(0, Constants.TrueLeaf, startHeight, Seq(), Map(), Array.fill(32)(0: Byte).toModifierId)
- prover.performOneOperation(Insert(zeroBox.id, ADValue @@ zeroBox.bytes))
- prover.generateProof()
-
- val prevDigest = prover.digest
- val boxes = (1 to howMany) map { i => testBox(1, Constants.TrueLeaf, startHeight, boxIndex = i.toShort) }
- boxes.foreach(box => prover.performOneOperation(Insert(box.id, ADValue @@ box.bytes)))
- val pf = prover.generateProof()
-
- val newDigest = prover.digest
- val operations: IndexedSeq[Insert] = boxes.map(box => Insert(box.id, ADValue @@ box.bytes))
- (operations, prevDigest, newDigest, pf)
- }
-
- property("verify should be success in simple case") {
- forAll(Gen.choose(0, 1000)) { s =>
- whenever(s >= 0) {
- val (operations, prevDigest, newDigest, pf) = createEnv(s)
- val proof = ADProofs(emptyModifierId, pf)
- proof.verify(StateChanges(IndexedSeq.empty, operations, IndexedSeq.empty), prevDigest, newDigest) shouldBe 'success
- }
- }
- }
-
- property("verify should be failed if first operation is missed") {
- val (operations, prevDigest, newDigest, pf) = createEnv()
- val proof = ADProofs(emptyModifierId, pf)
- proof.verify(StateChanges(IndexedSeq.empty, operations.tail, IndexedSeq.empty), prevDigest, newDigest) shouldBe 'failure
- }
-
- property("verify should be failed if last operation is missed") {
- val (operations, prevDigest, newDigest, pf) = createEnv()
- val proof = ADProofs(emptyModifierId, pf)
- proof.verify(StateChanges(IndexedSeq.empty, operations.init, IndexedSeq.empty), prevDigest, newDigest) shouldBe 'failure
- }
-
- property("verify should be failed if there are more operations than expected") {
- val (operations, prevDigest, newDigest, pf) = createEnv()
- val proof = ADProofs(emptyModifierId, pf)
- val moreInsertions = operations :+ insert(testBox(10, Constants.TrueLeaf, creationHeight = startHeight))
- proof.verify(StateChanges(IndexedSeq.empty, moreInsertions, IndexedSeq.empty), prevDigest, newDigest) shouldBe 'failure
- }
-
- property("verify should be failed if there are illegal operation") {
- val (operations, prevDigest, newDigest, pf) = createEnv()
- val proof = ADProofs(emptyModifierId, pf)
- val differentInsertions = operations.init :+ insert(testBox(10, Constants.TrueLeaf, creationHeight = startHeight))
- proof.verify(StateChanges(IndexedSeq.empty, differentInsertions, IndexedSeq.empty), prevDigest, newDigest) shouldBe 'failure
- }
-
- property("verify should be failed if there are operations in different order") {
- val (operations, prevDigest, newDigest, pf) = createEnv()
- val proof = ADProofs(emptyModifierId, pf)
- val operationsInDifferentOrder = operations.last +: operations.init
- proof.verify(StateChanges(IndexedSeq.empty, operationsInDifferentOrder, IndexedSeq.empty), prevDigest, newDigest) shouldBe 'failure
- }
-
- //todo: what to do with that?
- ignore("verify should be failed if there are more proof bytes that needed") {
- val (operations, prevDigest, newDigest, pf) = createEnv()
- val proof = ADProofs(emptyModifierId, SerializedAdProof @@ (pf :+ 't'.toByte))
- proof.verify(StateChanges(IndexedSeq.empty, operations, IndexedSeq.empty), prevDigest, newDigest) shouldBe 'failure
- }
-
- property("verify should be failed if there are less proof bytes that needed") {
- val (operations, prevDigest, newDigest, pf) = createEnv()
- val proof = ADProofs(emptyModifierId, SerializedAdProof @@ pf.init)
- proof.verify(StateChanges(IndexedSeq.empty, operations, IndexedSeq.empty), prevDigest, newDigest) shouldBe 'failure
- }
-
- property("verify should be failed if there are different proof bytes") {
- val (operations, prevDigest, newDigest, pf) = createEnv()
- pf.update(4, 6.toByte)
- val proof = ADProofs(emptyModifierId, pf)
- proof.verify(StateChanges(IndexedSeq.empty, operations, IndexedSeq.empty), prevDigest, newDigest) shouldBe 'failure
- }
-
- property("proof is deterministic") {
- val pf1 = createEnv()._4
- val pf2 = createEnv()._4
- ADProofs.proofDigest(pf1) shouldBe ADProofs.proofDigest(pf2)
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/BlockTransactionsSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/BlockTransactionsSpec.scala
deleted file mode 100644
index c3fd1fe644..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/BlockTransactionsSpec.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.ergoplatform.modifiers.history
-
-import org.ergoplatform.utils.ErgoPropertyTest
-
-class BlockTransactionsSpec extends ErgoPropertyTest {
-
- property("Correct Merkle proofs are generated") {
- forAll(invalidBlockTransactionsGen, modifierIdGen){ case (bt, absentTx) =>
- // for all the transactions presented in a BlockTransactions instance valid proofs should be generated
- bt.transactions.forall{t => BlockTransactions.proofValid(bt.digest, bt.proofFor(t.id).get)} shouldBe true
-
- // no proof should be generated for a transaction which is not there
- bt.proofFor(absentTx).isDefined shouldBe false
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/ExtensionCandidateTest.scala b/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/ExtensionCandidateTest.scala
deleted file mode 100644
index c644abf0d8..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/ExtensionCandidateTest.scala
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.ergoplatform.modifiers.history
-
-import org.ergoplatform.modifiers.history.extension.ExtensionCandidate
-import org.ergoplatform.modifiers.history.popow.NipopowAlgos
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.scalacheck.Gen
-
-class ExtensionCandidateTest extends ErgoPropertyTest {
- type KV = (Array[Byte], Array[Byte])
-
- property("proofFor should return a valid proof for an existing value") {
- forAll { explodedFields: (Seq[KV], KV, Seq[KV]) =>
- val (left, middle, right) = explodedFields
- val fields = left ++ (middle +: right)
-
- val ext = ExtensionCandidate(fields)
- val proof = ext.proofFor(middle._1.clone)
- proof shouldBe defined
- val nakedLeaf = proof.get.leafData
- val numBytesKey = nakedLeaf.head
- val key = nakedLeaf.tail.take(numBytesKey)
- key shouldBe middle._1
- proof.get.valid(ext.digest) shouldBe true
- }
- }
-
- property("batchProofFor should return a valid proof for a set of existing values") {
- val modifierIds = Gen.listOf(modifierIdGen)
- forAll(modifierIds) { modifiers =>
- whenever(modifiers.nonEmpty) {
-
- val fields = NipopowAlgos.packInterlinks(modifiers)
- val ext = ExtensionCandidate(fields)
- val proof = ext.batchProofFor(fields.map(_._1.clone).toArray: _*)
- proof shouldBe defined
- proof.get.valid(ext.interlinksDigest) shouldBe true
- }
- }
- }
-
- property("batchProofFor should return None for a empty fields") {
- val fields: Seq[KV] = Seq.empty
- val ext = ExtensionCandidate(fields)
- val proof = ext.batchProofFor(fields.map(_._1.clone).toArray: _*)
- proof shouldBe None
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/HeadersSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/HeadersSpec.scala
deleted file mode 100644
index 0cbd9fa3b8..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/HeadersSpec.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.ergoplatform.modifiers.history
-
-import com.google.common.primitives.Longs
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.crypto.hash.Blake2b256
-import scorex.util.ModifierId
-
-class HeadersSpec extends ErgoPropertyTest {
-
- val chain: HeaderChain = genHeaderChain(50, diffBitsOpt = None, useRealTs = false)
- val genesisId: ModifierId = chain.head.id
-
- private def mutateNonce(nonce: Array[Byte]): Array[Byte] = {
- Longs.toByteArray(Longs.fromByteArray(nonce) + 1)
- }
-
- property("Any field change should lead to different id") {
- forAll(defaultHeaderGen) { header =>
- val initialId = header.id
- header.copy(version = (header.version + 1).toByte).id should not equal initialId
- header.copy(parentId = initialId).id should not equal initialId
- header.copy(ADProofsRoot = Blake2b256(header.ADProofsRoot)).id should not equal initialId
- header.copy(transactionsRoot = Blake2b256(header.transactionsRoot)).id should not equal initialId
- header.copy(timestamp = header.timestamp + 1).id should not equal initialId
- header.copy(nBits = header.nBits + 1).id should not equal initialId
- header.copy(height = header.height + 1).id should not equal initialId
- header.copy(extensionRoot = Blake2b256(header.extensionRoot)).id should not equal initialId
- header.copy(powSolution = header.powSolution.copy(n = mutateNonce(header.powSolution.n))).id should not equal initialId
- if(header.version == 1) {
- header.copy(powSolution = header.powSolution.copy(d = header.powSolution.d + 1)).id should not equal initialId
- }
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/PoPowAlgosSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/PoPowAlgosSpec.scala
deleted file mode 100644
index ea2a976724..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/PoPowAlgosSpec.scala
+++ /dev/null
@@ -1,226 +0,0 @@
-package org.ergoplatform.modifiers.history
-
-import org.ergoplatform.modifiers.history.popow.{NipopowAlgos, NipopowProof, PoPowHeader, PoPowParams}
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.utils.generators.ChainGenerator
-import org.scalacheck.Gen
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-import scorex.util.ModifierId
-import org.ergoplatform.utils.HistoryTestHelpers
-
-class PoPowAlgosSpec extends AnyPropSpec with Matchers with HistoryTestHelpers with ChainGenerator {
-
- private val poPowParams = PoPowParams(30, 30, continuous = false)
- private val ChainLength = 10
-
- private def toPoPoWChain = (c: Seq[ErgoFullBlock]) => c.map(b => PoPowHeader.fromBlock(b).get)
-
- property("updateInterlinks") {
- val chain = genChain(ChainLength)
- val genesis = chain.head
- val interlinks = chain.foldLeft(Seq.empty[Seq[ModifierId]]) { case (acc, b) =>
- acc :+ (if (acc.isEmpty) {
- nipopowAlgos.updateInterlinks(b.header, Seq.empty)
- } else {
- nipopowAlgos.updateInterlinks(b.header, acc.last)
- })
- }
-
- interlinks.foreach { links =>
- links.head shouldEqual genesis.header.id
- links.tail should not contain genesis.header.id
- }
-
- interlinks.zipWithIndex.foreach { case (links, idx) =>
- if (idx > 0) links.size >= interlinks(idx - 1).size shouldBe true
- }
- }
-
- property("packInterlinks") {
- val diffInterlinks = Gen.listOfN(255, modifierIdGen).sample.get
- val modId = modifierIdGen.sample.get
- val sameInterlinks = List.fill(255)(modId)
- val packedDiff = nipopowAlgos.interlinksToExtension(diffInterlinks).fields
- val packedSame = nipopowAlgos.interlinksToExtension(sameInterlinks).fields
-
- packedDiff.map(_._1.last).toSet.size shouldEqual diffInterlinks.size
- packedSame.map(_._1.last).toSet.size shouldEqual 1
- }
-
- property("unpackInterlinks") {
- val interlinks = Gen.listOfN(255, modifierIdGen).sample.get
- val packed = nipopowAlgos.interlinksToExtension(interlinks).fields
- val improperlyPacked = packed.map(x => x._1 -> (x._2 :+ (127: Byte)))
-
- val unpackedTry = NipopowAlgos.unpackInterlinks(packed)
-
- unpackedTry shouldBe 'success
- NipopowAlgos.unpackInterlinks(improperlyPacked) shouldBe 'failure
-
- unpackedTry.get shouldEqual interlinks
- }
-
- property("proofForInterlinkVector") {
- val blockIds = Gen.listOfN(255, modifierIdGen).sample.get
- val extension = nipopowAlgos.interlinksToExtension(blockIds)
- val proof = NipopowAlgos.proofForInterlinkVector(extension)
- proof.get.valid(extension.digest) shouldBe true
- }
-
- property("empty proofForInterlinkVector should be None") {
- val blockIds = Seq.empty[ModifierId]
- val extension = nipopowAlgos.interlinksToExtension(blockIds)
- val proof = NipopowAlgos.proofForInterlinkVector(extension)
- proof shouldBe defined
- proof.get.proofs should have length 0
- proof.get.indices should have length 0
- }
-
- property("0 level is always valid for any block") {
- val chain = genChain(10)
- chain.foreach(x => nipopowAlgos.maxLevelOf(x.header) >= 0 shouldBe true)
- }
-
- property("lowestCommonAncestor - diverging") {
- val sizes = Seq(10, 100, 1000)
- sizes.foreach { size =>
- val chain0 = genChain(size)
- val branchPoint = chain0(size / 2)
- val chain1 = chain0.take(size / 2) ++ genChain(size / 2, branchPoint)
-
- nipopowAlgos.lowestCommonAncestor(chain0.map(_.header), chain1.map(_.header)) shouldBe Some(branchPoint.header)
- }
- }
-
- property("bestArg - always equal for equal proofs") {
- val chain0 = genChain(100).map(b => PoPowHeader.fromBlock(b).get)
- val proof0 = nipopowAlgos.prove(chain0)(poPowParams).get
- val chain1 = genChain(100).map(b => PoPowHeader.fromBlock(b).get)
- val proof1 = nipopowAlgos.prove(chain1)(poPowParams).get
- val m = poPowParams.m
-
- proof0.prefix.size shouldEqual proof1.prefix.size
-
- nipopowAlgos.bestArg(proof0.prefix.map(_.header))(m) shouldEqual nipopowAlgos.bestArg(proof1.prefix.map(_.header))(m)
- }
-
- property("bestArg - always greater for better proof") {
- val chain0 = genChain(100).map(b => PoPowHeader.fromBlock(b).get)
- val proof0 = nipopowAlgos.prove(chain0)(poPowParams).get
- val chain1 = genChain(70).map(b => PoPowHeader.fromBlock(b).get)
- val proof1 = nipopowAlgos.prove(chain1)(poPowParams).get
- val m = poPowParams.m
-
- proof0.prefix.size > proof1.prefix.size shouldBe true
-
- nipopowAlgos.bestArg(proof0.prefix.map(_.header))(m) > nipopowAlgos.bestArg(proof1.prefix.map(_.header))(m) shouldBe true
- }
-
- property("proof(chain) is equivalent to proof(histReader)") {
- val poPowParams = PoPowParams(m = 5, k = 6, continuous = false)
- val blocksChain = genChain(3000)
- val pchain = blocksChain.map(b => PoPowHeader.fromBlock(b).get)
- val proof0 = nipopowAlgos.prove(pchain)(poPowParams).get
-
- val h = generateHistory(true, StateType.Digest, false,
- 10000, 10000, 10, None)
- val hr = applyChain(h, blocksChain)
- val proof1 = nipopowAlgos.prove(hr)(poPowParams).get
-
- proof0.suffixHead.id shouldBe proof1.suffixHead.id
- proof0.suffixTail.map(_.id) shouldBe proof1.suffixTail.map(_.id)
-
- proof0.prefix.map(_.id).length shouldBe proof1.prefix.map(_.id).length
- proof0.prefix.map(_.id).toList shouldBe proof1.prefix.map(_.id).toList
- }
-
- property("proof(histReader) for a header in the past") {
- val poPowParams = PoPowParams(5, 6, continuous = false)
- val blocksChain = genChain(300)
-
- val at = 200
-
- val h = generateHistory(true, StateType.Digest, false,
- 10000, 10000, 10, None)
- val hr = applyChain(h, blocksChain.take(at))
- val proof0 = nipopowAlgos.prove(hr, None)(poPowParams).get
-
- val id = proof0.suffixHead.header.id
-
- val hrf = applyChain(hr, blocksChain.drop(at))
- val proof1 = nipopowAlgos.prove(hrf, Some(id))(poPowParams).get
-
- proof0.suffixHead.id shouldBe proof1.suffixHead.id
- proof0.suffixTail.map(_.id) shouldBe proof1.suffixTail.map(_.id)
-
- proof0.prefix.map(_.id).length shouldBe proof1.prefix.map(_.id).length
- proof0.prefix.map(_.id).sorted.toList shouldBe proof1.prefix.map(_.id).sorted.toList
- }
-
- property("isBetterThan - marginally longer chain should be better") {
- val sizes = Seq(1000)
- sizes.foreach { size =>
- val baseChain = genChain(size)
- val branchPoint = baseChain(baseChain.length - 1)
- val shortChain = toPoPoWChain(baseChain)
- val longChain = toPoPoWChain(baseChain ++ genChain(1, branchPoint).takeRight(1))
-
- val shortProof = nipopowAlgos.prove(shortChain)(poPowParams).get
- val longProof = nipopowAlgos.prove(longChain)(poPowParams).get
-
- shortProof.isBetterThan(longProof) shouldBe false
- }
- }
-
- property("isBetterThan - a disconnected prefix chain should not win") {
- val smallPoPowParams = PoPowParams(50, 1, continuous = false)
- val size = 100
- val chain = toPoPoWChain(genChain(size))
- val proof = nipopowAlgos.prove(chain)(smallPoPowParams).get
-
- val longerChain = toPoPoWChain(genChain(size * 2))
- val longerProof = nipopowAlgos.prove(longerChain)(smallPoPowParams).get
-
- val disconnectedProofPrefix = proof.prefix.take(proof.prefix.length / 2) ++ longerProof.prefix
- val disconnectedProof = NipopowProof(nipopowAlgos, proof.m, proof.k, disconnectedProofPrefix, proof.suffixHead, proof.suffixTail, continuous = false)
- proof.isBetterThan(disconnectedProof) shouldBe true
- }
-
- property("hasValidConnections - ensures a connected prefix chain") {
- val smallPoPowParams = PoPowParams(5, 5, continuous = false)
- val sizes = Seq(100, 200)
- sizes.foreach { size =>
- val chain = toPoPoWChain(genChain(size))
- val randomBlock = toPoPoWChain(genChain(1)).head
- val proof = nipopowAlgos.prove(chain)(smallPoPowParams).get
- val disconnectedProofPrefix = proof.prefix.updated(proof.prefix.length / 2, randomBlock)
- val disconnectedProof = NipopowProof(nipopowAlgos, proof.m, proof.k, disconnectedProofPrefix, proof.suffixHead, proof.suffixTail, continuous = false)
- proof.hasValidConnections shouldBe true
- disconnectedProof.hasValidConnections shouldBe false
- }
- }
-
- property("hasValidConnections - ensures a connected suffix chain") {
- val smallPoPowParams = PoPowParams(5, 5, continuous = false)
- val sizes = Seq(100, 200)
-
- sizes.foreach { size =>
- val chain = toPoPoWChain(genChain(size))
- val randomBlock = genChain(1).head.header
- val proof = nipopowAlgos.prove(chain)(smallPoPowParams).get
- val disconnectedProofSuffixTail = proof.suffixTail.updated(proof.suffixTail.length / 2, randomBlock)
- val disconnectedProof = NipopowProof(nipopowAlgos, proof.m, proof.k, proof.prefix, proof.suffixHead, disconnectedProofSuffixTail, continuous = false)
- proof.hasValidConnections shouldBe true
- disconnectedProof.hasValidConnections shouldBe false
- }
- }
-
- property("hasValidConnections - ensures prefix.last & suffix.head are linked") {
- val prefix = toPoPoWChain(genChain(1))
- val suffix = toPoPoWChain(genChain(1))
- NipopowProof(nipopowAlgos, 0, 0, prefix, suffix.head, suffix.tail.map(_.header), continuous = false).hasValidConnections shouldBe false
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/PoPowHeaderSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/PoPowHeaderSpec.scala
deleted file mode 100644
index 978f0f83dc..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/PoPowHeaderSpec.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.ergoplatform.modifiers.history
-
-import org.ergoplatform.modifiers.history.popow.NipopowAlgos
-import org.ergoplatform.modifiers.history.popow.PoPowHeader.checkInterlinksProof
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.scalacheck.Gen
-
-class PoPowHeaderSpec extends ErgoPropertyTest {
-
- property("Check interlinks proof should be true") {
- forAll(Gen.nonEmptyListOf(modifierIdGen)) { interlinks =>
- val interlinksProof = NipopowAlgos.proofForInterlinkVector(nipopowAlgos.interlinksToExtension(interlinks)).get
- checkInterlinksProof(interlinks, interlinksProof) shouldBe true
- }
- }
-
- property("Check invalid interlinks proof should be false") {
- forAll(Gen.nonEmptyListOf(modifierIdGen), Gen.nonEmptyListOf(modifierIdGen)) { (interlinks1, interlinks2) =>
- val interlinksProof = NipopowAlgos.proofForInterlinkVector(nipopowAlgos.interlinksToExtension(interlinks2)).get
- checkInterlinksProof(interlinks1, interlinksProof) shouldBe false
- }
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoTransactionSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoTransactionSpec.scala
deleted file mode 100644
index 4901e7526b..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoTransactionSpec.scala
+++ /dev/null
@@ -1,546 +0,0 @@
-package org.ergoplatform.modifiers.mempool
-
-import io.circe.syntax._
-import org.ergoplatform.ErgoBox._
-import org.ergoplatform.nodeView.ErgoContext
-import org.ergoplatform.nodeView.state.{ErgoStateContext, VotingData}
-import org.ergoplatform.sdk.wallet.protocol.context.TransactionContext
-import org.ergoplatform.settings.Parameters.MaxBlockCostIncrease
-import org.ergoplatform.settings.ValidationRules.{bsBlockTransactionsCost, txAssetsInOneBox}
-import org.ergoplatform.settings._
-import org.ergoplatform.utils.{ErgoPropertyTest, ErgoTestConstants}
-import org.ergoplatform.wallet.boxes.ErgoBoxAssetExtractor
-import org.ergoplatform.wallet.interpreter.{ErgoInterpreter, TransactionHintsBag}
-import org.ergoplatform.wallet.protocol.context.InputContext
-import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, Input}
-import org.scalacheck.Gen
-import sigma.util.BenchmarkUtil
-import scorex.crypto.authds.ADKey
-import scorex.crypto.hash.Blake2b256
-import scorex.util.encode.Base16
-import scorex.util.{ModifierId, bytesToId}
-import sigma.Colls
-import sigmastate.AND
-import sigmastate.Values.{ByteArrayConstant, ByteConstant, IntConstant, LongArrayConstant, SigmaPropConstant, TrueLeaf}
-import sigmastate.crypto.CryptoConstants
-import sigmastate.crypto.DLogProtocol.ProveDlog
-import sigmastate.eval._
-import sigmastate.helpers.TestingHelpers._
-import sigmastate.interpreter.{ContextExtension, ProverResult}
-import sigmastate.eval.Extensions._
-
-import scala.util.{Random, Try}
-
-class ErgoTransactionSpec extends ErgoPropertyTest with ErgoTestConstants {
-
- private implicit val verifier: ErgoInterpreter = ErgoInterpreter(parameters)
-
- private val emptyModifierId: ModifierId = bytesToId(Array.fill(32)(0.toByte))
-
-
- private def updateAnAsset(tx: ErgoTransaction, from: IndexedSeq[ErgoBox], deltaFn: Long => Long) = {
- val updCandidates = tx.outputCandidates.foldLeft(IndexedSeq[ErgoBoxCandidate]() -> false) { case ((seq, modified), ebc) =>
- if (modified) {
- (seq :+ ebc) -> true
- } else {
- if (ebc.additionalTokens.nonEmpty && ebc.additionalTokens.exists(t => !java.util.Arrays.equals(t._1.toArray, from.head.id))) {
- (seq :+ modifyAsset(ebc, deltaFn, from.head.id.toTokenId)) -> true
- } else {
- (seq :+ ebc) -> false
- }
- }
- }._1
- tx.copy(outputCandidates = updCandidates)
- }
-
- private def modifyValue(boxCandidate: ErgoBoxCandidate, delta: Long): ErgoBoxCandidate = {
- new ErgoBoxCandidate(
- boxCandidate.value + delta,
- boxCandidate.ergoTree,
- boxCandidate.creationHeight,
- boxCandidate.additionalTokens,
- boxCandidate.additionalRegisters)
- }
-
- private def modifyAsset(boxCandidate: ErgoBoxCandidate,
- deltaFn: Long => Long,
- idToskip: TokenId): ErgoBoxCandidate = {
- val assetId = boxCandidate.additionalTokens.find(t => t._1 != idToskip).get._1
-
- val tokens = boxCandidate.additionalTokens.map { case (id, amount) =>
- if (id == assetId) assetId -> deltaFn(amount) else assetId -> amount
- }
-
- new ErgoBoxCandidate(
- boxCandidate.value,
- boxCandidate.ergoTree,
- boxCandidate.creationHeight,
- tokens,
- boxCandidate.additionalRegisters)
- }
-
- private def checkTx(from: IndexedSeq[ErgoBox], tx: ErgoTransaction): Try[Int] = {
- tx.statelessValidity().flatMap(_ => tx.statefulValidity(from, emptyDataBoxes, emptyStateContext))
- }
-
- property("serialization vector") {
- // test vectors, that specifies transaction json and bytes representation.
- // ensures that bytes transaction representation was not changed
-
- def check(bytesStr: String, bytesToSign: String, jsonStr: String): Unit = {
- val bytes = Base16.decode(bytesStr).get
- val tx = ErgoTransactionSerializer.parseBytes(bytes)
- tx.asJson.noSpaces shouldBe jsonStr
- bytesToSign shouldBe Base16.encode(tx.messageToSign)
- }
-
- // simple transfer transaction with 2 inputs and 2 outputs (first is transfer, second is fee)
- val height = 1000
- val minerPkHex = "0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942"
- val minerPk = Base16.decode(minerPkHex).map { point =>
- ProveDlog(
- CryptoConstants.dlogGroup.ctx.decodePoint(point)
- )
- }.get
- val inputs: IndexedSeq[Input] = IndexedSeq(
- new Input(ADKey @@ Base16.decode("c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f7742").get,
- new ProverResult(Base16.decode("b4a04b4201da0578be3dac11067b567a73831f35b024a2e623c1f8da230407f63bab62c62ed9b93808b106b5a7e8b1751fa656f4c5de4674").get, new ContextExtension(Map()))),
- new Input(ADKey @@ Base16.decode("ca796a4fc9c0d746a69702a77bd78b1a80a5ef5bf5713bbd95d93a4f23b27ead").get,
- new ProverResult(Base16.decode("5aea4d78a234c35accacdf8996b0af5b51e26fee29ea5c05468f23707d31c0df39400127391cd57a70eb856710db48bb9833606e0bf90340").get, new ContextExtension(Map()))),
- )
- val outputCandidates: IndexedSeq[ErgoBoxCandidate] = IndexedSeq(
- new ErgoBoxCandidate(1000000000L, minerPk, height, Colls.emptyColl, Map()),
- new ErgoBoxCandidate(1000000L, settings.chainSettings.monetary.feeProposition, height, Colls.emptyColl, Map())
- )
- val tx = ErgoTransaction(inputs: IndexedSeq[Input], outputCandidates: IndexedSeq[ErgoBoxCandidate])
-
- val bytesToSign = "02c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f77420000ca796a4fc9c0d746a69702a77bd78b1a80a5ef5bf5713bbd95d93a4f23b27ead00000000028094ebdc030008cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942e8070000c0843d1005040004000e36100204cf0f08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a701730073011001020402d19683030193a38cc7b2a57300000193c2b2a57301007473027303830108cdeeac93b1a57304e8070000"
- val bytesStr = "02c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f774238b4a04b4201da0578be3dac11067b567a73831f35b024a2e623c1f8da230407f63bab62c62ed9b93808b106b5a7e8b1751fa656f4c5de467400ca796a4fc9c0d746a69702a77bd78b1a80a5ef5bf5713bbd95d93a4f23b27ead385aea4d78a234c35accacdf8996b0af5b51e26fee29ea5c05468f23707d31c0df39400127391cd57a70eb856710db48bb9833606e0bf90340000000028094ebdc030008cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942e8070000c0843d1005040004000e36100204cf0f08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a701730073011001020402d19683030193a38cc7b2a57300000193c2b2a57301007473027303830108cdeeac93b1a57304e8070000"
- val jsonStr = "{\"id\":\"b59ca51f7470f291acc32e84870d00c4fda8b773f38f757f3d65d45265c13da5\",\"inputs\":[{\"boxId\":\"c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f7742\",\"spendingProof\":{\"proofBytes\":\"b4a04b4201da0578be3dac11067b567a73831f35b024a2e623c1f8da230407f63bab62c62ed9b93808b106b5a7e8b1751fa656f4c5de4674\",\"extension\":{}}},{\"boxId\":\"ca796a4fc9c0d746a69702a77bd78b1a80a5ef5bf5713bbd95d93a4f23b27ead\",\"spendingProof\":{\"proofBytes\":\"5aea4d78a234c35accacdf8996b0af5b51e26fee29ea5c05468f23707d31c0df39400127391cd57a70eb856710db48bb9833606e0bf90340\",\"extension\":{}}}],\"dataInputs\":[],\"outputs\":[{\"boxId\":\"da288ce9e9a9d39f69634488a8d82c1bf4fb6ddce2f0930d2536016d8167eeb2\",\"value\":1000000000,\"ergoTree\":\"0008cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942\",\"assets\":[],\"creationHeight\":1000,\"additionalRegisters\":{},\"transactionId\":\"b59ca51f7470f291acc32e84870d00c4fda8b773f38f757f3d65d45265c13da5\",\"index\":0},{\"boxId\":\"be609af4436111d5592dbd52bc64f6a46a1c0605fd30cd61c74850b7f9875762\",\"value\":1000000,\"ergoTree\":\"1005040004000e36100204cf0f08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a701730073011001020402d19683030193a38cc7b2a57300000193c2b2a57301007473027303830108cdeeac93b1a57304\",\"assets\":[],\"creationHeight\":1000,\"additionalRegisters\":{},\"transactionId\":\"b59ca51f7470f291acc32e84870d00c4fda8b773f38f757f3d65d45265c13da5\",\"index\":1}],\"size\":341}"
- Base16.encode(tx.bytes) shouldBe bytesStr
-
- check(bytesStr, bytesToSign, jsonStr)
-
- // tx with registers in outputs
- val outputCandidates2: IndexedSeq[ErgoBoxCandidate] = IndexedSeq(
- new ErgoBoxCandidate(1000000000L, minerPk, height, Colls.emptyColl,
- Map(
- R6 -> IntConstant(10),
- R4 -> ByteConstant(1),
- R5 -> SigmaPropConstant(minerPk),
- R7 -> LongArrayConstant(Array(1L, 2L, 1234123L)),
- R8 -> ByteArrayConstant(Base16.decode("123456123456123456123456123456123456123456123456123456123456123456").get),
- )),
- new ErgoBoxCandidate(1000000000L, minerPk, height, Colls.emptyColl, Map())
- )
- val tx2 = ErgoTransaction(inputs: IndexedSeq[Input], outputCandidates2: IndexedSeq[ErgoBoxCandidate])
-
- Base16.encode(tx2.bytes) shouldBe "02c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f774238b4a04b4201da0578be3dac11067b567a73831f35b024a2e623c1f8da230407f63bab62c62ed9b93808b106b5a7e8b1751fa656f4c5de467400ca796a4fc9c0d746a69702a77bd78b1a80a5ef5bf5713bbd95d93a4f23b27ead385aea4d78a234c35accacdf8996b0af5b51e26fee29ea5c05468f23707d31c0df39400127391cd57a70eb856710db48bb9833606e0bf90340000000028094ebdc030008cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942e8070005020108cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b94204141103020496d396010e211234561234561234561234561234561234561234561234561234561234561234568094ebdc030008cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942e8070000"
- check(Base16.encode(tx2.bytes), "02c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f77420000ca796a4fc9c0d746a69702a77bd78b1a80a5ef5bf5713bbd95d93a4f23b27ead00000000028094ebdc030008cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942e8070005020108cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b94204141103020496d396010e211234561234561234561234561234561234561234561234561234561234561234568094ebdc030008cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942e8070000",
- "{\"id\":\"bd04a93f67fda77d89afc38cd8237f142ad5a349405929fd1f7b7f24c4ea2e80\",\"inputs\":[{\"boxId\":\"c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f7742\",\"spendingProof\":{\"proofBytes\":\"b4a04b4201da0578be3dac11067b567a73831f35b024a2e623c1f8da230407f63bab62c62ed9b93808b106b5a7e8b1751fa656f4c5de4674\",\"extension\":{}}},{\"boxId\":\"ca796a4fc9c0d746a69702a77bd78b1a80a5ef5bf5713bbd95d93a4f23b27ead\",\"spendingProof\":{\"proofBytes\":\"5aea4d78a234c35accacdf8996b0af5b51e26fee29ea5c05468f23707d31c0df39400127391cd57a70eb856710db48bb9833606e0bf90340\",\"extension\":{}}}],\"dataInputs\":[],\"outputs\":[{\"boxId\":\"1baffa8e5ffce634a8e70530023c16a5c177d2b5ab756ae89a8dce2a23ba433c\",\"value\":1000000000,\"ergoTree\":\"0008cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942\",\"assets\":[],\"creationHeight\":1000,\"additionalRegisters\":{\"R4\":\"0201\",\"R5\":\"08cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942\",\"R6\":\"0414\",\"R7\":\"1103020496d39601\",\"R8\":\"0e21123456123456123456123456123456123456123456123456123456123456123456\"},\"transactionId\":\"bd04a93f67fda77d89afc38cd8237f142ad5a349405929fd1f7b7f24c4ea2e80\",\"index\":0},{\"boxId\":\"33eff46f94067b32073d5f81984607be559108f58bc3f53906a1e8db7cf0f708\",\"value\":1000000000,\"ergoTree\":\"0008cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942\",\"assets\":[],\"creationHeight\":1000,\"additionalRegisters\":{},\"transactionId\":\"bd04a93f67fda77d89afc38cd8237f142ad5a349405929fd1f7b7f24c4ea2e80\",\"index\":1}],\"size\":356}")
-//
- // tx with 2 inputs, 1 data input, 3 outputs with tokens 0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942
- check("02e76bf387ab2e63ba8f4e23267bc88265b5fee4950030199e2e2c214334251c6400002e9798d7eb0cd867f6dc29872f80de64c04cef10a99a58d007ef7855f0acbdb9000001f97d1dc4626de22db836270fe1aa004b99970791e4557de8f486f6d433b81195026df03fffc9042bf0edb0d0d36d7a675239b83a9080d39716b9aa0a64cccb9963e76bf387ab2e63ba8f4e23267bc88265b5fee4950030199e2e2c214334251c6403da92a8b8e3ad770008cd02db0ce4d301d6dc0b7a5fbe749588ef4ef68f2c94435020a3c31764ffd36a2176000200daa4eb6b01aec8d1ff0100da92a8b8e3ad770008cd02db0ce4d301d6dc0b7a5fbe749588ef4ef68f2c94435020a3c31764ffd36a2176000200daa4eb6b01aec8d1ff0100fa979af8988ce7010008cd02db0ce4d301d6dc0b7a5fbe749588ef4ef68f2c94435020a3c31764ffd36a2176000000",
- "02e76bf387ab2e63ba8f4e23267bc88265b5fee4950030199e2e2c214334251c6400002e9798d7eb0cd867f6dc29872f80de64c04cef10a99a58d007ef7855f0acbdb9000001f97d1dc4626de22db836270fe1aa004b99970791e4557de8f486f6d433b81195026df03fffc9042bf0edb0d0d36d7a675239b83a9080d39716b9aa0a64cccb9963e76bf387ab2e63ba8f4e23267bc88265b5fee4950030199e2e2c214334251c6403da92a8b8e3ad770008cd02db0ce4d301d6dc0b7a5fbe749588ef4ef68f2c94435020a3c31764ffd36a2176000200daa4eb6b01aec8d1ff0100da92a8b8e3ad770008cd02db0ce4d301d6dc0b7a5fbe749588ef4ef68f2c94435020a3c31764ffd36a2176000200daa4eb6b01aec8d1ff0100fa979af8988ce7010008cd02db0ce4d301d6dc0b7a5fbe749588ef4ef68f2c94435020a3c31764ffd36a2176000000",
- "{\"id\":\"663ae91ab7145a4f42b5509e1a2fb0469b7cb46ea87fdfd90e0b4c8ef29c2493\",\"inputs\":[{\"boxId\":\"e76bf387ab2e63ba8f4e23267bc88265b5fee4950030199e2e2c214334251c64\",\"spendingProof\":{\"proofBytes\":\"\",\"extension\":{}}},{\"boxId\":\"2e9798d7eb0cd867f6dc29872f80de64c04cef10a99a58d007ef7855f0acbdb9\",\"spendingProof\":{\"proofBytes\":\"\",\"extension\":{}}}],\"dataInputs\":[{\"boxId\":\"f97d1dc4626de22db836270fe1aa004b99970791e4557de8f486f6d433b81195\"}],\"outputs\":[{\"boxId\":\"69e05b68715caaa4ca58ba59a8c8c7e031d42ad890b05f87021a28617c1e70d5\",\"value\":524940416256346,\"ergoTree\":\"0008cd02db0ce4d301d6dc0b7a5fbe749588ef4ef68f2c94435020a3c31764ffd36a2176\",\"assets\":[{\"tokenId\":\"6df03fffc9042bf0edb0d0d36d7a675239b83a9080d39716b9aa0a64cccb9963\",\"amount\":226153050},{\"tokenId\":\"e76bf387ab2e63ba8f4e23267bc88265b5fee4950030199e2e2c214334251c64\",\"amount\":536110126}],\"creationHeight\":0,\"additionalRegisters\":{},\"transactionId\":\"663ae91ab7145a4f42b5509e1a2fb0469b7cb46ea87fdfd90e0b4c8ef29c2493\",\"index\":0},{\"boxId\":\"556a9a3ec7880d468e56d44e75898cf8a32f6a07344895fa6b5cf34edf101a59\",\"value\":524940416256346,\"ergoTree\":\"0008cd02db0ce4d301d6dc0b7a5fbe749588ef4ef68f2c94435020a3c31764ffd36a2176\",\"assets\":[{\"tokenId\":\"6df03fffc9042bf0edb0d0d36d7a675239b83a9080d39716b9aa0a64cccb9963\",\"amount\":226153050},{\"tokenId\":\"e76bf387ab2e63ba8f4e23267bc88265b5fee4950030199e2e2c214334251c64\",\"amount\":536110126}],\"creationHeight\":0,\"additionalRegisters\":{},\"transactionId\":\"663ae91ab7145a4f42b5509e1a2fb0469b7cb46ea87fdfd90e0b4c8ef29c2493\",\"index\":1},{\"boxId\":\"16385b5b83992629909c7e004ed0421229ed3587162ce6f29b2df129472e3909\",\"value\":1016367755463674,\"ergoTree\":\"0008cd02db0ce4d301d6dc0b7a5fbe749588ef4ef68f2c94435020a3c31764ffd36a2176\",\"assets\":[],\"creationHeight\":0,\"additionalRegisters\":{},\"transactionId\":\"663ae91ab7145a4f42b5509e1a2fb0469b7cb46ea87fdfd90e0b4c8ef29c2493\",\"index\":2}],\"size\":329}")
- }
-
- property("a valid transaction is valid") {
- forAll(validErgoTransactionGen) { case (from, tx) =>
- tx.statelessValidity().isSuccess shouldBe true
- tx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe true
- }
- }
-
- property("ergo preservation law holds") {
- forAll(validErgoTransactionGen, smallPositiveInt) { case ((from, tx), deltaAbs) =>
- val delta = if (Random.nextBoolean()) -deltaAbs else deltaAbs
-
- val wrongTx = tx.copy(outputCandidates =
- modifyValue(tx.outputCandidates.head, delta) +: tx.outputCandidates.tail)
-
- wrongTx.statelessValidity().isSuccess &&
- wrongTx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe false
- }
- }
-
- property("impossible to create a negative-value output") {
- forAll(validErgoTransactionGen) { case (from, tx) =>
- val negValue = Math.min(Math.abs(Random.nextLong()), Long.MaxValue - tx.outputCandidates.head.value)
- val wrongTx = tx.copy(outputCandidates =
- modifyValue(tx.outputCandidates.head, -(tx.outputCandidates.head.value + negValue)) +: tx.outputCandidates.tail)
-
- wrongTx.statelessValidity().isSuccess shouldBe false
- wrongTx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe false
- }
- }
-
- property("impossible to overflow ergo tokens") {
- forAll(validErgoTransactionGen) { case (from, tx) =>
- val overflowSurplus = (Long.MaxValue - tx.outputCandidates.map(_.value).sum) + 1
-
- val wrongTx = tx.copy(outputCandidates =
- modifyValue(tx.outputCandidates.head, overflowSurplus) +: tx.outputCandidates.tail)
-
- wrongTx.statelessValidity().isSuccess shouldBe false
- wrongTx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe false
- }
- }
-
- property("assets preservation law holds") {
- forAll(validErgoTransactionWithAssetsGen) { case (from, tx) =>
- checkTx(from, updateAnAsset(tx, from, _ + 1)) shouldBe 'failure
- }
- }
-
- property("impossible to create an asset of negative amount") {
- forAll(validErgoTransactionWithAssetsGen) { case (from, tx) =>
- checkTx(from, updateAnAsset(tx, from, _ => -1)) shouldBe 'failure
- }
- }
-
- property("impossible to create an asset of zero amount") {
- forAll(validErgoTransactionWithAssetsGen) { case (from, tx) =>
- checkTx(from, updateAnAsset(tx, from, _ => 0)) shouldBe 'failure
- }
- }
-
- property("impossible to overflow an asset value") {
- val gen = validErgoTransactionGenTemplate(minAssets = 1, maxAssets = 1, maxInputs = 16, propositionGen = trueLeafGen)
- forAll(gen) { case (from, tx) =>
- val tokenOpt = tx.outputCandidates.flatMap(_.additionalTokens.toArray)
- .groupBy(_._1).find(_._2.size >= 2)
-
- whenever(tokenOpt.nonEmpty) {
- val tokenId = tokenOpt.get._1
- val tokenAmount = tokenOpt.get._2.map(_._2).sum
-
- var modified = false
- val updCandidates = tx.outputCandidates.map { c =>
- val updTokens = c.additionalTokens.map { case (id, amount) =>
- if (!modified && id == tokenId) {
- modified = true
- id -> ((Long.MaxValue - tokenAmount) + amount + 1)
- } else {
- id -> amount
- }
- }
- new ErgoBoxCandidate(c.value, c.ergoTree, startHeight, updTokens, c.additionalRegisters)
- }
-
- val wrongTx = tx.copy(outputCandidates = updCandidates)
- checkTx(from, wrongTx) shouldBe 'failure
- }
- }
- }
-
- property("stateful validation should catch false proposition") {
- val propositionGen = Gen.const(Constants.FalseLeaf)
- val gen = validErgoTransactionGenTemplate(1, 1, 1, propositionGen)
- forAll(gen) { case (from, tx) =>
- tx.statelessValidity().isSuccess shouldBe true
- val validity = tx.statefulValidity(from, emptyDataBoxes, emptyStateContext)
- validity.isSuccess shouldBe false
- val e = validity.failed.get
- e.getMessage should startWith(ValidationRules.errorMessage(ValidationRules.txScriptValidation, "", emptyModifierId, ErgoTransaction.modifierTypeId))
- }
- }
-
- property("assets usage correctly affects transaction total cost") {
- val txGen = validErgoTransactionGenTemplate(1, 1,16, propositionGen = trueLeafGen)
- forAll(txGen) { case (from, tx) =>
- val initTxCost = tx.statefulValidity(from, emptyDataBoxes, emptyStateContext).get
-
- // already existing token from one of the inputs
- val existingToken = from.flatMap(_.additionalTokens.toArray).toSet.head
- // completely new token
- val randomToken = (scorex.util.Random.randomBytes().toTokenId, Random.nextInt(100000000).toLong)
-
- val in0 = from.last
- // new token added to the last input
- val modifiedIn0 = testBox(in0.value, in0.ergoTree, in0.creationHeight,
- in0.additionalTokens.toArray.toSeq :+ randomToken, in0.additionalRegisters, in0.transactionId, in0.index)
- val txInMod0 = tx.inputs.last.copy(boxId = modifiedIn0.id)
-
- val in1 = from.last
- // existing token added to the last input
- val modifiedIn1 = testBox(in1.value, in1.ergoTree, in1.creationHeight,
- in1.additionalTokens.toArray.toSeq :+ existingToken, in1.additionalRegisters, in1.transactionId, in1.index)
- val txInMod1 = tx.inputs.last.copy(boxId = modifiedIn1.id)
-
- val out0 = tx.outputs.last
- // new token added to the last output
- val modifiedOut0 = testBox(out0.value, out0.ergoTree, out0.creationHeight,
- out0.additionalTokens.toArray.toSeq :+ randomToken, out0.additionalRegisters, out0.transactionId, out0.index)
- // existing token added to the last output
- val modifiedOut1 = testBox(out0.value, out0.ergoTree, out0.creationHeight,
- out0.additionalTokens.toArray.toSeq :+ existingToken, out0.additionalRegisters, out0.transactionId, out0.index)
-
- // update transaction inputs and outputs accordingly
- val txMod0 = tx.copy(inputs = tx.inputs.init :+ txInMod0) // new token group added to one input
- val txMod1 = tx.copy(inputs = tx.inputs.init :+ txInMod1) // existing token added to one input
- val txMod2 = tx.copy(inputs = tx.inputs.init :+ txInMod0, // new token group added to one input and one output
- outputCandidates = tx.outputCandidates.init :+ modifiedOut0)
- val txMod3 = tx.copy(inputs = tx.inputs.init :+ txInMod1, // existing token added to one input and one output
- outputCandidates = tx.outputCandidates.init :+ modifiedOut1)
-
- val inputIncTxCost0 = txMod0.statefulValidity(from.init :+ modifiedIn0, emptyDataBoxes, emptyStateContext).get
- val inputIncTxCost1 = txMod1.statefulValidity(from.init :+ modifiedIn1, emptyDataBoxes, emptyStateContext).get
- val outputIncTxCost0 = txMod2.statefulValidity(from.init :+ modifiedIn0, emptyDataBoxes, emptyStateContext).get
- val outputIncTxCost1 = txMod3.statefulValidity(from.init :+ modifiedIn1, emptyDataBoxes, emptyStateContext).get
-
- (inputIncTxCost0 - initTxCost) shouldEqual Parameters.TokenAccessCostDefault * 2 // one more group + one more token in total
- (inputIncTxCost1 - initTxCost) shouldEqual Parameters.TokenAccessCostDefault // one more token in total
- (outputIncTxCost0 - inputIncTxCost0) shouldEqual Parameters.TokenAccessCostDefault * 2
- (outputIncTxCost1 - inputIncTxCost1) shouldEqual Parameters.TokenAccessCostDefault
- }
- }
-
- property("spam simulation (transaction validation cost with too many tokens exceeds block limit)") {
- val bxsQty = 392 // with greater value test is failing with collection size exception
- val (inputs, tx) = validErgoTransactionGenTemplate(1, 1,16).sample.get // it takes too long to test with `forAll`
- val tokens = (0 until 255).map(_ => (scorex.util.Random.randomBytes().toTokenId, Random.nextLong))
- val (in, out) = {
- val in0 = inputs.head
- val out0 = tx.outputs.head
- val inputsMod = (0 until bxsQty).map { i =>
- testBox(10000000000L, in0.ergoTree, in0.creationHeight,
- tokens, in0.additionalRegisters, in0.transactionId, i.toShort)
- }
- val outputsMod = (0 until bxsQty).map { i =>
- testBox(10000000000L, out0.ergoTree, out0.creationHeight,
- tokens, out0.additionalRegisters, out0.transactionId, i.toShort)
- }
- inputsMod -> outputsMod
- }
- val inputsPointers = {
- val inSample = tx.inputs.head
- (0 until bxsQty).map(i => inSample.copy(boxId = in(i).id))
- }
- val txMod = tx.copy(inputs = inputsPointers, outputCandidates = out)
- val validFailure = txMod.statefulValidity(in, emptyDataBoxes, emptyStateContext)
- validFailure.failed.get.getMessage should startWith(ValidationRules.errorMessage(txAssetsInOneBox, "", emptyModifierId, ErgoTransaction.modifierTypeId).take(30))
- }
-
- property("transaction with too many inputs should be rejected") {
-
- //we assume that verifier must finish verification of any script in less time than 250K hash calculations
- // (for the Blake2b256 hash function over a single block input)
- val Timeout: Long = {
- val hf = Blake2b256
-
- //just in case to heat up JVM
- (1 to 5000000).foreach(i => hf(s"$i-$i"))
-
- val t0 = System.currentTimeMillis()
- (1 to 250000).foreach(i => hf(s"$i"))
- val t = System.currentTimeMillis()
- t - t0
- }
-
- val gen = validErgoTransactionGenTemplate(0, 0, 2000, trueLeafGen)
- val (from, tx) = gen.sample.get
- tx.statelessValidity().isSuccess shouldBe true
-
- //check that spam transaction is being rejected quickly
- implicit val verifier: ErgoInterpreter = ErgoInterpreter(parameters)
- val (validity, time0) = BenchmarkUtil.measureTime(tx.statefulValidity(from, IndexedSeq(), emptyStateContext))
- validity.isSuccess shouldBe false
- assert(time0 <= Timeout)
-
- val cause = validity.failed.get.getMessage
- cause should startWith(ValidationRules.errorMessage(bsBlockTransactionsCost, "", emptyModifierId, ErgoTransaction.modifierTypeId).take(30))
-
- //check that spam transaction validation with no cost limit is indeed taking too much time
- import Parameters._
- val maxCost = (Int.MaxValue - 10) / 10 // cannot use Int.MaxValue directly due to overflow when it is converted to block cost
- val ps = Parameters(0, DefaultParameters.updated(MaxBlockCostIncrease, maxCost), emptyVSUpdate)
- val sc = new ErgoStateContext(Seq.empty, None, genesisStateDigest, ps, ErgoValidationSettings.initial,
- VotingData.empty)(settings)
- .upcoming(org.ergoplatform.mining.group.generator,
- 0L,
- settings.chainSettings.initialNBits,
- Array.fill(3)(0.toByte),
- ErgoValidationSettingsUpdate.empty,
- 0.toByte)
- val (_, time) = BenchmarkUtil.measureTime(
- tx.statefulValidity(from, IndexedSeq(), sc)(verifier)
- )
-
- assert(time > Timeout)
- }
-
- property("transaction cost") {
- def paramsWith(manualCost: Int) = Parameters(
- 0,
- Parameters.DefaultParameters + (MaxBlockCostIncrease -> manualCost),
- ErgoValidationSettingsUpdate.empty
- )
-
- val gen = validErgoTransactionGenTemplate(0, 0,10, trueLeafGen)
- val (from, tx) = gen.sample.get
- tx.statelessValidity().isSuccess shouldBe true
-
- // calculate costs manually
- val initialCost: Long =
- tx.inputs.size * parameters.inputCost +
- tx.dataInputs.size * parameters.dataInputCost +
- tx.outputs.size * parameters.outputCost +
- ErgoInterpreter.interpreterInitCost
- val (outAssets, outAssetsNum) = tx.outAssetsTry.get
- val (inAssets, inAssetsNum) = ErgoBoxAssetExtractor.extractAssets(from).get
- val totalAssetsAccessCost =
- (outAssetsNum + inAssetsNum) * parameters.tokenAccessCost +
- (inAssets.size + outAssets.size) * parameters.tokenAccessCost
- val scriptsValidationCosts = tx.inputs.size + 1 // +1 for the block to JIT cost scaling
- println(s"tx.inputs.size: ${tx.inputs.size}")
- println(s"initialCost + totalAssetsAccessCost: ${initialCost + totalAssetsAccessCost}")
- val approxCost: Int = (initialCost + totalAssetsAccessCost + scriptsValidationCosts).toInt
-
-
- // check that validation pass if cost limit equals to approximated cost
- val sc = stateContextWith(paramsWith(approxCost))
- sc.currentParameters.maxBlockCost shouldBe approxCost
- val calculatedCost = tx.statefulValidity(from, IndexedSeq(), sc)(ErgoInterpreter(sc.currentParameters)).get
- approxCost - calculatedCost <= 1 shouldBe true
-
- // transaction exceeds computations limit
- val sc2 = stateContextWith(paramsWith(approxCost - 1))
- tx.statefulValidity(from, IndexedSeq(), sc2)(ErgoInterpreter(sc2.currentParameters)) shouldBe 'failure
-
- // transaction exceeds computations limit due to non-zero accumulatedCost
- tx.statefulValidity(from, IndexedSeq(), sc, accumulatedCost = 1)(ErgoInterpreter(sc.currentParameters)) shouldBe 'failure
- }
-
- property("cost accumulated correctly across inputs") {
- val accInitCost = 100000
-
- def inputCost(tx: ErgoTransaction, from: IndexedSeq[ErgoBox]): Long = {
- val idx = 0
- val input = tx.inputs(idx)
- val proof = input.spendingProof
- val transactionContext = TransactionContext(from, IndexedSeq(), tx)
- val inputContext = InputContext(idx.toShort, proof.extension)
-
- val ctx = new ErgoContext(
- emptyStateContext, transactionContext, inputContext,
- costLimit = emptyStateContext.currentParameters.maxBlockCost,
- initCost = 0)
-
- val messageToSign = tx.messageToSign
-
- val inputCost = verifier.verify(from(idx).ergoTree, ctx, proof, messageToSign).get._2
-
- inputCost
- }
-
- forAll(smallPositiveInt) { inputsNum =>
-
- val nonTrivialTrueGen = Gen.const(AND(Seq(TrueLeaf, TrueLeaf)).toSigmaProp.treeWithSegregation)
- val gen = validErgoTransactionGenTemplate(0, 0, inputsNum, nonTrivialTrueGen)
- val (from, tx) = gen.sample.get
- tx.statelessValidity().isSuccess shouldBe true
-
- tx.inputs.length shouldBe inputsNum
-
- val tokenAccessCost = emptyStateContext.currentParameters.tokenAccessCost
-
- val txCost = tx.statefulValidity(from, IndexedSeq(), emptyStateContext, accInitCost).get
-
- val (inAssets, inAssetsNum): (Map[Seq[Byte], Long], Int) = ErgoBoxAssetExtractor.extractAssets(from).get
- val (outAssets, outAssetsNum): (Map[Seq[Byte], Long], Int) = ErgoBoxAssetExtractor.extractAssets(tx.outputs).get
-
- val assetsCost = inAssetsNum * tokenAccessCost + inAssets.size * tokenAccessCost +
- outAssetsNum * tokenAccessCost + outAssets.size * tokenAccessCost
-
- val unsignedTx = UnsignedErgoTransaction(tx.inputs, tx.dataInputs, tx.outputCandidates)
- val signerTxCost =
- defaultProver.signInputs(unsignedTx, from, Vector.empty, emptyStateContext, TransactionHintsBag.empty).get._2
-
- val signerTxCostWithInitCost = signerTxCost + accInitCost
- signerTxCostWithInitCost shouldBe txCost // signer and verifier costs should be the same
-
- val initialCost: Long =
- tx.inputs.size * parameters.inputCost +
- tx.dataInputs.size * parameters.dataInputCost +
- tx.outputs.size * parameters.outputCost +
- ErgoInterpreter.interpreterInitCost +
- assetsCost
-
- txCost shouldBe (accInitCost + initialCost + inputCost(tx, from) * inputsNum)
- }
- }
-
- property("monotonic creation height") {
- def stateContext(height: Int, blockVersion: Byte): ErgoStateContext = {
- val header = defaultHeaderGen.sample.get.copy(version = blockVersion, height = height)
- val params = Parameters(LaunchParameters.height,
- LaunchParameters.parametersTable.updated(Parameters.BlockVersion, blockVersion),
- LaunchParameters.proposedUpdate)
- new ErgoStateContext(Seq(header), None, genesisStateDigest, params, ErgoValidationSettings.initial,
- VotingData.empty)(settings)
- }
-
- def stateContextForTx(tx: ErgoTransaction, blockVersion: Byte): ErgoStateContext = {
- stateContext(tx.outputs.map(_.creationHeight).max, blockVersion)
- }
-
- def updateOutputHeight(box: ErgoBoxCandidate, value: Int): ErgoBoxCandidate = {
- new ErgoBoxCandidate(box.value, box.ergoTree, value, box.additionalTokens, box.additionalRegisters)
- }
-
- def updateInputHeight(box: ErgoBox): ErgoBox = {
- val creationHeight = scala.util.Random.nextInt(1000) + 1
- new ErgoBox(box.value, box.ergoTree, box.additionalTokens, box.additionalRegisters,
- box.transactionId, box.index, creationHeight)
- }
-
- // retuns random transaction along with inputs,
- // and a boolean flag, if the latter is true, monotonic creation height rule holds,
- // otherwise, it does not hold
- val txGen = boxesGenTemplate(minAssets = 0, maxAssets = 5, minInputs = 5, maxInputs = 10, propositionGen = trueLeafGen).map { case (boxes, _) =>
- boxes.map(updateInputHeight)
- }.map{ boxes =>
- val fixed = Random.nextBoolean()
- val maxHeight = boxes.map(_.creationHeight).max
- val preUnsignedTx = validUnsignedTransactionFromBoxes(boxes)
- val unsignedTx = if(fixed) {
- preUnsignedTx.copy(outputCandidates = preUnsignedTx.outputCandidates.map{out =>
- val creationHeight = maxHeight + Random.nextInt(3)
- updateOutputHeight(out, creationHeight)
- })
- } else {
- preUnsignedTx.copy(outputCandidates = preUnsignedTx.outputCandidates.map{out =>
- val creationHeight = maxHeight - (Random.nextInt(maxHeight) + 1)
- updateOutputHeight(out, creationHeight)
- })
- }
- val tx = defaultProver.sign(unsignedTx, boxes, IndexedSeq.empty, emptyStateContext)
- .map(ErgoTransaction.apply)
- .get
- (boxes, tx, fixed)
- }
-
- forAll(txGen){ case (boxes, tx, fixed) =>
- // with initial block version == 1, monotonic rule does not work
- tx.statefulValidity(boxes, IndexedSeq.empty, stateContextForTx(tx, blockVersion = 1)).isSuccess shouldBe true
-
- // with pre-5.0 block version == 2, monotonic rule does not work as well
- tx.statefulValidity(boxes, IndexedSeq.empty, stateContextForTx(tx, blockVersion = 2)).isSuccess shouldBe true
-
- // starting from block version == 3, monotonic rule works,
- // so validation fails if transaction is not following the rule (fixed == false)
- val ctx3 = stateContextForTx(tx, blockVersion = 3)
- if (fixed) {
- tx.statefulValidity(boxes, IndexedSeq.empty, ctx3).isSuccess shouldBe true
- } else {
- val txFailure = tx.statefulValidity(boxes, IndexedSeq.empty, ctx3)
- txFailure.isSuccess shouldBe false
- val cause = txFailure.toEither.left.get.getMessage
- val expectedMessage = ValidationRules.errorMessage(ValidationRules.txMonotonicHeight, "", emptyModifierId, ErgoTransaction.modifierTypeId)
- cause should startWith(expectedMessage)
- }
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/modifiers/mempool/ExpirationSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/modifiers/mempool/ExpirationSpecification.scala
deleted file mode 100644
index 7398a9ce5f..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/modifiers/mempool/ExpirationSpecification.scala
+++ /dev/null
@@ -1,155 +0,0 @@
-package org.ergoplatform.modifiers.mempool
-
-import org.ergoplatform.nodeView.state.{ErgoStateContext, VotingData}
-import org.ergoplatform.settings.Constants
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.ergoplatform.wallet.interpreter.ErgoInterpreter
-import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, Input}
-import org.scalatest.Assertion
-import sigma.Colls
-import sigmastate.Values.ShortConstant
-import sigmastate.interpreter.{ContextExtension, ProverResult}
-import sigmastate.eval._
-import sigmastate.helpers.TestingHelpers._
-
-class ExpirationSpecification extends ErgoPropertyTest {
-
- type Height = Int
-
- private implicit val verifier: ErgoInterpreter = ErgoInterpreter(parameters)
-
- def falsify(box: ErgoBox): ErgoBox = {
- testBox(box.value,
- Constants.FalseLeaf,
- box.creationHeight,
- box.additionalTokens.toArray.toSeq,
- box.additionalRegisters,
- transactionId = box.transactionId,
- boxIndex = box.index)
- }
-
- def constructTest(from: ErgoBox,
- heightDelta: Int,
- outsConstructor: Height => IndexedSeq[ErgoBoxCandidate],
- expectedValidity: Boolean): Assertion = {
- // We are filtering out certain heights to avoid problems with improperly generated extension
- // at the beginning of a voting epoch
- whenever((from.creationHeight + Constants.StoragePeriod + heightDelta) % votingSettings.votingLength != 0) {
- val in = Input(from.id,
- ProverResult(Array.emptyByteArray, ContextExtension(Map(Constants.StorageIndexVarId -> ShortConstant(0)))))
-
- val h: Int = from.creationHeight + Constants.StoragePeriod + heightDelta
-
- val oc = outsConstructor(h).map(c => updateHeight(c, h))
- val tx = ErgoTransaction(inputs = IndexedSeq(in), dataInputs = IndexedSeq(), outputCandidates = oc)
-
- val fb0 = invalidErgoFullBlockGen.sample.get
- val fakeHeader = fb0.header.copy(height = h - 1)
- val fb = fb0.copy(fb0.header.copy(height = h, parentId = fakeHeader.id))
-
- val updContext = {
- val inContext = new ErgoStateContext(Seq(fakeHeader), None, genesisStateDigest, parameters, validationSettingsNoIl,
- VotingData.empty)(settings)
- inContext.appendFullBlock(fb).get
- }
-
- //serialization roundtrip
- val bs = ErgoTransactionSerializer.toBytes(tx)
- ErgoTransactionSerializer.parseBytes(bs) shouldBe tx
-
- tx.statelessValidity().isSuccess shouldBe true
- tx.statefulValidity(IndexedSeq(from), emptyDataBoxes, updContext).isSuccess shouldBe expectedValidity
- }
- }
-
- property("successful spending w. same value") {
- forAll(unspendableErgoBoxGen()) { from =>
- constructTest(from, 0, _ => IndexedSeq(from), expectedValidity = true)
- }
- }
-
- property("successful spending w. max spending") {
- forAll(unspendableErgoBoxGen()) { from =>
- constructTest(from, 0, h => {
- val fee = Math.min(parameters.storageFeeFactor * from.bytes.length, from.value)
- val feeBoxCandidate = new ErgoBoxCandidate(fee, Constants.TrueLeaf, creationHeight = h)
- IndexedSeq(changeValue(from, -fee), Some(feeBoxCandidate)).flatten
- }, expectedValidity = true)
- }
- }
-
- property("unsuccessful spending due too big storage fee charged") {
- forAll(unspendableErgoBoxGen(parameters.storageFeeFactor * 100 + 1, Long.MaxValue)) { from =>
- constructTest(from, 0, h => {
- val fee = Math.min(parameters.storageFeeFactor * from.bytes.length + 1, from.value)
- val feeBoxCandidate = new ErgoBoxCandidate(fee, Constants.TrueLeaf, creationHeight = h)
- IndexedSeq(changeValue(from, -fee), Some(feeBoxCandidate)).flatten
- }, expectedValidity = false)
- }
- }
-
- property("unsuccessful spending when more time passed than storage period and charged more than K*storagePeriod") {
- forAll(unspendableErgoBoxGen(parameters.storageFeeFactor * 100 + 1, Long.MaxValue)) { from =>
- constructTest(from, 1, h => {
- val fee = Math.min(parameters.storageFeeFactor * from.bytes.length + 1, from.value)
- val feeBoxCandidate = new ErgoBoxCandidate(fee, Constants.TrueLeaf, creationHeight = h)
-
- IndexedSeq(changeValue(from, -fee), Some(feeBoxCandidate)).flatten
- }, expectedValidity = false)
- }
- }
-
- property("too early spending") {
- forAll(unspendableErgoBoxGen()) { from =>
- constructTest(from, -1, h => {
- val fee = Math.min(parameters.storageFeeFactor * from.bytes.length, from.value)
- val feeBoxCandidate = new ErgoBoxCandidate(fee, Constants.TrueLeaf, creationHeight = h)
- IndexedSeq(changeValue(from, -fee), Some(feeBoxCandidate)).flatten
- }, expectedValidity = false)
- }
- }
-
- property("script changed spending w. same value") {
- forAll(unspendableErgoBoxGen()) { from =>
- val out = new ErgoBoxCandidate(from.value, Constants.TrueLeaf, from.creationHeight + 1, from.additionalTokens)
- constructTest(from, 0, _ => IndexedSeq(out), expectedValidity = false)
- }
- }
-
- property("script changed tokens w. same value") {
- forAll(unspendableErgoBoxGen()) { from =>
- whenever(from.additionalTokens.nonEmpty) {
- val out = new ErgoBoxCandidate(from.value, from.ergoTree, from.creationHeight + 1, Colls.emptyColl)
- constructTest(from, 0, _ => IndexedSeq(out), expectedValidity = false)
- }
- }
- }
-
- property("script changed register w. same value") {
- forAll(unspendableErgoBoxGen()) { from =>
- whenever(from.additionalRegisters.get(ErgoBox.R4).nonEmpty) {
- val out = new ErgoBoxCandidate(from.value, from.ergoTree, from.creationHeight + 1, from.additionalTokens)
- constructTest(from, 0, _ => IndexedSeq(out), expectedValidity = false)
- }
- }
- }
-
- property("spending of whole coin when its value no more than storage fee") {
- val out2 = ergoBoxGenNoProp.sample.get
- val minValue = out2.value + 1
-
- forAll(unspendableErgoBoxGen(minValue, Long.MaxValue)) { from =>
- val outcome = from.value <= from.bytes.length * parameters.storageFeeFactor
- val out1 = new ErgoBoxCandidate(from.value - minValue, Constants.TrueLeaf, creationHeight = from.creationHeight + 1)
- constructTest(from, 0, _ => IndexedSeq(out1, out2), expectedValidity = outcome)
- }
- }
-
- property("destructing the whole box when its value no more than storage fee") {
- forAll(unspendableErgoBoxGen(maxValue = parameters.storageFeeFactor)) { from =>
- val out = new ErgoBoxCandidate(from.value, Constants.TrueLeaf, creationHeight = from.creationHeight + 1)
- constructTest(from, 0, _ => IndexedSeq(out), expectedValidity = true)
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/ActivePeerFilteringSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/ActivePeerFilteringSpecification.scala
deleted file mode 100644
index 8271050c45..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/ActivePeerFilteringSpecification.scala
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.ergoplatform.network
-
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.core.network.peer.PeerInfo
-import scorex.core.network.peer.PeerManager.ReceivableMessages.SeenPeers
-
-import java.net.{InetAddress, InetSocketAddress}
-
-class ActivePeerFilteringSpecification extends ErgoPropertyTest {
-
- private val filter: SeenPeers = SeenPeers(5)
-
- private def newPeer(address: String, port: Int, lastHandshakeOffset: Long): (InetSocketAddress, PeerInfo) = {
- val addr = new InetSocketAddress(address, port)
- val pi = PeerInfo(
- defaultPeerSpec.copy(declaredAddress = Some(addr)),
- System.currentTimeMillis() - lastHandshakeOffset,
- None,
- System.currentTimeMillis() - lastHandshakeOffset
- )
- (addr, pi)
- }
-
- private val knownPeers: Map[InetSocketAddress, PeerInfo] = Map(
- newPeer("1.2.3.4", 1234, 12340), // blacklisted
- newPeer("2.3.4.1", 2341, 23410),
- newPeer("3.4.1.2", 3412, 34120),
- newPeer("4.1.2.3", 4123, 41230 + filter.limit), // over limit
- )
-
- private val blacklistedPeers: Seq[InetAddress] = Seq(InetAddress.getByName("1.2.3.4"))
-
- private val correct: Seq[PeerInfo] = knownPeers.toSeq.slice(1,3).map(_._2)
-
- property("time based activity filter") {
-
- val result: Seq[PeerInfo] =
- filter.choose(knownPeers, blacklistedPeers, null).sortBy(-_.lastHandshake) // sort to undo Random.shuffle
-
- result.size shouldBe 2
- result shouldBe correct
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/DecodingUtils.scala b/ergo-core/src/test/scala/org/ergoplatform/network/DecodingUtils.scala
deleted file mode 100644
index cecc865a23..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/DecodingUtils.scala
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.ergoplatform.network
-
-import java.nio.ByteBuffer
-
-// Common functions used in parsers, collected in one place to be easily understood and rewritten into other languages
-trait DecodingUtils {
-
- /**
- * Read unsigned byte
- */
- def getUByte(buf: ByteBuffer): Int = getByte(buf) & 0xFF
-
- /**
- * Read signed byte
- */
- def getByte(buf: ByteBuffer): Byte = buf.get
-
- /**
- * Reading up to 64 bits VLQ-encoded value. The value is considered to be signed.
- * Can be read less than 64 bytes!
- * See https://en.wikipedia.org/wiki/Variable-length_quantity
- */
- def getULong(buf: ByteBuffer): Long = {
- var result: Long = 0
- var shift = 0
- while (shift < 64) {
- val b = getByte(buf)
- result = result | ((b & 0x7F).toLong << shift)
- if ((b & 0x80) == 0) return result
- shift += 7
- }
- throw new IllegalStateException("Trying to read long, but more bytes than needed found")
- }
-
- /**
- * Read signed int (32 bits) value
- **/
- def getInt(buf: ByteBuffer): Int = {
- // should only be changed simultaneously with `putInt`
- decodeZigZagInt(getULong(buf).toInt)
- }
-
-
- /**
- * Read `size` bytes
- */
- def getBytes(buf: ByteBuffer, size: Int): Array[Byte] = {
- val res = new Array[Byte](size)
- buf.get(res)
- res
- }
-
- /**
- * Decode ZigZag-encoded (32 bits) integer
- */
- def decodeZigZagInt(n: Int): Int = {
- // source: http://github.com/google/protobuf/blob/a7252bf42df8f0841cf3a0c85fdbf1a5172adecb/java/core/src/main/java/com/google/protobuf/CodedInputStream.java#L553
- (n >>> 1) ^ -(n & 1)
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/ElementPartitionerSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/ElementPartitionerSpecification.scala
deleted file mode 100644
index 3104f18265..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/ElementPartitionerSpecification.scala
+++ /dev/null
@@ -1,121 +0,0 @@
-package org.ergoplatform.network
-
-import org.scalacheck.Gen
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-
-
-class ElementPartitionerSpecification
- extends AnyPropSpec
- with ScalaCheckPropertyChecks
- with Matchers {
-
- def distribute[B, T, I](buckets: Iterable[B],
- maxElements: Int,
- minElementsPerBucket: Int,
- maxElementsPerBucket: Int
- )(fetchMax: Int => Map[T, Seq[I]]): Map[(B, T), Seq[I]] = {
- val peersCount = buckets.size
- val maxElementsToFetch = Math.min(maxElements, peersCount * maxElementsPerBucket)
- val fetched = if (maxElementsToFetch <= 0) {
- Map.empty[T, Seq[I]]
- } else {
- fetchMax(maxElementsToFetch)
- }
- ElementPartitioner.distribute(buckets, minElementsPerBucket, fetched)
- }
-
- property("elements should be evenly distributed in buckets limited by bucket size") {
- forAll(Gen.nonEmptyListOf(Gen.alphaNumChar), Gen.nonEmptyListOf(Gen.alphaNumChar)) {
- case (buckets, elements) =>
- val (elemsType_1, elemsType_2) = elements.splitAt(elements.size / 2)
- val elemsByBucket =
- distribute(buckets, Integer.MAX_VALUE, 1, 5) { count =>
- count shouldBe buckets.size * 5
- Map("A" -> elemsType_1.take(count), "B" -> elemsType_2.take(count))
- }
- elemsByBucket shouldNot be(empty)
- elemsByBucket.forall(_._2.nonEmpty) shouldBe true
- elemsByBucket.map(_._2.size).toSet.size <= 2 shouldBe true // evenly distributed
- elemsByBucket.forall(_._2.size <= 5) shouldBe true // max sized batches
- }
- }
-
- property("elements should never reach max elements") {
- forAll(Gen.nonEmptyListOf(Gen.alphaNumChar), Gen.nonEmptyListOf(Gen.alphaNumChar)) {
- case (buckets, elements) =>
- val (elemsType_1, elemsType_2) = elements.splitAt(elements.size / 2)
- val elemsByBucket = distribute(buckets, 5, 1, 100) { count =>
- count shouldBe 5
- Map("A" -> elemsType_1.take(count), "B" -> elemsType_2.take(count))
- }
- elemsByBucket.map(_._2.size).sum <= 2 * 5 shouldBe true // max size of elements
- }
- }
-
- property(
- "bucket should contain less elements than minElementsPerBucket only if not enough elements is available"
- ) {
- forAll(Gen.listOf(Gen.alphaNumChar), Gen.listOf(Gen.alphaNumChar)) {
- case (buckets, elements) =>
- val elemsByBucket =
- distribute(buckets, Integer.MAX_VALUE, 5, 10) { count =>
- assert(count <= 10 * buckets.size)
- Map("A" -> elements.take(count))
- }
- // if there is only 4 elements available to download, then bucket may contain only 4 elements regardless of minElementsPerBucket=5
- if (elements.size >= 5) {
- elemsByBucket.map(_._2.size).foreach { count =>
- assert(count >= 5 && count <= 10)
- }
- }
- }
- }
-
- property("empty buckets or elements cannot be partitioned") {
- distribute(List.empty, Integer.MAX_VALUE, 1, 5)(_ => Map("A" -> List(1)))
- .size shouldBe 0
- distribute(List(1), Integer.MAX_VALUE, 1, 5)(_ => Map.empty[String, Seq[Int]])
- .size shouldBe 0
- distribute(List.empty, Integer.MAX_VALUE, 1, 5)(_ => Map.empty[String, Seq[Int]])
- .size shouldBe 0
- }
-
- property("0 or negative count of elements to fetch cannot be partitioned") {
- distribute(List.empty, -1, 1, 5)(_ => Map("A" -> List(1)))
- .size shouldBe 0
- distribute(List.empty, 5, 1, 0)(_ => Map("A" -> List(1)))
- .size shouldBe 0
- }
-
- property("less or equal elements than buckets should return one element per bucket") {
- distribute(List(1, 2, 3), Integer.MAX_VALUE, 1, 5) { _ =>
- Map("A" -> List(1))
- } shouldBe Map((1, "A") -> List(1))
- }
-
- property("elements should be distributed into bucket-types") {
- distribute(List(1, 2), Integer.MAX_VALUE, 1, 1) { _ =>
- Map("A" -> List(1, 2), "B" -> List(1, 2), "C" -> List(1, 2))
- } shouldBe Map(
- (2, "B") -> List(2),
- (1, "C") -> List(1),
- (1, "B") -> List(1),
- (1, "A") -> List(1),
- (2, "C") -> List(2),
- (2, "A") -> List(2)
- )
- }
-
- property(
- "minElementsPerBucket constraint should not be used if there is less elements available"
- ) {
- val elems =
- distribute(List(1), Integer.MAX_VALUE, 100, 1) { _ =>
- Map("A" -> List(1))
- }
- elems.size shouldBe 1
- elems.head._2.size shouldBe 1
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/ErgoNodeViewSynchronizerSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/ErgoNodeViewSynchronizerSpecification.scala
deleted file mode 100644
index 2430aa7728..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/ErgoNodeViewSynchronizerSpecification.scala
+++ /dev/null
@@ -1,452 +0,0 @@
-package org.ergoplatform.network
-
-import akka.actor.{ActorRef, ActorSystem, Cancellable, Props}
-import akka.testkit.TestProbe
-import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer}
-import org.ergoplatform.modifiers.{BlockSection, ErgoFullBlock}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages._
-import org.ergoplatform.nodeView.ErgoNodeViewHolder
-import org.ergoplatform.nodeView.history.{ErgoHistory, ErgoHistoryReader, ErgoSyncInfoMessageSpec, ErgoSyncInfoV2}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
-import org.ergoplatform.nodeView.state.{StateType, UtxoState}
-import org.ergoplatform.sanity.ErgoSanity._
-import org.ergoplatform.settings.ErgoSettings
-import org.ergoplatform.utils.HistoryTestHelpers
-import org.ergoplatform.wallet.utils.FileUtils
-import org.scalacheck.Gen
-import org.scalatest.concurrent.Eventually
-import org.scalatest.matchers.should.Matchers
-import scorex.core.PersistentNodeViewModifier
-import scorex.core.network.ModifiersStatus.{Received, Unknown}
-import scorex.core.network.NetworkController.ReceivableMessages.SendToNetwork
-import scorex.core.network.message._
-import scorex.core.network.peer.PeerInfo
-import scorex.core.network.{ConnectedPeer, DeliveryTracker}
-import scorex.core.serialization.ErgoSerializer
-import scorex.testkit.utils.AkkaFixture
-
-import scala.concurrent.duration.{Duration, _}
-import scala.concurrent.{Await, ExecutionContext, ExecutionContextExecutor}
-import scala.language.postfixOps
-
-class ErgoNodeViewSynchronizerSpecification extends HistoryTestHelpers with Matchers with FileUtils with Eventually {
-
- // ToDo: factor this out of here and NVHTests?
- private def withFixture(testCode: SynchronizerFixture => Any): Unit = {
- val fixture = new SynchronizerFixture
- try {
- testCode(fixture)
- }
- finally {
- Await.result(fixture.system.terminate(), Duration.Inf)
- }
- }
-
- private def withFixture2(testCode: Synchronizer2Fixture => Any): Unit = {
- val fixture = new Synchronizer2Fixture
- try {
- testCode(fixture)
- }
- finally {
- Await.result(fixture.system.terminate(), Duration.Inf)
- }
- }
-
- class NodeViewHolderMock extends ErgoNodeViewHolder[UtxoState](settings)
-
- class SynchronizerMock(networkControllerRef: ActorRef,
- viewHolderRef: ActorRef,
- syncInfoSpec: ErgoSyncInfoMessageSpec.type,
- settings: ErgoSettings,
- syncTracker: ErgoSyncTracker,
- deliveryTracker: DeliveryTracker)
- (implicit ec: ExecutionContext) extends ErgoNodeViewSynchronizer(
- networkControllerRef,
- viewHolderRef,
- syncInfoSpec,
- settings,
- syncTracker,
- deliveryTracker)(ec) {
-
- protected def broadcastInvForNewModifier(mod: PersistentNodeViewModifier): Unit = {
- mod match {
- case fb: ErgoFullBlock if fb.header.isNew(1.hour) =>
- fb.toSeq.foreach(s => broadcastModifierInv(s))
- case h: Header if h.isNew(1.hour) =>
- broadcastModifierInv(h)
- case _ =>
- }
- }
- }
-
- override implicit val patienceConfig: PatienceConfig = PatienceConfig(2.seconds, 100.millis)
- val history = generateHistory(verifyTransactions = true, StateType.Utxo, PoPoWBootstrap = false, blocksToKeep = -1)
- val chain = genHeaderChain(2000, history, diffBitsOpt = None, useRealTs = false)
- val localChain = chain.take(1000)
- val altchain = genHeaderChain(1000, history, diffBitsOpt = None, useRealTs = false)
-
- val forkedChain = {
- val c = localChain.take(1000 - 512)
- c ++ genHeaderChain(512, Some(c.last), diffBitsOpt = None, useRealTs = false).tail
- }
- val forkedHeight = forkedChain.last.height
-
- val localHistoryGen: Gen[HT] = {
- require(history.isEmpty)
- applyHeaderChain(history, localChain)
- }
-
- val localStateGen: Gen[WrappedUtxoState] =
- boxesHolderGen.map(WrappedUtxoState(_, createTempDir, None, parameters, settings))
-
- def semanticallyValidModifier(state: UTXO_ST): PM = {
- statefulyValidFullBlock(state.asInstanceOf[WrappedUtxoState])
- }
-
- def semanticallyInvalidModifier(state: UTXO_ST): PM = invalidErgoFullBlockGen.sample.get
-
- def totallyValidModifier(history: HT, state: UTXO_ST): PM = {
- val parentOpt = history.bestFullBlockOpt
- validFullBlock(parentOpt, state.asInstanceOf[WrappedUtxoState]).header
- }
-
- def totallyValidModifiers(history: HT, state: UTXO_ST, count: Int): Seq[PM] = {
- require(count >= 1)
- val headerOpt = history.bestFullBlockOpt
- (0 until count).foldLeft((headerOpt, Seq.empty[PM])) { case (acc, _) =>
- val pm = validFullBlock(headerOpt, state.asInstanceOf[WrappedUtxoState])
- (Some(pm), acc._2 :+ pm)
- }._2.map(_.asInstanceOf[ErgoFullBlock].header)
- }
-
- def nodeViewSynchronizer(implicit system: ActorSystem):
- (ActorRef, ActorRef, SI, PM, TX, ConnectedPeer, TestProbe, TestProbe, TestProbe, ErgoSerializer[PM], DeliveryTracker) = {
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val h = localHistoryGen.sample.get
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val s = localStateGen.sample.get
- val settings = ErgoSettings.read()
- val pool = ErgoMemPool.empty(settings)
- implicit val ec: ExecutionContextExecutor = system.dispatcher
- val ncProbe = TestProbe("NetworkControllerProbe")
- val pchProbe = TestProbe("PeerHandlerProbe")
- val eventListener = TestProbe("EventListener")
- val syncTracker = ErgoSyncTracker(settings.scorexSettings.network)
- val deliveryTracker: DeliveryTracker = DeliveryTracker.empty(settings)
-
- // each test should always start with empty history
- deleteRecursive(ErgoHistory.historyDir(settings))
- val nodeViewHolderMockRef = system.actorOf(Props(new NodeViewHolderMock))
-
- val synchronizerMockRef = system.actorOf(Props(
- new SynchronizerMock(
- ncProbe.ref,
- nodeViewHolderMockRef,
- ErgoSyncInfoMessageSpec,
- settings,
- syncTracker,
- deliveryTracker)
- ))
- val m = totallyValidModifier(h, s)
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val tx = validErgoTransactionGenTemplate(0, 0).sample.get._2
-
- val peerInfo = PeerInfo(defaultPeerSpec, System.currentTimeMillis())
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val p: ConnectedPeer = ConnectedPeer(
- connectionIdGen.sample.get,
- pchProbe.ref,
- Some(peerInfo)
- )
- synchronizerMockRef ! ChangedHistory(history)
- synchronizerMockRef ! ChangedMempool(pool)
- val serializer: ErgoSerializer[PM] = HeaderSerializer.asInstanceOf[ErgoSerializer[PM]]
- (synchronizerMockRef, nodeViewHolderMockRef, h.syncInfoV1, m, tx, p, pchProbe, ncProbe, eventListener, serializer, deliveryTracker)
- }
-
- class SynchronizerFixture extends AkkaFixture {
- @SuppressWarnings(Array("org.wartremover.warts.PublicInference"))
- val (synchronizer, nodeViewHolder, syncInfo, mod, tx, peer, pchProbe, ncProbe, eventListener, modSerializer, deliveryTracker) = nodeViewSynchronizer
- }
-
- class Synchronizer2Fixture extends AkkaFixture {
- implicit val ec: ExecutionContextExecutor = system.dispatcher
- val ncProbe = TestProbe("NetworkControllerProbe")
- val pchProbe = TestProbe("PeerHandlerProbe")
- val syncTracker = ErgoSyncTracker(settings.scorexSettings.network)
- val deliveryTracker: DeliveryTracker = DeliveryTracker.empty(settings)
-
- // each test should always start with empty history
- deleteRecursive(ErgoHistory.historyDir(settings))
- val nodeViewHolderMockRef = system.actorOf(Props(new NodeViewHolderMock))
-
- val synchronizerMockRef = system.actorOf(Props(
- new SynchronizerMock(
- ncProbe.ref,
- nodeViewHolderMockRef,
- ErgoSyncInfoMessageSpec,
- settings,
- syncTracker,
- deliveryTracker)
- ))
-
- val peerInfo = PeerInfo(defaultPeerSpec, System.currentTimeMillis())
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val peer: ConnectedPeer = ConnectedPeer(
- connectionIdGen.sample.get,
- pchProbe.ref,
- Some(peerInfo)
- )
- }
-
- property("NodeViewSynchronizer: Message: SyncInfoSpec V2 - younger peer") {
- withFixture { ctx =>
- import ctx._
-
- val emptySync = ErgoSyncInfoV2(Seq.empty)
-
- // Neighbour is sending
- val msgBytes = ErgoSyncInfoMessageSpec.toBytes(emptySync)
-
- // we check that in case of neighbour with empty history (it has no any blocks),
- // inv message with our block ids will be sent
- synchronizer ! Message(ErgoSyncInfoMessageSpec, Left(msgBytes), Some(peer))
- ncProbe.fishForMessage(3 seconds) { case m =>
- m match {
- case stn: SendToNetwork =>
- val msg = stn.message
- msg.spec.messageCode == InvSpec.messageCode &&
- msg.data.get.asInstanceOf[InvData].ids.head == chain.head.id
- case _ => false
- }
- }
- }
- }
-
- property("NodeViewSynchronizer: receiving valid header") {
- withFixture { ctx =>
- import ctx._
- deliveryTracker.reset()
- deliveryTracker.setRequested(Header.modifierTypeId, chain.take(1001).last.id, peer)(_ => Cancellable.alreadyCancelled)
- val olderChain = chain.take(1001)
- val modData = ModifiersData(Header.modifierTypeId, Map(olderChain.last.id -> olderChain.last.bytes))
- val modSpec = ModifiersSpec
- synchronizer ! Message(modSpec, Left(modSpec.toBytes(modData)), Some(peer))
- // desired state of submitting valid headers is Received
- eventually {
- deliveryTracker.status(olderChain.last.id, Header.modifierTypeId, Seq.empty) shouldBe Received
- }
- }
- }
-
- property("NodeViewSynchronizer: apply continuation header from syncV2 and download its block") {
- withFixture2 { ctx =>
- import ctx._
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 100.millis)
-
- // we generate and apply existing base chain
- val hhistory = ErgoHistory.readOrGenerate(settings)(null)
- val baseChain = genHeaderChain(_.size > 4, None, hhistory.difficultyCalculator, None, false)
- baseChain.headers.foreach(hhistory.append)
- val bestHeaderOpt = hhistory.bestHeaderOpt
-
- // then a continuation chain that will be part of the syncV2 message
- val continuationChain = genHeaderChain(_.size > 4, bestHeaderOpt, hhistory.difficultyCalculator, None, false).tail
-
- // sync message carries best header of our base change + continuation chain whose Head header is supposed to be applied
- val sync = ErgoSyncInfoV2(continuationChain.headers)
- val msgBytes = ErgoSyncInfoMessageSpec.toBytes(sync)
-
- // send this sync msg to synchronizer which should apply the header following the common header from base chain
- synchronizerMockRef ! Message(ErgoSyncInfoMessageSpec, Left(msgBytes), Some(peer))
- val appliedHeader = continuationChain.headers.head
- // calculate block sections for applied header and test whether they were attempted to be downloaded from remote peer
- var remainingSectionIds = hhistory.requiredModifiersForHeader(appliedHeader).groupBy(_._1).mapValues(_.map(_._2).head)
- while (remainingSectionIds.nonEmpty) {
- ncProbe.fishForMessage(3 seconds) { case m =>
- m match {
- case stn: SendToNetwork if stn.message.spec.messageCode == RequestModifierSpec.messageCode =>
- val invData = stn.message.data.get.asInstanceOf[InvData]
- remainingSectionIds.exists { case (sectionTypeId, sectionId) =>
- val sectionFound = invData.typeId == sectionTypeId && invData.ids.head == sectionId
- if (sectionFound) {
- remainingSectionIds = remainingSectionIds - sectionTypeId
- }
- sectionFound
- }
- case _ =>
- false
- }
- }
- }
- eventually {
- // test whether applied header was actually persisted to history
- val hist = ErgoHistory.readOrGenerate(settings)(null)
- hist.bestHeaderIdOpt.get shouldBe appliedHeader.id
- }
- }
- }
-
- property("NodeViewSynchronizer: receiving out-of-order header should request it again") {
- withFixture2 { ctx =>
- import ctx._
-
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.seconds, 100.millis)
-
- def sendHeader(header: Header): Unit = {
- deliveryTracker.setRequested(Header.modifierTypeId, header.id, peer)(_ => Cancellable.alreadyCancelled)
- val modData = ModifiersData(Header.modifierTypeId, Map(header.id -> header.bytes))
- val modSpec = ModifiersSpec
- synchronizerMockRef ! Message(modSpec, Left(modSpec.toBytes(modData)), Some(peer))
- }
-
- deliveryTracker.reset()
-
- // we generate fork of two headers, starting from the parent of the best header
- // so the depth of the rollback is 1, and the fork bypasses the best chain by 1 header
- val hhistory = ErgoHistory.readOrGenerate(settings)(null)
- val newHeaders = genHeaderChain(2, hhistory, diffBitsOpt = None, useRealTs = false).headers
- val newHistory = newHeaders.foldLeft(hhistory) { case (hist, header) => hist.append(header).get._1 }
- val parentOpt = newHistory.lastHeaders(2).headOption
- val smallFork = genHeaderChain(_.size > 2, parentOpt, newHistory.difficultyCalculator, None, false)
- val secondForkHeader = smallFork.last
-
- sendHeader(secondForkHeader)
- // we submit header at best height + 1, but with parent not known, the status should be unknown,
- // so after some time the header could be downloaded again (when the parent may be known)
- eventually {
- deliveryTracker.status(secondForkHeader.id, Header.modifierTypeId, Seq.empty) shouldBe Unknown
- }
- }
- }
-
-
- property("NodeViewSynchronizer: longer fork is applied and shorter is not") {
- withFixture2 { ctx =>
- import ctx._
-
- def sendHeader(block: ErgoFullBlock): Unit = {
- deliveryTracker.setRequested(Header.modifierTypeId, block.header.id, peer)(_ => Cancellable.alreadyCancelled)
- val modData = ModifiersData(Header.modifierTypeId, Map(block.header.id -> block.header.bytes))
- synchronizerMockRef ! Message(ModifiersSpec, Left(ModifiersSpec.toBytes(modData)), Some(peer))
- }
-
- def sendBlockSection(block: BlockSection): Unit = {
- deliveryTracker.setRequested(block.modifierTypeId, block.id, peer)(_ => Cancellable.alreadyCancelled)
- val modData = ModifiersData(block.modifierTypeId, Map(block.id -> block.bytes))
- synchronizerMockRef ! Message(ModifiersSpec, Left(ModifiersSpec.toBytes(modData)), Some(peer))
- }
-
- def sendBlock(block: ErgoFullBlock): Unit = {
- sendBlockSection(block.blockTransactions)
- sendBlockSection(block.extension)
- block.adProofs.foreach(sendBlockSection(_))
- }
-
- deliveryTracker.reset()
-
- val hist = ErgoHistory.readOrGenerate(settings)(null)
- // generate smaller fork that is going to be reverted after applying a bigger fork
- val smallFork = genChain(4, hist)
-
- smallFork.foreach(sendHeader)
- // history should eventually contain all smaller fork headers
- eventually {
- smallFork.forall(block => hist.contains(block.id))
- }
- smallFork.foreach(sendBlock)
- // history should eventually contain smaller fork block parts
- eventually {
- smallFork.forall(block => hist.contains(block.extension.id) && hist.contains(block.blockTransactions.id))
- }
- // generate bigger fork that is going to win over smaller fork that is to be reverted
- val bigFork = genChain(20, hist, extension = emptyExtension)
-
- bigFork.foreach(sendHeader)
- // history should revert all smaller fork headers
- eventually {
- smallFork.forall(block => !hist.contains(block.id))
- }
- bigFork.foreach(sendBlock)
- // history should revert all smaller fork block parts
- eventually {
- smallFork.forall(block => !hist.contains(block.extension.id) && !hist.contains(block.blockTransactions.id))
- }
- }
- }
-
- property("NodeViewSynchronizer: Message: SyncInfoSpec V2 - older peer") {
- withFixture { ctx =>
- import ctx._
-
- val sync = ErgoSyncInfoV2(Seq(chain.last))
-
- // Neighbour is sending
- val msgBytes = ErgoSyncInfoMessageSpec.toBytes(sync)
-
- // we check that in case of neighbour with older history (it has more blocks),
- // sync message will be sent by our node (to get invs from the neighbour),
- // sync message will consist of 4 headers
- synchronizer ! Message(ErgoSyncInfoMessageSpec, Left(msgBytes), Some(peer))
- ncProbe.fishForMessage(3 seconds) { case m =>
- m match {
- case stn: SendToNetwork =>
- val msg = stn.message
- val headers = msg.data.get.asInstanceOf[ErgoSyncInfoV2].lastHeaders
- msg.spec.messageCode == ErgoSyncInfoMessageSpec.messageCode && headers.length == 4
- case _ => false
- }
- }
- }
- }
-
- property("NodeViewSynchronizer: Message: SyncInfoSpec V2 - unknown peer") {
- withFixture { ctx =>
- import ctx._
-
- val sync = ErgoSyncInfoV2(Seq(altchain.last))
-
- // Neighbour is sending
- val msgBytes = ErgoSyncInfoMessageSpec.toBytes(sync)
-
- // we check that in case of neighbour with older history (it has more blocks),
- // sync message will be sent by our node (to get invs from the neighbour),
- // sync message will consist of 4 headers
- synchronizer ! Message(ErgoSyncInfoMessageSpec, Left(msgBytes), Some(peer))
- ncProbe.fishForMessage(3 seconds) { case m =>
- m match {
- case stn: SendToNetwork =>
- val msg = stn.message
- val headers = msg.data.get.asInstanceOf[ErgoSyncInfoV2].lastHeaders
- msg.spec.messageCode == ErgoSyncInfoMessageSpec.messageCode && headers.length == 4
- case _ => false
- }
- }
- }
- }
-
- property("NodeViewSynchronizer: Message: SyncInfoSpec V2 - forked peer") {
- withFixture { ctx =>
- import ctx._
-
- val sync = ErgoSyncInfoV2(ErgoHistoryReader.FullV2SyncOffsets.map(offset => forkedChain.apply(forkedHeight - offset - 1)))
-
- // Neighbour is sending
- val msgBytes = ErgoSyncInfoMessageSpec.toBytes(sync)
- val invSpec = InvSpec
- // we check that in case of neighbour with older history (it has more blocks),
- // invs (extension for the forked peer) will be sent to the peer
- synchronizer ! Message(ErgoSyncInfoMessageSpec, Left(msgBytes), Some(peer))
- ncProbe.fishForMessage(3 seconds) { case m =>
- m match {
- case stn: SendToNetwork =>
- val msg = stn.message
- msg.spec.messageCode == invSpec.messageCode
- case _ => false
- }
- }
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/ErgoSyncInfoSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/ErgoSyncInfoSpecification.scala
deleted file mode 100644
index 3768260d27..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/ErgoSyncInfoSpecification.scala
+++ /dev/null
@@ -1,73 +0,0 @@
-package org.ergoplatform.network
-
-import java.nio.ByteBuffer
-
-import com.google.common.primitives.Ints
-import org.ergoplatform.nodeView.history.{ErgoSyncInfoMessageSpec, ErgoSyncInfoV1}
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.core.network.message.{Message, MessageSerializer}
-import scorex.crypto.hash
-import scorex.util.ModifierId
-import scorex.util.encode.Base16
-
-
-/**
- * syncInfo is a message sent from one peer to another in order to get (and agree) on synchronization status
- *
- * syncInfo v1 is about a sequence of header ids just
- */
-class ErgoSyncInfoSpecification extends ErgoPropertyTest with DecodingUtils {
-
- property("sync info v1 reference parser") {
- val magic = Array(1: Byte, 0: Byte, 2: Byte, 4: Byte) // mainnet magic
- val syncSpec = ErgoSyncInfoMessageSpec
-
- val lastHeaderId = Array.fill(16)(1: Byte) ++ Array.fill(16)(2: Byte)
-
- val syncInfo = ErgoSyncInfoV1(Seq(ModifierId @@ Base16.encode(lastHeaderId)))
-
- val syncMessage = Message(syncSpec, Right(syncInfo), None)
-
- val ms = new MessageSerializer(Seq(syncSpec), magic)
-
- val bs = ms.serialize(syncMessage).toArray
- val bsString = Base16.encode(bs)
-
- // test vector got via high-level API
- bsString shouldBe "0100020441000000214f904163010101010101010101010101010101010102020202020202020202020202020202"
-
- val bb = ByteBuffer.wrap(bs)
-
- // simple reference parser below
-
- // read network magic (network id) bytes (4 bytes)
- val magicRead = getBytes(bb, 4)
- magicRead.toIndexedSeq shouldBe magic.toIndexedSeq
-
- // read message type id
- val messageCode = getByte(bb)
- messageCode shouldBe syncSpec.messageCode // 65 (in dec)
-
- // read message length (4 bytes)
- val messageLength = Ints.fromByteArray(getBytes(bb,4))
-
- messageLength shouldBe 33
-
- // read message length (4 bytes)
- val checkSum = getBytes(bb, 4)
-
- // read number of headers, up to 8 bytes, but there are app-level limits (400 in reference client)
- val headersCount = getULong(bb).toByte // should read one byte only
-
- headersCount shouldBe 1.toByte
-
- // read header ids, one-by-one
- val headerId = getBytes(bb, 32)
-
- headerId.toIndexedSeq shouldBe lastHeaderId.toIndexedSeq
-
- // checksum must be equal to first 4 bytes of message payload
- checkSum shouldBe hash.Blake2b256(headersCount +: headerId).take(4)
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/ErgoSyncTrackerSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/ErgoSyncTrackerSpecification.scala
deleted file mode 100644
index b96081117e..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/ErgoSyncTrackerSpecification.scala
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.ergoplatform.network
-
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.core.consensus.{Older, Younger}
-import scorex.core.network.{ConnectedPeer, ConnectionId, Incoming}
-import scorex.core.network.peer.PeerInfo
-
-class ErgoSyncTrackerSpecification extends ErgoPropertyTest {
- property("getters test") {
- val time = 10L
- val peerInfo = PeerInfo(defaultPeerSpec, time, Some(Incoming), 5L)
- val cid = ConnectionId(inetAddr1, inetAddr2, Incoming)
- val connectedPeer = ConnectedPeer(cid, handlerRef = null, Some(peerInfo))
- val syncTracker = ErgoSyncTracker(settings.scorexSettings.network)
-
- val height = 1000
- // add peer to sync
- syncTracker.updateStatus(connectedPeer, Younger, Some(height))
- syncTracker.maxHeight() shouldBe Some(height)
- syncTracker.statuses(connectedPeer) shouldBe ErgoPeerStatus(connectedPeer, Younger, height, None, None)
- // updating status should change status and height of existing peer
- syncTracker.updateStatus(connectedPeer, Older, Some(height+1))
- syncTracker.maxHeight() shouldBe Some(height + 1)
- syncTracker.getStatus(connectedPeer) shouldBe Some(Older)
-
- syncTracker.peersByStatus.apply(Older).head shouldBe connectedPeer
- // peer should not be synced yet
- syncTracker.notSyncedOrOutdated(connectedPeer) shouldBe true
- syncTracker.outdatedPeers shouldBe Vector.empty
- // peer should be ready for sync
- syncTracker.peersToSyncWith().head shouldBe connectedPeer
- syncTracker.updateLastSyncSentTime(connectedPeer)
- // peer should be synced now
- syncTracker.notSyncedOrOutdated(connectedPeer) shouldBe false
-
- syncTracker.clearStatus(connectedPeer)
- // peer should not be tracked anymore
- syncTracker.getStatus(connectedPeer) shouldBe None
- syncTracker.peersByStatus.isEmpty shouldBe true
- syncTracker.statuses.get(connectedPeer) shouldBe None
- syncTracker.peersToSyncWith().length shouldBe 0
- syncTracker.maxHeight() shouldBe None
-
- // clearStatus() is ok when there's no peer
- syncTracker.clearStatus(connectedPeer)
- syncTracker.getStatus(connectedPeer) shouldBe None
- syncTracker.maxHeight() shouldBe None
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/FixedSizeApproximateCacheQueueSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/network/FixedSizeApproximateCacheQueueSpec.scala
deleted file mode 100644
index de06f3d9c7..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/FixedSizeApproximateCacheQueueSpec.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.ergoplatform.network
-
-import org.ergoplatform.network.FixedSizeApproximateCacheQueue.{ApproxCache, ConciseCache, elemCountApproxThreshold}
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class FixedSizeApproximateCacheQueueSpec extends AnyFlatSpec with Matchers {
-
- it should "create fixed size amount of caches" in {
- val queue = FixedSizeApproximateCacheQueue.empty(cacheQueueSize = 5)
- val queue1 =
- queue
- .putAll((1 to 100).map(_.toString))
- .putAll((101 to 200).map(_.toString))
- .putAll((201 to 300).map(_.toString))
-
- (1 to 300).foreach { n =>
- assert(queue1.mightContain(n.toString), s"$n should be in cache")
- }
-
- queue1.cacheQueue.size shouldBe 3
-
- val queue2 =
- queue1
- .putAll(Vector("301"))
- .putAll(Vector("302"))
- .putAll(Vector("303"))
- .putAll(Vector("304"))
- .putAll(Vector("305"))
- queue2.cacheQueue.size shouldBe 5
-
- (301 to 305).foreach { n =>
- assert(queue2.mightContain(n.toString), s"$n should be in cache")
- }
- }
-
- it should "create different types of caches based on reaching approx threshold" in {
- val queue = FixedSizeApproximateCacheQueue.empty(cacheQueueSize = 2)
-
- val fewElemQueue = queue.putAll((1 to 10).map(_.toString))
- assert(fewElemQueue.cacheQueue.head.isInstanceOf[ConciseCache], "Few elements should go to concise cache")
-
- val manyElemQueue = queue.putAll((1 to (elemCountApproxThreshold + 10)).map(_.toString))
- assert(manyElemQueue.cacheQueue.head.isInstanceOf[ApproxCache], "Many elements should go to approximate cache")
-
- val combinedQueue = manyElemQueue.putAll((1 to 10).map(_.toString))
- assert(combinedQueue.cacheQueue.head.isInstanceOf[ConciseCache], "Few elements should go to concise cache")
- assert(combinedQueue.cacheQueue.last.isInstanceOf[ApproxCache], "Many elements should go to approximate cache")
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/HandshakeSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/HandshakeSpecification.scala
deleted file mode 100644
index b00ec2867d..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/HandshakeSpecification.scala
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.ergoplatform.network
-
-import java.nio.ByteBuffer
-
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.core.app.Version
-import scorex.core.network.message.HandshakeSerializer
-import scorex.util.encode.Base16
-
-class HandshakeSpecification extends ErgoPropertyTest with DecodingUtils {
-
- property("handshake test vectors") {
- // bytes got from a real node
- val hsBase16 = "bcd2919cee2e076572676f726566030306126572676f2d6d61696e6e65742d332e332e36000210040001000102067f000001ae46"
- val hsBytes = Base16.decode(hsBase16).get
-
- val agentName = "ergoref"
-
- val peerName = "ergo-mainnet-3.3.6"
-
- val handshakeSerializer0 = HandshakeSerializer
- val hs0 = handshakeSerializer0.parseBytes(hsBytes)
- hs0.time shouldBe 1610134874428L // Friday, 8 January 2021, 19:41:14
- hs0.peerSpec.protocolVersion shouldBe Version(3, 3, 6)
- hs0.peerSpec.agentName shouldBe agentName
- hs0.peerSpec.nodeName shouldBe peerName
-
- val handshakeSerializer1 = HandshakeSerializer
- val hs1 = handshakeSerializer1.parseBytes(hsBytes)
- hs1.time shouldBe 1610134874428L
- val mf = hs1.peerSpec.features.find(_.isInstanceOf[ModePeerFeature]).head.asInstanceOf[ModePeerFeature]
- mf.stateType shouldBe StateType.Utxo
-
- // Byte-by-byte parsing below, according to the spec https://github.com/ergoplatform/ergo/wiki/P2P-Handshaking
-
- val bb = ByteBuffer.wrap(hsBytes)
- val time = getULong(bb)
- time shouldBe 1610134874428L
-
- val agentNameLength = getUByte(bb)
- agentNameLength shouldBe agentName.length
-
- val agentNameParsed = getBytes(bb, agentNameLength)
- new String(agentNameParsed, "UTF-8") shouldBe agentName
-
- val version = getBytes(bb, 3)
- version(0) shouldBe 3
- version(1) shouldBe 3
- version(2) shouldBe 6
-
- val peerNameLength = getUByte(bb)
- peerNameLength shouldBe peerName.length
-
- val peerNameParsed = getBytes(bb, peerNameLength)
- new String(peerNameParsed, "UTF-8") shouldBe peerName
-
- val pubNode = getUByte(bb)
-
- pubNode shouldBe 0
-
- val featuresCount = getUByte(bb)
-
- featuresCount shouldBe 2
-
- val firstFeatureId = getUByte(bb)
-
- firstFeatureId shouldBe 16 //mode feature
-
- val firstFeatureLength = getULong(bb) //should read one byte only
-
- firstFeatureLength shouldBe 4
-
- val stateTypeCode = getUByte(bb).toByte
-
- val stateType = StateType.fromCode(stateTypeCode)
-
- stateType shouldBe StateType.Utxo
-
- val verifyTransactions = getUByte(bb).toByte
-
- verifyTransactions shouldBe 1 // true
-
- val nipopowSuffixLength = getUByte(bb).toByte
-
- nipopowSuffixLength shouldBe 0 // no nipopow suffix, the peer has full header-chain
-
- val blocksToKeep = getInt(bb)
-
- blocksToKeep shouldBe -1 // all the full blocks stored
-
- val secondFeatureId = getUByte(bb)
-
- secondFeatureId shouldBe 2 // local address feature id
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/HeaderSerializationSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/HeaderSerializationSpecification.scala
deleted file mode 100644
index 8270804c48..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/HeaderSerializationSpecification.scala
+++ /dev/null
@@ -1,205 +0,0 @@
-package org.ergoplatform.network
-
-import org.ergoplatform.mining.difficulty.DifficultySerializer
-import org.ergoplatform.mining.{AutolykosSolution, groupElemFromBytes}
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.settings.Algos
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.crypto.authds.ADDigest
-import scorex.crypto.hash.{Blake2b256, Digest32}
-import scorex.util.ModifierId
-import scorex.util.encode.Base16
-import sigmastate.crypto.CryptoConstants.EcPointType
-
-import java.nio.ByteBuffer
-
-class HeaderSerializationSpecification extends ErgoPropertyTest with DecodingUtils {
-
- private def base16ToEcPoint(pointEncoded: String): EcPointType = {
- val bytes = Algos.decode(pointEncoded).get
- groupElemFromBytes(bytes)
- }
-
- // This test contains simple parser for header version 1
- // In Ergo mainnet, used for blocks till 417,791
- property("Header simple parsing - block version 1") {
- // real header from mainnet, at 414,474, https://explorer.ergoplatform.com/en/blocks/8cf6dca6b9505243e36192fa107735024c0000cf4594b1daa2dc4e13ee86f26f
- val version = 1 : Byte
- val height = 414474
- val parentId = ModifierId @@ "8bdd043dab20aa690afc9a18fc4797de4f02f049f5c16f9657646c753d69582e"
- val adProofsRoot = Digest32 @@ Base16.decode("4527a2a7bcee7f77b5697f505e5effc5342750f58a52dddfe407a3ce3bd3abd0").get
- val stateRoot = ADDigest @@ Base16.decode("6c06d6277d40aeb958c5631515dc3ec3d11d8504e62de77df024d0ca67242fb512").get
- val transactionsRoot = Digest32 @@ Base16.decode("722f9306300d0d96fe8c10de830216d700131614f9e6ce2496e8dba1cbb45951").get
- val timestamp = 1611874199636L
- val nBits = 118039443L
- val extensionRoot = Digest32 @@ Base16.decode("a1a3933312467ce53d41fdc20e38c603e8fd89999371c60d7537c5d5760ef7c4").get
-
- val pk = base16ToEcPoint("02bb8eb301ab3d5d14515e33760d0dfb4f7191312a640db64a3a1aeeac9703f2d3")
- val w = base16ToEcPoint("026d7b267c33120d15c267664081a6b77a6dcae6b35147db2c3e1195573119cb14")
- val n = Base16.decode("0008a1d103880117").get
- val d = BigInt("35863003992655055679291741607273543535646500642591973829915050")
- val powSolution = AutolykosSolution(pk, w, n, d)
- val votes = Array[Byte](4, 3, 0)
-
- val h = Header(version, parentId, adProofsRoot, stateRoot, transactionsRoot, timestamp, nBits,
- height, extensionRoot, powSolution, votes)
-
- h.id shouldBe "8cf6dca6b9505243e36192fa107735024c0000cf4594b1daa2dc4e13ee86f26f"
-
- h.id shouldBe Base16.encode(Blake2b256(h.bytes)) // header id is blake2b256 of its bytes
-
-
- //test vector
- Base16.encode(h.bytes) shouldBe
- "018bdd043dab20aa690afc9a18fc4797de4f02f049f5c16f9657646c753d69582e4527a2a7bcee7f77b5697f505e5effc5342750f58a52dddfe407a3ce3bd3abd0722f9306300d0d96fe8c10de830216d700131614f9e6ce2496e8dba1cbb459516c06d6277d40aeb958c5631515dc3ec3d11d8504e62de77df024d0ca67242fb512d4d0c1d9f42ea1a3933312467ce53d41fdc20e38c603e8fd89999371c60d7537c5d5760ef7c4070923938aa61904030002bb8eb301ab3d5d14515e33760d0dfb4f7191312a640db64a3a1aeeac9703f2d3026d7b267c33120d15c267664081a6b77a6dcae6b35147db2c3e1195573119cb140008a1d1038801171a16514e604d76c516eec4124f4066e6e326b9e8d2fc5165b631aa"
-
- h.bytes.length shouldBe 279
-
- val bb = ByteBuffer.wrap(h.bytes)
-
- // read block version, 1 byte
- val versionParsed = getByte(bb)
- versionParsed shouldBe version
-
- // read parent header id, 32 bytes
- val parentIdParsed = getBytes(bb, 32)
- Base16.encode(parentIdParsed) shouldBe parentId
-
- // read authenticating hash of state transformation correctness proofs, 32 bytes
- val adProofsRootParsed = getBytes(bb, 32)
- adProofsRootParsed.toIndexedSeq shouldBe adProofsRoot.toIndexedSeq
-
- // read transactions Merkle tree root, 32 bytes
- val transactionsRootParsed = getBytes(bb, 32)
- transactionsRootParsed.toIndexedSeq shouldBe transactionsRoot.toIndexedSeq
-
- // read UTXO state AVL+ tree root + height, 33 bytes
- val stateRootParsed = getBytes(bb, 33)
- stateRootParsed.toIndexedSeq shouldBe stateRoot.toIndexedSeq
-
- val timestampParsed = getULong(bb) // timestamp, up to 8 bytes
- timestampParsed shouldBe timestamp
-
- // read Merkle tree root of block extension data, 32 bytes
- val extensionRootParsed = getBytes(bb, 32)
- extensionRootParsed.toIndexedSeq shouldBe extensionRoot.toIndexedSeq
-
- // read difficulty encoded in Bitcoin nBits format, https://bitco.in/en/developer-reference#target-nbits
- val nbits = getBytes(bb, 4) // 4 bytes
- val difficulty = DifficultySerializer.decodeCompactBits(DifficultySerializer.readUint32BE(nbits))
- difficulty shouldBe h.requiredDifficulty
-
- val heightParsed = getULong(bb) // up to 4 bytes
- heightParsed shouldBe height
-
- // read miner votes for protocol parameters update
- val votesParsed = getBytes(bb, 3)
- votesParsed.toIndexedSeq shouldBe votes.toIndexedSeq
-
- // read PoW solution
- // read public key, 33 bytes (EC point)
- val pkParsed = getBytes(bb, 33)
- groupElemFromBytes(pkParsed) shouldBe pk
-
- // read one-time secret w, 33 bytes (EC point)
- val wParsed = getBytes(bb, 33)
- groupElemFromBytes(wParsed) shouldBe w
-
- // read nonce (8 bytes)
- val nonceParsed = getBytes(bb, 8)
- nonceParsed.toIndexedSeq shouldBe n.toIndexedSeq
-
- // read length of d, 1 byte
- val dLength = getUByte(bb)
- // read d bigint bytes
- val dBytes = getBytes(bb, dLength)
- val dParsed = BigInt(1, dBytes)
- dParsed shouldBe d
- }
-
-
- // This test contains simple parser for header version 2
- // In Ergo mainnet, used for blocks since 417,792 (inclusive)
- property("Header simple parsing - block version 2") {
- // real header from mainnet, at 418,838, https://explorer.ergoplatform.com/en/blocks/f46c89e44f13a92d8409341490f97f05c85785fa8d2d2164332cc066eda95c39
- val version = 2 : Byte
- val height = 418138
- val parentId = ModifierId @@ "7fbc70ec5913706ddef67bbcdb7700ea5f15dc709012491269c9c7eb545d720c"
- val adProofsRoot = Digest32 @@ Base16.decode("a80bbd4d69b4f017da6dd9250448ef1cde492121fc350727e755c7b7ae2988ad").get
- val stateRoot = ADDigest @@ Base16.decode("995c0efe63744c5227e6ae213a2061c60f8db845d47707a6bff53f9ff1936a9e13").get
- val transactionsRoot = Digest32 @@ Base16.decode("141bf3de015c44995858a435e4d6c50c51622d077760de32977ba5412aaaae03").get
- val timestamp = 1612465607426L
- val nBits = 107976917L
- val extensionRoot = Digest32 @@ Base16.decode("b1457df896bba9dc962f8e42187e1ac580842f1282c8c7fb9cf9f4cd520d1c07").get
-
- val pk = base16ToEcPoint("0315345f1fca9445eee5df74759d4c495094bcfc82a2831b26fca6efa599b509de")
- val w = AutolykosSolution.wForV2
- val n = Base16.decode("1b95db2168f95fda").get
- val d = AutolykosSolution.dForV2
- val powSolution = AutolykosSolution(pk, w, n, d)
- val votes = Array[Byte](0, 0, 0)
-
- val h = Header(version, parentId, adProofsRoot, stateRoot, transactionsRoot, timestamp, nBits,
- height, extensionRoot, powSolution, votes)
-
- h.id shouldBe "f46c89e44f13a92d8409341490f97f05c85785fa8d2d2164332cc066eda95c39"
-
- h.id shouldBe Base16.encode(Blake2b256(h.bytes)) // header id is blake2b256 of its bytes
-
- val bb = ByteBuffer.wrap(h.bytes)
-
- // read block version
- val versionParsed = getByte(bb)
- versionParsed shouldBe version
-
- // read parent id, 32 bytes
- val parentIdParsed = getBytes(bb, 32)
- Base16.encode(parentIdParsed) shouldBe parentId
-
- // read authenticating hash of state transformation correctness proofs, 32 bytes
- val adProofsRootParsed = getBytes(bb, 32)
- adProofsRootParsed.toIndexedSeq shouldBe adProofsRoot.toIndexedSeq
-
- // read transactions Merkle tree root, 32 bytes
- val transactionsRootParsed = getBytes(bb, 32)
- transactionsRootParsed.toIndexedSeq shouldBe transactionsRoot.toIndexedSeq
-
- // read UTXO state AVL+ tree root + height, 33 bytes
- val stateRootParsed = getBytes(bb, 33)
- stateRootParsed.toIndexedSeq shouldBe stateRoot.toIndexedSeq
-
- val timestampParsed = getULong(bb) // timestamp, up to 8 bytes
- timestampParsed shouldBe timestamp
-
- // read Merkle tree root of block extension data, 32 bytes
- val extensionRootParsed = getBytes(bb, 32)
- extensionRootParsed.toIndexedSeq shouldBe extensionRoot.toIndexedSeq
-
- // read difficulty encoded in Bitcoin nBits format, https://bitco.in/en/developer-reference#target-nbits
- val nbits = getBytes(bb, 4) // 4 bytes
- val difficulty = DifficultySerializer.decodeCompactBits(DifficultySerializer.readUint32BE(nbits))
- difficulty shouldBe h.requiredDifficulty
-
- val heightParsed = getULong(bb) // up to 4 bytes
- heightParsed shouldBe height
-
- // read miner votes for protocol parameters update
- val votesParsed = getBytes(bb, 3)
- votesParsed.toIndexedSeq shouldBe votes.toIndexedSeq
-
- // Block version V2 specific field, contains length of additional data
- val additionalFieldsLength = getUByte(bb)
- additionalFieldsLength shouldBe 0
-
- // read PoW solution, no "w" and "d" in block version 2
-
- val pkParsed = getBytes(bb, 33)
- groupElemFromBytes(pkParsed) shouldBe pk
-
- val nonceParsed = getBytes(bb, 8)
- nonceParsed.toIndexedSeq shouldBe n.toIndexedSeq
-
- bb.remaining() shouldBe 0
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/InvSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/InvSpecification.scala
deleted file mode 100644
index 7c756ec079..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/InvSpecification.scala
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.ergoplatform.network
-
-import java.nio.ByteBuffer
-
-import com.google.common.primitives.Ints
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.core.network.message.{InvData, InvSpec, Message, MessageSerializer}
-import scorex.crypto.hash
-import scorex.util.ModifierId
-import scorex.util.encode.Base16
-
-/**
- * Inv message is informing peers around about transactions and block parts available
- */
-class InvSpecification extends ErgoPropertyTest with DecodingUtils {
-
- property("inv reference parser") {
- val magic = Array(1: Byte, 0: Byte, 2: Byte, 4: Byte) // mainnet magic
- val invSpec = InvSpec
-
- val headerId = Array.fill(16)(1: Byte) ++ Array.fill(16)(2: Byte)
-
- val headerIdEncoded = ModifierId @@ Base16.encode(headerId)
-
- val invData = InvData(Header.modifierTypeId, Seq(headerIdEncoded))
-
- val invMessage = Message(invSpec, Right(invData), None)
-
- val ms = new MessageSerializer(Seq(invSpec), magic)
-
- val bs = ms.serialize(invMessage).toArray
- val bsString = Base16.encode(bs)
-
- // test vector for external implementations
- bsString shouldBe "0100020437000000226abfdbf565010101010101010101010101010101010102020202020202020202020202020202"
-
- val bb = ByteBuffer.wrap(bs)
-
- // simple reference parser below
-
- // read network magic (network id) bytes (4 bytes)
- val magicRead = getBytes(bb, 4)
- magicRead.toIndexedSeq shouldBe magic.toIndexedSeq
-
- // read message type id
- val messageCode = getByte(bb)
- messageCode shouldBe invSpec.messageCode // 55 (in dec)
-
- // read message length (4 bytes)
- val messageLength = Ints.fromByteArray(getBytes(bb,4))
-
- messageLength shouldBe 34
-
- val checkSum = getBytes(bb, 4)
-
- // read modifier type id (1 byte)
- val modifierTypeId = getByte(bb) // should read one byte only
-
- modifierTypeId shouldBe 101.toByte // type id corresponding to block header
-
- // read number of modifiers (headers)
- val headersCount = getULong(bb).toInt // should read up to 4 bytes max
-
- headersCount shouldBe 1
-
- // read mofifier (header) ids
- val headerIdParsed = getBytes(bb, 32)
-
- headerIdParsed.toIndexedSeq shouldBe headerId.toIndexedSeq
-
- // validating checksum
- checkSum shouldBe hash.Blake2b256(Array(modifierTypeId, headersCount.toByte) ++ headerId).take(4)
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/ModePeerFeatureSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/ModePeerFeatureSpecification.scala
deleted file mode 100644
index 092a1ad45d..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/ModePeerFeatureSpecification.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.ergoplatform.network
-
-import org.ergoplatform.utils.ErgoPropertyTest
-import scala.util.Try
-
-
-class ModePeerFeatureSpecification extends ErgoPropertyTest {
-
- //roundtrip test is provided in SerializationTests
-
- property("additional bytes can be added") {
- forAll(modeFeatureGen) { mf =>
- val bs = mf.serializer.toBytes(mf)
- mf.serializer.parseBytes(bs ++ Array(1: Byte, 2: Byte, 3: Byte)) shouldEqual mf
- }
- }
-
- property("serialization of too big byte array fails") {
- forAll(modeFeatureGen) { mf =>
- val bs = mf.serializer.toBytes(mf)
- Try(mf.serializer.parseBytes(bs ++ Array.fill(512)(0: Byte))).isFailure shouldBe true
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/ModifiersSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/ModifiersSpecification.scala
deleted file mode 100644
index bc8e8d876f..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/ModifiersSpecification.scala
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.ergoplatform.network
-
-import java.nio.ByteBuffer
-
-import com.google.common.primitives.Ints
-import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer}
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.core.network.message.{Message, MessageSerializer, ModifiersData, ModifiersSpec}
-import scorex.util.encode.Base16
-
-/**
- * Modifiers message used to send transactions or block parts to a remote peer
- */
-class ModifiersSpecification extends ErgoPropertyTest with DecodingUtils {
-
- property("modifiers message reference parser") {
- val hBytes = Base16.decode("4201ad7fffba807080ce7f808001b4771880bdffbd7fff857f8db17fdc89b0015bff0189486d80934a84015e03c064c6d100c17fae55bf01f380007fbb00ff01d9000000013f0680d10015ff11c4b7ffff01ffb2d27f0001050064010080ffb93e7fff4cc15a2bffdd770480007f8080ff8026802f7f51007f004b01ff0080002380a581e8c0ca81dfca62007fa7ff01860019f37f3c4491067cd1001ee07e570fe8689b80ff11017aff7408703927a2bbc4fa0200000000032bdb4c610ddf0078b4f31f5a36bff7b003704dfc93b201fedd8fe331d9ff1102008d7fff010d80ff").get
- val header = HeaderSerializer.parseBytes(hBytes)
-
- val magic = Array(1: Byte, 0: Byte, 2: Byte, 4: Byte) // mainnet magic
- val mSpec = ModifiersSpec
-
- val mData = ModifiersData(Header.modifierTypeId, Map(header.id -> header.bytes))
-
- val mMessage = Message(mSpec, Right(mData), None)
-
- val ms = new MessageSerializer(Seq(mSpec), magic)
-
- val bs = ms.serialize(mMessage).toArray
- val bsString = Base16.encode(bs)
-
- // test vector for external implementations
- bsString shouldBe "0100020421000001058fdd57ca65010d537f94ae67e5026fd4acee1cdd1e7281a73e94a7681864438c629e9683b3a5e1014201ad7fffba807080ce7f808001b4771880bdffbd7fff857f8db17fdc89b0015bff0189486d80934a84015e03c064c6d100c17fae55bf01f380007fbb00ff01d9000000013f0680d10015ff11c4b7ffff01ffb2d27f0001050064010080ffb93e7fff4cc15a2bffdd770480007f8080ff8026802f7f51007f004b01ff0080002380a581e8c0ca81dfca62007fa7ff01860019f37f3c4491067cd1001ee07e570fe8689b80ff11017aff7408703927a2bbc4fa0200000000032bdb4c610ddf0078b4f31f5a36bff7b003704dfc93b201fedd8fe331d9ff1102008d7fff010d80ff"
-
- val bb = ByteBuffer.wrap(bs)
-
- // simple reference parser below
-
- // read network magic (network id) bytes (4 bytes)
- val magicRead = getBytes(bb, 4)
- magicRead.toIndexedSeq shouldBe magic.toIndexedSeq
-
- // read message type id
- val messageCode = getByte(bb)
- messageCode shouldBe mSpec.messageCode // 33 (in dec)
-
- // read message length (4 bytes)
- val messageLength = Ints.fromByteArray(getBytes(bb,4))
-
- messageLength shouldBe 261
-
- getBytes(bb, 4)
-
- // read modifier type id (1 byte)
- val modifierTypeId = getByte(bb) // should read one byte only
-
- modifierTypeId shouldBe 101.toByte // type id corresponding to block header
-
- // read number of modifiers (headers)
- val headersCount = getULong(bb).toInt // could read up to 4 bytes max
-
- headersCount shouldBe 1
-
- // read modifier (header) id
- val headerIdParsed = getBytes(bb, 32)
-
- Base16.encode(headerIdParsed) shouldBe header.id
-
- // read read modifier (header) bytes length
- val headerLength = getULong(bb).toInt // could read up to 4 bytes max
-
- // read read modifier (header) bytes
- val headerBytes = getBytes(bb, headerLength)
-
- headerBytes.toIndexedSeq shouldBe header.bytes.toIndexedSeq
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/PeerFilteringRuleSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/PeerFilteringRuleSpecification.scala
deleted file mode 100644
index cd7ee1e71e..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/PeerFilteringRuleSpecification.scala
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.ergoplatform.network
-
-import akka.actor.ActorRef
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.core.app.Version
-import scorex.core.network.PeerSpec
-import scorex.core.network.peer.PeerInfo
-import scorex.core.network.{ConnectedPeer, ConnectionId}
-
-class PeerFilteringRuleSpecification extends ErgoPropertyTest {
-
- private def peerWithVersion(version: Version): ConnectedPeer = {
- val ref = ActorRef.noSender
- val peerSpec = PeerSpec("", version, "", None, Seq.empty)
- val peerInfo = PeerInfo(peerSpec, lastHandshake = 0L, None, 0L)
- ConnectedPeer(ConnectionId(null, null, null), ref, Some(peerInfo))
- }
-
- property("syncv2 filter") {
- val v1Peer = peerWithVersion(Version(4, 0, 15))
- val v2Peer0 = peerWithVersion(Version(4, 0, 16))
- val v2Peer1 = peerWithVersion(Version(4, 0, 21))
- val v2Peer2 = peerWithVersion(Version(5, 0, 0))
-
- SyncV2Filter.filter(Seq(v1Peer, v2Peer0, v2Peer1, v2Peer2)) shouldBe Seq(v2Peer0, v2Peer1, v2Peer2)
- }
-
- property("utxo set snapshot filter") {
- val peer0 = peerWithVersion(Version(4, 0, 17))
- val peer1 = peerWithVersion(Version(4, 0, 18))
- val peer2 = peerWithVersion(Version(4, 0, 16))
- val peer3 = peerWithVersion(Version(4, 0, 19))
- val peer4 = peerWithVersion(Version(5, 0, 0))
- val peer5 = peerWithVersion(Version(5, 0, 5))
- val peer6 = peerWithVersion(Version(5, 0, 15))
- val peer7 = peerWithVersion(Version(5, 0, 25))
-
- UtxoSetNetworkingFilter.filter(Seq(peer0, peer1, peer2, peer3, peer4, peer5, peer6, peer7)) shouldBe
- Seq(peer6, peer7)
- }
-
- property("nipopow support filter") {
- val peer0 = peerWithVersion(Version(4, 0, 17))
- val peer1 = peerWithVersion(Version(4, 0, 18))
- val peer2 = peerWithVersion(Version(4, 0, 16))
- val peer3 = peerWithVersion(Version(4, 0, 19))
- val peer4 = peerWithVersion(Version(5, 0, 0))
- val peer5 = peerWithVersion(Version(5, 0, 12))
- val peer6 = peerWithVersion(Version(5, 0, 13))
- val peer7 = peerWithVersion(Version(5, 0, 25))
-
- NipopowSupportFilter.filter(Seq(peer0, peer1, peer2, peer3, peer4, peer5, peer6, peer7)) shouldBe
- Seq(peer6, peer7)
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/RequestModifiersSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/RequestModifiersSpecification.scala
deleted file mode 100644
index 7489c43871..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/network/RequestModifiersSpecification.scala
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.ergoplatform.network
-
-import java.nio.ByteBuffer
-
-import com.google.common.primitives.Ints
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.core.network.message.{InvData, Message, MessageSerializer, RequestModifierSpec}
-import scorex.crypto.hash
-import scorex.util.ModifierId
-import scorex.util.encode.Base16
-
-/**
- * RequestModifiers message is used to ask peers about transactions and block parts to download
- */
-class RequestModifiersSpecification extends ErgoPropertyTest with DecodingUtils {
-
- property("requestModifiers reference parser") {
-
- val magic = Array(1: Byte, 0: Byte, 2: Byte, 4: Byte) // mainnet magic
- val rmSpec = RequestModifierSpec
-
- val headerId = Array.fill(16)(1: Byte) ++ Array.fill(16)(2: Byte)
-
- val headerIdEncoded = ModifierId @@ Base16.encode(headerId)
-
- val invData = InvData(Header.modifierTypeId, Seq(headerIdEncoded))
-
- val rmMessage = Message(rmSpec, Right(invData), None)
-
- val ms = new MessageSerializer(Seq(rmSpec), magic)
-
- val bs = ms.serialize(rmMessage).toArray
- val bsString = Base16.encode(bs)
-
- // test vector for external implementations
- bsString shouldBe "0100020416000000226abfdbf565010101010101010101010101010101010102020202020202020202020202020202"
-
- val bb = ByteBuffer.wrap(bs)
-
- // simple reference parser below
-
- // read network magic (network id) bytes (4 bytes)
- val magicRead = getBytes(bb, 4)
- magicRead.toIndexedSeq shouldBe magic.toIndexedSeq
-
- // read message type id
- val messageCode = getByte(bb)
- messageCode shouldBe rmSpec.messageCode // 22 (in dec)
-
- // read message length (4 bytes)
- val messageLength = Ints.fromByteArray(getBytes(bb,4))
-
- messageLength shouldBe 34
-
- val checkSum = getBytes(bb, 4)
-
- // read modifier type id (1 byte)
- val modifierTypeId = getByte(bb) // should read one byte only
-
- modifierTypeId shouldBe 101.toByte // type id corresponding to block header
-
- // read number of modifiers (headers)
- val headersCount = getULong(bb).toInt // should read up to 4 bytes max
-
- headersCount shouldBe 1
-
- // read modifier (header) ids
- val headerIdParsed = getBytes(bb, 32)
-
- headerIdParsed.toIndexedSeq shouldBe headerId.toIndexedSeq
-
- // validating checksum
- checkSum shouldBe hash.Blake2b256(Array(modifierTypeId, headersCount.toByte) ++ headerId).take(4)
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/ErgoModifiersCacheSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/ErgoModifiersCacheSpec.scala
deleted file mode 100644
index 29e67176bd..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/ErgoModifiersCacheSpec.scala
+++ /dev/null
@@ -1,119 +0,0 @@
-package org.ergoplatform.nodeView
-
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.history.{ADProofs, BlockTransactions}
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.utils.{ErgoPropertyTest, HistoryTestHelpers}
-import scorex.crypto.hash.Blake2b256
-import scorex.util.{ModifierId, bytesToId}
-
-import scala.annotation.tailrec
-
-class ErgoModifiersCacheSpec extends ErgoPropertyTest with HistoryTestHelpers {
-
- private def genKey(i: Int): ModifierId = bytesToId(Blake2b256(s"$i"))
-
- private def genCachePair(i: Int): (ModifierId, Header) = {
- val header = defaultHeaderGen.sample.value
- val k = genKey(i)
- k -> header
- }
-
- property("cache size is within limits") {
- val limit = 3
- val modifiersCache = new ErgoModifiersCache(limit)
-
- modifiersCache.maxSize shouldBe limit
-
- (1 to limit).foreach { i =>
- val (k, h) = genCachePair(i)
- modifiersCache.put(k, h)
- }
-
- modifiersCache.size shouldBe limit
-
- val above = genCachePair(limit + 1)
-
- modifiersCache.put(above._1, above._2)
- modifiersCache.size shouldBe (limit + 1)
-
- modifiersCache.cleanOverfull()
-
- modifiersCache.size shouldBe limit
-
- modifiersCache.remove(genKey(1)).isEmpty shouldBe true
- }
-
- property("cache is proposing a reasonable candidate to enhance history") {
- val limit = 25
- val modifiersCache = new ErgoModifiersCache(limit)
-
- val history0 = generateHistory(verifyTransactions = true, StateType.Utxo, PoPoWBootstrap = false, BlocksToKeep)
-
- val chain = genChain(5, history0)
-
- chain.foreach { fb =>
- modifiersCache.put(fb.header.id, fb.header)
- modifiersCache.put(fb.header.transactionsId, fb.blockTransactions)
- modifiersCache.put(fb.header.ADProofsId, fb.adProofs.value)
- }
-
- //The history is empty - we can apply only a header at height == 0 at this moment.
- //Out of 15 elements in the cache, the cache should propose a proper candidate
- val c1 = modifiersCache.popCandidate(history0).value
- c1.isInstanceOf[Header] shouldBe true
- val h1 = c1.asInstanceOf[Header]
- h1.height shouldBe ErgoHistory.GenesisHeight
-
- val history1 = history0.append(c1).get._1
-
- //We have only header of height == 0 in the history, so cache should return whether a header of height == 1
- //or a non-header part of the full block at height == 0
- val c2 = modifiersCache.popCandidate(history1).value
- val properCandidate = c2 match {
- case h: Header => h.height == 1
- case bt: BlockTransactions => bt.id == h1.transactionsId
- case ap: ADProofs => ap.id == h1.ADProofsId
- }
- properCandidate shouldBe true
- }
-
- property("cache is proposing proper candidate during forking") {
- val limit = 25
- val modifiersCache = new ErgoModifiersCache(limit)
-
- var history = generateHistory(verifyTransactions = true, StateType.Utxo, PoPoWBootstrap = false, BlocksToKeep)
-
- val chain = genChain(1, history)
-
- chain.foreach{fb => history = applyBlock(history, fb)}
-
- val chain1 = genChain(5, history).tail
-
- val chain2 = genChain(10, history).tail
-
- chain1.foreach(fb => history = applyBlock(history, fb))
-
- chain2.foreach(fb => history = history.append(fb.header).get._1)
-
- history.bestFullBlockOpt.value shouldBe chain1.last
- history.bestHeaderOpt.value shouldBe chain2.last.header
-
- chain2.flatMap(_.blockSections).foreach(s => modifiersCache.put(s.id, s))
-
- @tailrec
- def applyLoop(): Unit = {
- modifiersCache.popCandidate(history) match {
- case Some(mod) =>
- history.append(mod)
- applyLoop()
- case None =>
- modifiersCache.size shouldBe 0
- history.bestFullBlockOpt.value shouldBe chain2.last
- }
- }
- applyLoop()
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/NodeViewSynchronizerTests.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/NodeViewSynchronizerTests.scala
deleted file mode 100644
index 9311d13c78..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/NodeViewSynchronizerTests.scala
+++ /dev/null
@@ -1,366 +0,0 @@
-package org.ergoplatform.nodeView
-
-import akka.actor.{ActorRef, ActorSystem}
-import akka.testkit.TestProbe
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages._
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.{GetNodeViewChanges, ModifiersFromRemote}
-import org.ergoplatform.nodeView.history.{ErgoHistory, ErgoSyncInfo, ErgoSyncInfoMessageSpec}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.ergoplatform.nodeView.state.UtxoState.ManifestId
-import org.ergoplatform.nodeView.state._
-import org.ergoplatform.settings.Algos
-import org.ergoplatform.wallet.utils.TestFileUtils
-import org.scalacheck.Gen
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-import scorex.core.consensus.SyncInfo
-import scorex.core.network.ConnectedPeer
-import scorex.core.network.NetworkController.ReceivableMessages.{PenalizePeer, SendToNetwork}
-import scorex.core.network.message._
-import scorex.core.network.peer.PenaltyType
-import scorex.core.serialization.{BytesSerializable, ErgoSerializer, ManifestSerializer}
-import scorex.crypto.hash.Digest32
-import scorex.testkit.generators.{SyntacticallyTargetedModifierProducer, TotallyValidModifierProducer}
-import scorex.testkit.utils.AkkaFixture
-import scorex.util.ScorexLogging
-import scorex.util.serialization.{Reader, Writer}
-import org.ergoplatform.utils.generators.ChainGenerator
-
-import scala.concurrent.Await
-import scala.concurrent.duration._
-import scala.language.postfixOps
-import scala.util.Random
-
-@SuppressWarnings(Array("org.wartremover.warts.IsInstanceOf"))
-trait NodeViewSynchronizerTests[ST <: ErgoState[ST]] extends AnyPropSpec
- with Matchers
- with ScorexLogging
- with SyntacticallyTargetedModifierProducer
- with TotallyValidModifierProducer[ST]
- with ChainGenerator
- with TestFileUtils {
-
- implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global
-
- val historyGen: Gen[ErgoHistory]
- val memPool: ErgoMemPool
-
- val stateGen: Gen[ST]
-
- def nodeViewSynchronizer(implicit system: ActorSystem):
- (ActorRef, ErgoSyncInfo, BlockSection, ErgoTransaction, ConnectedPeer, TestProbe, TestProbe, TestProbe, TestProbe, ErgoSerializer[BlockSection])
-
- class SynchronizerFixture extends AkkaFixture {
- @SuppressWarnings(Array("org.wartremover.warts.PublicInference"))
- val (node, syncInfo, mod, tx, peer, pchProbe, ncProbe, vhProbe, eventListener, modSerializer) = nodeViewSynchronizer
- }
-
- // ToDo: factor this out of here and NVHTests?
- private def withFixture(testCode: SynchronizerFixture => Any): Unit = {
- val fixture = new SynchronizerFixture
- try {
- testCode(fixture)
- }
- finally {
- Await.result(fixture.system.terminate(), Duration.Inf)
- }
- }
-
- property("NodeViewSynchronizer: SuccessfulTransaction") {
- withFixture { ctx =>
- import ctx._
- node ! SuccessfulTransaction(UnconfirmedTransaction(tx, None))
- ncProbe.fishForMessage(3 seconds) { case m => m.isInstanceOf[SendToNetwork] }
- }
- }
-
- property("NodeViewSynchronizer: FailedTransaction") {
- withFixture { ctx =>
- import ctx._
- node ! FailedTransaction(UnconfirmedTransaction(tx, None), new Exception)
- // todo: NVS currently does nothing in this case. Should check banning.
- }
- }
-
- property("NodeViewSynchronizer: SyntacticallySuccessfulModifier") {
- withFixture { ctx =>
- import ctx._
- node ! SyntacticallySuccessfulModifier(mod.modifierTypeId, mod.id)
- // todo ? : NVS currently does nothing in this case. Should it do?
- }
- }
-
- property("NodeViewSynchronizer: SyntacticallyFailedModification") {
- withFixture { ctx =>
- import ctx._
- node ! SyntacticallyFailedModification(mod.modifierTypeId, mod.id, new Exception)
- // todo: NVS currently does nothing in this case. Should check banning.
- }
- }
-
- property("NodeViewSynchronizer: SemanticallySuccessfulModifier") {
- withFixture { ctx =>
- import ctx._
- node ! FullBlockApplied(mod.asInstanceOf[Header]) //todo: fix
- ncProbe.fishForMessage(3 seconds) { case m => m.isInstanceOf[SendToNetwork] }
- }
- }
-
- property("NodeViewSynchronizer: SemanticallyFailedModification") {
- withFixture { ctx =>
- import ctx._
- node ! SemanticallyFailedModification(mod.modifierTypeId, mod.id, new Exception)
- // todo: NVS currently does nothing in this case. Should check banning.
- }
- }
-
- //TODO rewrite
- ignore("NodeViewSynchronizer: Message: SyncInfoSpec") {
- withFixture { ctx =>
- import ctx._
-
- val dummySyncInfoMessageSpec = new SyncInfoMessageSpec[SyncInfo](serializer = new ErgoSerializer[SyncInfo] {
- override def parse(r: Reader): SyncInfo = {
- throw new Exception()
- }
-
- override def serialize(obj: SyncInfo, w: Writer): Unit = {}
- })
-
- val dummySyncInfo: SyncInfo = new SyncInfo {
- type M = BytesSerializable
-
- def serializer: ErgoSerializer[M] = throw new Exception
- }
-
- val msgBytes = dummySyncInfoMessageSpec.toBytes(dummySyncInfo)
-
- node ! Message(dummySyncInfoMessageSpec, Left(msgBytes), Some(peer))
- // vhProbe.fishForMessage(3 seconds) { case m => m == OtherNodeSyncingInfo(peer, dummySyncInfo) }
- }
- }
-
- property("NodeViewSynchronizer: GetNipopowProof") {
- withFixture { ctx =>
- import ctx._
-
- // Generate history chain
- val emptyHistory = historyGen.sample.get
- val prefix = blockStream(None).take(settings.chainSettings.makeSnapshotEvery)
- val fullHistory = applyChain(emptyHistory, prefix)
-
- // Broadcast updated history
- node ! ChangedHistory(fullHistory)
-
- // Build and send GetNipopowProofSpec request
- val spec = GetNipopowProofSpec
- val msgBytes = spec.toBytes(NipopowProofData(m = emptyHistory.P2PNipopowProofM, k = emptyHistory.P2PNipopowProofK, headerId = None))
- node ! Message[NipopowProofData](spec, Left(msgBytes), Option(peer))
-
- // Listen for NipopowProofSpec response
- ncProbe.fishForMessage(5 seconds) {
- case stn: SendToNetwork =>
- stn.message.spec match {
- case _: NipopowProofSpec.type => true
- case _ => false
- }
- case _: Any => false
- }
- }
- }
-
- property("NodeViewSynchronizer: Message: InvSpec") {
- withFixture { ctx =>
- import ctx._
- val syncMsgBytes = ErgoSyncInfoMessageSpec.toBytes(syncInfo)
- node ! Message(ErgoSyncInfoMessageSpec, Left(syncMsgBytes), Some(peer))
-
- val spec = InvSpec
- val modifiers = Seq(mod.id)
- val msgBytes = spec.toBytes(InvData(mod.modifierTypeId, modifiers))
- node ! Message(spec, Left(msgBytes), Some(peer))
- ncProbe.fishForMessage(5 seconds) {
- case SendToNetwork(msg, _)
- if msg.spec.messageCode == RequestModifierSpec.messageCode &&
- msg.data.get.asInstanceOf[InvData].ids.head == mod.id => true
- case _ => false
- }
- }
- }
-
- property("NodeViewSynchronizer: Message: RequestModifierSpec") {
- withFixture { ctx =>
- import ctx._
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val h = historyGen.sample.get
- val mod = syntacticallyValidModifier(h)
- val (newH, _) = h.append(mod).get
- val m = memPool
- val spec = RequestModifierSpec
- val modifiers = Seq(mod.id)
- val msgBytes = spec.toBytes(InvData(mod.modifierTypeId, modifiers))
- node ! ChangedHistory(newH)
- node ! ChangedMempool(m)
- node ! Message(spec, Left(msgBytes), Option(peer))
-
- pchProbe.fishForMessage(5 seconds) {
- case _: Message[_] => true
- case _ => false
- }
- }
- }
-
- property("NodeViewSynchronizer: Message: Non-Asked Modifiers from Remote") {
- withFixture { ctx =>
- import ctx._
-
- val modifiersSpec = ModifiersSpec
- val msgBytes = modifiersSpec.toBytes(ModifiersData(mod.modifierTypeId, Map(mod.id -> mod.bytes)))
-
- node ! Message(modifiersSpec, Left(msgBytes), Option(peer))
- val messages = vhProbe.receiveWhile(max = 3 seconds, idle = 1 second) { case m => m }
- assert(!messages.exists(_.isInstanceOf[ModifiersFromRemote]))
- }
- }
-
- property("NodeViewSynchronizer: Message: Asked Modifiers from Remote") {
- withFixture { ctx =>
- import ctx._
- vhProbe.expectMsgType[GetNodeViewChanges]
-
- val invSpec = InvSpec
- val invMsgBytes = invSpec.toBytes(InvData(mod.modifierTypeId, Seq(mod.id)))
-
- val modifiersSpec = ModifiersSpec
- val modMsgBytes = modifiersSpec.toBytes(ModifiersData(mod.modifierTypeId, Map(mod.id -> mod.bytes)))
-
- node ! Message(invSpec, Left(invMsgBytes), Option(peer))
- node ! Message(modifiersSpec, Left(modMsgBytes), Option(peer))
- vhProbe.fishForMessage(3 seconds) {
- case m: ModifiersFromRemote => m.modifiers.toSeq.contains(mod)
- case _ => false
- }
- }
- }
-
- property("NodeViewSynchronizer: Message - CheckDelivery - Do not penalize if delivered") {
- withFixture { ctx =>
- import ctx._
-
- val invSpec = InvSpec
- val invMsgBytes = invSpec.toBytes(InvData(mod.modifierTypeId, Seq(mod.id)))
-
- val modifiersSpec = ModifiersSpec
- val modMsgBytes = modifiersSpec.toBytes(ModifiersData(mod.modifierTypeId, Map(mod.id -> mod.bytes)))
-
- node ! Message(invSpec, Left(invMsgBytes), Option(peer))
- node ! Message(modifiersSpec, Left(modMsgBytes), Option(peer))
- system.scheduler.scheduleOnce(1 second, node, Message(modifiersSpec, Left(modMsgBytes), Option(peer)))
- val messages = ncProbe.receiveWhile(max = 5 seconds, idle = 1 second) { case m => m }
- assert(!messages.contains(PenalizePeer(peer.connectionId.remoteAddress, PenaltyType.MisbehaviorPenalty)))
- }
- }
-
-
- property("NodeViewSynchronizer: GetSnapshotInfo") {
- withFixture { ctx =>
- import ctx._
-
- val s = stateGen.sample.get
-
- if (s.isInstanceOf[UtxoStateReader]) {
- // To initialize utxoStateReaderOpt in ErgoNodeView Synchronizer
- node ! ChangedState(s)
-
- // First, store snapshots info in DB
- val m = (0 until 100).map { _ =>
- Random.nextInt(1000000) -> (Digest32 @@ Algos.decode(mod.id).get)
- }.toMap
- val si = new SnapshotsInfo(m)
- val db = SnapshotsDb.create(createTempDir.getPath)
- db.writeSnapshotsInfo(si)
-
- // Then send message to request it
- node ! Message[Unit](GetSnapshotsInfoSpec, Left(Array.empty[Byte]), Option(peer))
- ncProbe.fishForMessage(5 seconds) {
- case stn: SendToNetwork if stn.message.spec.isInstanceOf[SnapshotsInfoSpec.type] => true
- case _: Any => false
- }
- } else {
- log.info("Snapshots not supported by digest-state")
- }
- }
- }
-
- property("NodeViewSynchronizer: GetManifest") {
- withFixture { ctx =>
- import ctx._
-
- val s = stateGen.sample.get
-
- s match {
- case usr: UtxoState => {
- // To initialize utxoStateReaderOpt in ErgoNodeView Synchronizer
- node ! ChangedState(s)
-
- // Generate some snapshot
- val height = 1
- usr.applyModifier(mod, Some(height))(_ => ())
-
- val manifestId = usr.dumpSnapshot(height, usr.rootDigest.dropRight(1)).get
-
- // Then send message to request it
- node ! Message[ManifestId](GetManifestSpec, Left(manifestId), Option(peer))
- ncProbe.fishForMessage(5 seconds) {
- case stn: SendToNetwork if stn.message.spec.isInstanceOf[ManifestSpec.type] => true
- case _: Any => false
- }
- }
- case _ =>
- log.info("Snapshots not supported by digest-state")
- }
- }
- }
-
- property("NodeViewSynchronizer: GetSnapshotChunk") {
- withFixture { ctx =>
- import ctx._
-
- val s = stateGen.sample.get
-
- s match {
- case usr: UtxoState => {
- // To initialize utxoStateReaderOpt in ErgoNodeView Synchronizer
- node ! ChangedState(s)
-
- // Generate some snapshot
-
- val height = 1
-
- usr.applyModifier(mod, Some(height))(_ => ())
-
- val manifestDepth = 2.toByte
- val serializer = new ManifestSerializer(manifestDepth)
- usr.dumpSnapshot(height, usr.rootDigest.dropRight(1), manifestDepth)
- val manifestId = usr.snapshotsDb.readSnapshotsInfo.availableManifests.apply(height)
- val manifestBytes = usr.snapshotsDb.readManifestBytes(manifestId).get
- val manifest = serializer.parseBytes(manifestBytes)
- val subtreeIds = manifest.subtreesIds
-
- // Then send message to request it
- node ! Message[ManifestId](GetUtxoSnapshotChunkSpec, Left(subtreeIds.last), Option(peer))
- ncProbe.fishForMessage(5 seconds) {
- case stn: SendToNetwork if stn.message.spec.isInstanceOf[UtxoSnapshotChunkSpec.type] => true
- case _: Any => false
- }
- }
- case _ =>
- log.info("Snapshots not supported by digest-state")
- }
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/BlockSectionValidationSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/BlockSectionValidationSpecification.scala
deleted file mode 100644
index 40feb58cef..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/BlockSectionValidationSpecification.scala
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.ergoplatform.nodeView.history
-
-import org.ergoplatform.modifiers.{BlockSection, NonHeaderBlockSection}
-import org.ergoplatform.modifiers.history._
-import org.ergoplatform.modifiers.history.extension.Extension
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.utils.HistoryTestHelpers
-import scorex.core.consensus.ModifierSemanticValidity
-import scorex.crypto.hash.Blake2b256
-import scorex.util.ModifierId
-import scorex.util.encode.Base16
-
-class BlockSectionValidationSpecification extends HistoryTestHelpers {
-
- private def changeProofByte(version: Header.Version, outcome: Symbol) = {
- val (history, block) = init(version)
- val bt = block.blockTransactions
- val txBytes = HistoryModifierSerializer.toBytes(bt)
-
- val txs = bt.transactions
- val proof = txs.head.inputs.head.spendingProof.proof
- proof(0) = if(proof.head < 0) (proof.head + 1).toByte else (proof.head - 1).toByte
-
- val txBytes2 = HistoryModifierSerializer.toBytes(bt)
-
- val hashBefore = Base16.encode(Blake2b256(txBytes))
- val hashAfter = Base16.encode(Blake2b256(txBytes2))
-
- val wrongBt = HistoryModifierSerializer.parseBytes(txBytes2).asInstanceOf[BlockTransactions]
-
- hashBefore should not be hashAfter
- history.applicableTry(bt) shouldBe 'success
- history.applicableTry(wrongBt) shouldBe outcome
- }
-
- property("BlockTransactions - proof byte changed - v.1") {
- changeProofByte(Header.InitialVersion, outcome = 'success)
- }
-
- property("BlockTransactions - proof byte changed - v.2") {
- changeProofByte((Header.InitialVersion + 1).toByte, outcome = 'failure)
- }
-
- property("BlockTransactions commons check") {
- val (history, block) = init()
- commonChecks(history, block.blockTransactions, block.header)
- }
-
- property("ADProofs validation") {
- val (history, block) = init()
- commonChecks(history, block.adProofs.get, block.header)
- }
-
- property("Extension validation") {
- val (history, block) = init()
- commonChecks(history, block.extension, block.header)
- }
-
- private def init(version: Header.Version = Header.InitialVersion) = {
- var history = genHistory()
- val chain = genChain(2, history, version)
- history = applyBlock(history, chain.head)
- history = history.append(chain.last.header).get._1
- (history, chain.last)
- }
-
- private def commonChecks(history: ErgoHistory, section: NonHeaderBlockSection, header: Header) = {
- history.applicableTry(section) shouldBe 'success
- // header should contain correct digest
- history.applicableTry(withUpdatedHeaderId(section, section.id)) shouldBe 'failure
-
- // should not be able to apply when blocks at this height are already pruned
- history.applicableTry(section) shouldBe 'success
- history.writeMinimalFullBlockHeight(history.bestHeaderOpt.get.height + 1)
- history.isHeadersChainSyncedVar = true
- history.applicableTry(section) shouldBe 'failure
- history.writeMinimalFullBlockHeight(ErgoHistory.GenesisHeight)
-
- // should not be able to apply if corresponding header is marked as invalid
- history.applicableTry(section) shouldBe 'success
- history.historyStorage.insert(Array(history.validityKey(header.id) -> Array(0.toByte)), Array.empty[BlockSection]).get
- history.isSemanticallyValid(header.id) shouldBe ModifierSemanticValidity.Invalid
- history.applicableTry(section) shouldBe 'failure
- history.historyStorage.insert(Array(history.validityKey(header.id) -> Array(1.toByte)), Array.empty[BlockSection]).get
-
- // should not be able to apply if already in history
- history.applicableTry(section) shouldBe 'success
- history.append(section).get
- history.applicableTry(section) shouldBe 'failure
- }
-
- private def genHistory() =
- generateHistory(verifyTransactions = true, StateType.Utxo, PoPoWBootstrap = false, BlocksToKeep)
-
- private def withUpdatedHeaderId[T <: NonHeaderBlockSection](section: T, newId: ModifierId): T = section match {
- case s: Extension => s.copy(headerId = newId).asInstanceOf[T]
- case s: BlockTransactions => s.copy(headerId = newId).asInstanceOf[T]
- case s: ADProofs => s.copy(headerId = newId).asInstanceOf[T]
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/NonVerifyADHistorySpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/NonVerifyADHistorySpecification.scala
deleted file mode 100644
index b2cbb964ca..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/NonVerifyADHistorySpecification.scala
+++ /dev/null
@@ -1,303 +0,0 @@
-package org.ergoplatform.nodeView.history
-
-import org.ergoplatform.mining.difficulty.DifficultySerializer
-import org.ergoplatform.modifiers.history.extension.Extension
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.history.popow.NipopowAlgos
-import org.ergoplatform.modifiers.history.HeaderChain
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.settings.Algos
-import org.ergoplatform.utils.HistoryTestHelpers
-import scorex.crypto.hash.Digest32
-import scorex.core.consensus.{Older, Younger, Fork, Equal}
-
-import scala.util.Random
-
-class NonVerifyADHistorySpecification extends HistoryTestHelpers {
-
- private def genHistory() =
- generateHistory(verifyTransactions = false, StateType.Digest, PoPoWBootstrap = false, blocksToKeep = 0, epochLength = 1000)
- .ensuring(_.bestFullBlockOpt.isEmpty)
-
- private lazy val popowHistory = ensureMinimalHeight(genHistory(), 100)
-
- property("Should calculate difficulty correctly") {
- val epochLength = 3
- val useLastEpochs = 3
-
- val initDiff = BigInt(2)
- val initDiffBits = DifficultySerializer.encodeCompactBits(initDiff)
-
- var history = generateHistory(
- verifyTransactions = false,
- StateType.Digest,
- PoPoWBootstrap = false,
- blocksToKeep = 0,
- epochLength = epochLength,
- useLastEpochs = useLastEpochs,
- initialDiffOpt = Some(initDiff)
- )
- val blocksBeforeRecalculate = epochLength + 1
-
- history = applyHeaderChain(history,
- genHeaderChain(blocksBeforeRecalculate, history, diffBitsOpt = Some(initDiffBits), useRealTs = true))
-
- val bestHeaderOpt = history.bestHeaderOpt
-
- history.requiredDifficultyAfter(bestHeaderOpt.get) shouldBe initDiff
- }
-
- property("lastHeaders() should return correct number of blocks") {
- forAll(smallInt) { m =>
- val lastHeaders = popowHistory.lastHeaders(m)
- if (m > 0) {
- lastHeaders.last shouldBe popowHistory.bestHeaderOpt.get
- }
- lastHeaders.length shouldBe m
- }
- }
-
- property("lastHeaders() should be sorted") {
- forAll(smallInt) { m =>
- val lastHeaderTimestamps = popowHistory.lastHeaders(m).headers.map(_.timestamp)
- lastHeaderTimestamps shouldBe lastHeaderTimestamps.sorted
- }
- }
-
- property("History.isInBestChain") {
- var history = genHistory()
- val common = genHeaderChain(BlocksInChain, history, diffBitsOpt = None, useRealTs = false)
- history = applyHeaderChain(history, common)
-
- val fork1 = genHeaderChain(BlocksInChain, history, diffBitsOpt = None, useRealTs = false)
- val fork2 = genHeaderChain(BlocksInChain + 1, history, diffBitsOpt = None, useRealTs = false)
-
- history = applyHeaderChain(history, fork1.tail)
- history.bestHeaderOpt.get shouldBe fork1.last
- fork1.headers.foreach(h => history.isInBestChain(h.id) shouldBe true)
-
- history = applyHeaderChain(history, fork2.tail)
- history.bestHeaderOpt.get shouldBe fork2.last
- fork2.headers.foreach(h => history.isInBestChain(h.id) shouldBe true)
- fork1.tail.headers.foreach(h => history.isInBestChain(h.id) shouldBe false)
- }
-
- property("Compare headers chain") {
- var history = genHistory()
-
- def getInfoV1(c: HeaderChain): ErgoSyncInfo = ErgoSyncInfoV1(c.headers.map(_.id))
- def getInfoV2(c: HeaderChain): ErgoSyncInfo = ErgoSyncInfoV2(Seq(c.headers.last))
-
- // generate common chain prefix
- val common = genHeaderChain(BlocksInChain, history, diffBitsOpt = None, useRealTs = false)
- history = applyHeaderChain(history, common)
-
- val fork1 = genHeaderChain(BlocksInChain, history, diffBitsOpt = None, useRealTs = false)
- val fork2 = genHeaderChain(BlocksInChain + 1, history, diffBitsOpt = None, useRealTs = false)
-
- history = applyHeaderChain(history, fork1.tail)
- history.bestHeaderOpt.get shouldBe fork1.last
-
- // v1 sync
- history.compare(getInfoV1(fork2)) shouldBe Fork
- history.compare(getInfoV1(fork1)) shouldBe Equal
- history.compare(getInfoV1(fork1.take(BlocksInChain - 1))) shouldBe Fork
- history.compare(getInfoV1(fork2.take(BlocksInChain - 1))) shouldBe Fork
- history.compare(getInfoV1(fork2.tail)) shouldBe Older
-
- // v2 sync
- history.compare(getInfoV2(fork2)) shouldBe Older
- history.compare(getInfoV2(fork1)) shouldBe Equal
- history.compare(getInfoV2(fork1.take(BlocksInChain - 1))) shouldBe Younger
- history.compare(getInfoV2(fork2.take(BlocksInChain - 1))) shouldBe Younger
- history.compare(getInfoV2(fork2.tail)) shouldBe Older
- }
-
- property("continuationIds() on forks") {
- var history1 = genHistory()
- var history2 = genHistory()
- val inChain = genHeaderChain(20, history1, diffBitsOpt = None, useRealTs = false)
-
- //put genesis
- history1 = applyHeaderChain(history1, inChain)
- history2 = applyHeaderChain(history2, inChain)
- val fork1 = genHeaderChain(BlocksInChain, history1, diffBitsOpt = None, useRealTs = false).tail
- val fork2 = genHeaderChain(BlocksInChain, history1, diffBitsOpt = None, useRealTs = false).tail
-
- //apply 2 different forks
- history1 = applyHeaderChain(history1, fork1)
- history2 = applyHeaderChain(history2, fork1.take(BlocksInChain / 3))
- history2 = applyHeaderChain(history2, fork2.take(BlocksInChain / 2))
- history2.bestHeaderOpt.get shouldBe fork2.take(BlocksInChain / 2).last
- history1.bestHeaderOpt.get shouldBe fork1.last
-
- val si = history2.syncInfoV1
- val continuation = history1.continuationIds(si, BlocksInChain * 100)
- fork1.headers.foreach(h => continuation.exists(_._2 == h.id) shouldBe true)
-
- val si2 = history2.syncInfoV2(full = true)
- val continuation2 = history1.continuationIds(si2, BlocksInChain * 100)
- fork1.headers.foreach(h => continuation2.exists(_._2 == h.id) shouldBe true)
- }
-
- property("continuationIds() for empty ErgoSyncInfo should contain ids of all headers") {
- var history = genHistory()
- val chain = genHeaderChain(BlocksInChain, history, diffBitsOpt = None, useRealTs = false)
- history = applyHeaderChain(history, chain)
-
- val smallerLimit = 2
- val ci0v1 = history.continuationIds(ErgoSyncInfoV1(Seq()), smallerLimit)
- ci0v1.length shouldBe smallerLimit
-
- val ci0v2 = history.continuationIds(ErgoSyncInfoV2(Seq()), smallerLimit)
- ci0v2.length shouldBe smallerLimit
-
- chain.headers.take(smallerLimit).map(_.encodedId) shouldEqual ci0v1.map(c => Algos.encode(c._2))
- chain.headers.take(smallerLimit).map(_.encodedId) shouldEqual ci0v2.map(c => Algos.encode(c._2))
-
- val biggerLimit = BlocksInChain + 2
- val ci1v1 = history.continuationIds(ErgoSyncInfoV1(Seq()), biggerLimit)
- chain.headers.map(_.id) should contain theSameElementsAs ci1v1.map(_._2)
- val ci1v2 = history.continuationIds(ErgoSyncInfoV2(Seq()), biggerLimit)
- chain.headers.map(_.id) should contain theSameElementsAs ci1v2.map(_._2)
-
- val civ1 = history.continuationIds(ErgoSyncInfoV1(Seq()), BlocksInChain)
- civ1.foreach(c => c._1 shouldBe Header.modifierTypeId)
- chain.headers.map(_.id) should contain theSameElementsAs civ1.map(_._2)
- val civ2 = history.continuationIds(ErgoSyncInfoV2(Seq()), BlocksInChain)
- civ2.foreach(c => c._1 shouldBe Header.modifierTypeId)
- chain.headers.map(_.id) should contain theSameElementsAs civ2.map(_._2)
- }
-
- property("continuationIds() for smaller chain should contain ids of next headers in our chain") {
- var history = genHistory()
-
- history = ensureMinimalHeight(history, BlocksInChain + 1)
- val chain = history.lastHeaders(BlocksInChain)
-
- forAll(smallPositiveInt) { forkLength: Int =>
- whenever(forkLength > 1 && chain.size > forkLength) {
- val siv1 = ErgoSyncInfoV1(Seq(chain.headers(chain.size - forkLength - 1).id))
- val continuation1 = history.continuationIds(siv1, forkLength + 1)
- continuation1.length shouldBe forkLength + 1
- continuation1.last._2 shouldEqual chain.last.id
- continuation1.head._2 shouldEqual chain.headers(chain.size - forkLength - 1).id
-
- val siv2 = ErgoSyncInfoV2(Seq(chain.headers(chain.size - forkLength - 1)))
- val continuation2 = history.continuationIds(siv2, forkLength + 1)
- continuation2.length shouldBe forkLength
- continuation2.last._2 shouldEqual chain.last.id
- continuation2.head._2 shouldEqual chain.headers(chain.size - forkLength).id
- }
- }
- }
-
- property("continuationHeaderChains()") {
- var history = genHistory()
- //put 2 blocks
- val inChain = genHeaderChain(2, history, diffBitsOpt = None, useRealTs = false)
- history = applyHeaderChain(history, inChain)
- //apply 2 different forks
- val fork1 = genHeaderChain(2, history, diffBitsOpt = None, useRealTs = false).tail
- val fork2 = genHeaderChain(3, history, diffBitsOpt = None, useRealTs = false).tail
- history = applyHeaderChain(history, fork1)
- history = applyHeaderChain(history, fork2)
- //get continuationHeaderChains
- val continuations = history.continuationHeaderChains(inChain.last, _ => true)
- continuations.length shouldBe 2
- continuations.flatMap(_.tail).map(_.encodedId).toSet should contain theSameElementsAs
- (fork1.headers ++ fork2.headers).map(_.encodedId).toSet
- }
-
- property("chainToHeader()") {
- var history = genHistory()
- //put 2 blocks
- val inChain = genHeaderChain(2, history, diffBitsOpt = None, useRealTs = false)
- history = applyHeaderChain(history, inChain)
- //apply 2 different forks
- val fork1 = genHeaderChain(2, history, diffBitsOpt = None, useRealTs = false).tail
- val fork2 = genHeaderChain(3, history, diffBitsOpt = None, useRealTs = false).tail
- history = applyHeaderChain(history, fork1)
- history = applyHeaderChain(history, fork2)
-
- val fork1Chain = history.chainToHeader(None, fork1.last)
- fork1Chain._1 shouldBe None
- fork1Chain._2 shouldEqual HeaderChain(inChain.headers ++ fork1.headers)
-
- val from1to2Chain = history.chainToHeader(Some(fork1.last), fork2.last)
- from1to2Chain._1.get shouldEqual inChain.last.id
- from1to2Chain._2.headers.map(_.height) shouldEqual fork2.headers.map(_.height)
- from1to2Chain._2.headers shouldEqual fork2.headers
- }
-
- property("commonBlockThenSuffixes()") {
- var history = genHistory()
-
- history = ensureMinimalHeight(history, BlocksInChain + 1)
-
- val forkDepth = BlocksInChain / 2
- forAll(smallInt, digest32Gen) { (forkLength: Int, extensionHash: Digest32) =>
- whenever(forkLength > forkDepth) {
-
- val fork1 = genHeaderChain(forkLength, history, diffBitsOpt = None, useRealTs = false).tail
- val common = fork1.headers(forkDepth)
- history.typedModifierById[Extension](common.extensionId)
- .map(ext => NipopowAlgos.unpackInterlinks(ext.fields).get)
- .getOrElse(Seq.empty)
- val fork2 = fork1.take(forkDepth) ++ genHeaderChain(forkLength + 1, Option(common),
- defaultDifficultyControl, extensionHash, diffBitsOpt = None, useRealTs = false)
- val fork1SuffixIds = fork1.headers.drop(forkDepth + 1).map(_.encodedId)
- val fork2SuffixIds = fork2.headers.drop(forkDepth + 1).map(_.encodedId)
- (fork1SuffixIds intersect fork2SuffixIds) shouldBe empty
-
- history = applyHeaderChain(history, fork1)
- history.bestHeaderOpt.get shouldBe fork1.last
-
- val (our, their) = history.commonBlockThenSuffixes(fork2, history.bestHeaderOpt.get, 1000)
- our.head shouldBe their.head
- our.head shouldBe common
- our.last shouldBe fork1.last
- their.last shouldBe fork2.last
- }
- }
- }
-
- property("Append headers to best chain in history") {
- var history = genHistory()
-
- val chain = genHeaderChain(BlocksInChain, history, diffBitsOpt = None, useRealTs = false)
-
- chain.headers.foreach { header =>
- val inHeight = history.heightOf(header.parentId).getOrElse(ErgoHistory.EmptyHistoryHeight)
-
- history.contains(header) shouldBe false
- history.applicable(header) shouldBe true
-
- history = history.append(header).get._1
-
- history.contains(header) shouldBe true
- history.applicable(header) shouldBe false
- history.bestHeaderOpt.get shouldBe header
- history.heightOf(header.id).get shouldBe (inHeight + 1)
- }
- }
-
- property("bestHeadersAfter returns correct number of headers") {
- val chainLength = 50
-
- var history = genHistory()
- val chain = genHeaderChain(chainLength, history, diffBitsOpt = None, useRealTs = false)
-
- history = applyHeaderChain(history, chain)
-
- val suffixLength = Random.nextInt(chainLength - 1) + 1
- val hdr = chain.headers.takeRight(suffixLength).head
- val count = Random.nextInt(suffixLength)
- history.bestHeadersAfter(hdr, count).length shouldBe count
-
- history.bestHeadersAfter(chain.last, 0).length shouldBe 0
- history.bestHeadersAfter(chain.last, 1).length shouldBe 0
- history.bestHeadersAfter(chain.last, Int.MaxValue).length shouldBe 0
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/PopowProcessorSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/PopowProcessorSpecification.scala
deleted file mode 100644
index b0d148c6b2..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/PopowProcessorSpecification.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.ergoplatform.nodeView.history
-
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.popow.PoPowHeader
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.utils.HistoryTestHelpers
-import scorex.util.ModifierId
-
-class PopowProcessorSpecification extends HistoryTestHelpers {
-
- private def genHistory(genesisIdOpt: Option[ModifierId], popowBootstrap: Boolean) =
- generateHistory(verifyTransactions = true, StateType.Utxo, PoPoWBootstrap = popowBootstrap, blocksToKeep = -1,
- epochLength = 10000, useLastEpochs = 3, initialDiffOpt = None, genesisIdOpt)
- .ensuring(_.bestFullBlockOpt.isEmpty)
-
- val toPoPoWChain = (c: Seq[ErgoFullBlock]) => c.map(b => PoPowHeader.fromBlock(b).get)
-
- property("popow proof application") {
- val senderHistory = genHistory(None, popowBootstrap = false)
- val senderChain = genChain(5000, senderHistory)
- applyChain(senderHistory, senderChain)
-
- val popowProofBytes = senderHistory.popowProofBytes().get
- val popowProof = senderHistory.nipopowSerializer.parseBytes(popowProofBytes)
-
- val receiverHistory = genHistory(senderHistory.bestHeaderAtHeight(1).map(_.id), popowBootstrap = true)
- receiverHistory.headersHeight shouldBe 0
- receiverHistory.applyPopowProof(popowProof)
- receiverHistory.headersHeight shouldBe senderHistory.headersHeight
- receiverHistory.bestHeaderOpt.get shouldBe senderHistory.bestHeaderOpt.get
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/UtxoSetSnapshotProcessorSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/UtxoSetSnapshotProcessorSpecification.scala
deleted file mode 100644
index 3903251054..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/UtxoSetSnapshotProcessorSpecification.scala
+++ /dev/null
@@ -1,94 +0,0 @@
-package org.ergoplatform.nodeView.history
-
-import org.ergoplatform.nodeView.history.storage.HistoryStorage
-import org.ergoplatform.nodeView.history.storage.modifierprocessors.UtxoSetSnapshotProcessor
-import org.ergoplatform.nodeView.state.{StateType, UtxoState}
-import org.ergoplatform.settings.{Algos, ErgoSettings}
-import org.ergoplatform.utils.HistoryTestHelpers
-import scorex.core.VersionTag
-import scorex.core.serialization.{ManifestSerializer, SubtreeSerializer}
-import scorex.db.LDBVersionedStore
-import scorex.util.ModifierId
-
-import scala.util.Random
-
-class UtxoSetSnapshotProcessorSpecification extends HistoryTestHelpers {
-
- private val s = settings
-
- val epochLength = 20
-
- val utxoSetSnapshotProcessor = new UtxoSetSnapshotProcessor {
- var minimalFullBlockHeightVar = ErgoHistory.GenesisHeight
- override protected val settings: ErgoSettings = s.copy(chainSettings =
- s.chainSettings.copy(voting = s.chainSettings.voting.copy(votingLength = epochLength)))
- override protected val historyStorage: HistoryStorage = HistoryStorage(settings)
- override def readMinimalFullBlockHeight() = minimalFullBlockHeightVar
- override def writeMinimalFullBlockHeight(height: Int): Unit = {
- minimalFullBlockHeightVar = height
- }
- }
-
- var history = generateHistory(
- verifyTransactions = true,
- StateType.Utxo,
- PoPoWBootstrap = false,
- blocksToKeep = -1,
- epochLength = epochLength,
- useLastEpochs = 2,
- initialDiffOpt = None)
-
- val chain = genHeaderChain(epochLength + 1, history, diffBitsOpt = None, useRealTs = false)
- history = applyHeaderChain(history, chain)
-
- property("registerManifestToDownload + getUtxoSetSnapshotDownloadPlan + getChunkIdsToDownload") {
- val bh = boxesHolderGenOfSize(32 * 1024).sample.get
- val us = createUtxoState(bh, parameters)
-
- val snapshotHeight = epochLength - 1
- val serializer = ManifestSerializer.defaultSerializer
-
- us.dumpSnapshot(snapshotHeight, us.rootDigest.dropRight(1))
- val manifestId = us.snapshotsDb.readSnapshotsInfo.availableManifests.apply(snapshotHeight)
- val manifestBytes = us.snapshotsDb.readManifestBytes(manifestId).get
- val manifest = serializer.parseBytes(manifestBytes)
- val subtreeIds = manifest.subtreesIds
- val subtreeIdsEncoded = subtreeIds.map(id => ModifierId @@ Algos.encode(id))
-
- subtreeIds.foreach {sid =>
- val subtreeBytes = us.snapshotsDb.readSubtreeBytes(sid).get
- val subtree = SubtreeSerializer.parseBytes(subtreeBytes)
- subtree.verify(sid) shouldBe true
- }
-
- val blockId = ModifierId @@ Algos.encode(Array.fill(32)(Random.nextInt(100).toByte))
- utxoSetSnapshotProcessor.registerManifestToDownload(manifest, snapshotHeight, Seq.empty)
- val dp = utxoSetSnapshotProcessor.utxoSetSnapshotDownloadPlan().get
- dp.snapshotHeight shouldBe snapshotHeight
- val expected = dp.expectedChunkIds.map(id => ModifierId @@ Algos.encode(id))
- expected shouldBe subtreeIdsEncoded
- val toDownload = utxoSetSnapshotProcessor.getChunkIdsToDownload(expected.size).map(id => ModifierId @@ Algos.encode(id))
- toDownload shouldBe expected
-
- subtreeIds.foreach { subtreeId =>
- val subtreeBytes = us.snapshotsDb.readSubtreeBytes(subtreeId).get
- utxoSetSnapshotProcessor.registerDownloadedChunk(subtreeId, subtreeBytes)
- }
- val s = utxoSetSnapshotProcessor.downloadedChunksIterator().map(s => ModifierId @@ Algos.encode(s.id)).toSeq
- s shouldBe subtreeIdsEncoded
-
- val dir = createTempDir
- val store = new LDBVersionedStore(dir, initialKeepVersions = 100)
- val restoredProver = utxoSetSnapshotProcessor.createPersistentProver(store, history, snapshotHeight, blockId).get
- bh.sortedBoxes.foreach { box =>
- restoredProver.unauthenticatedLookup(box.id).isDefined shouldBe true
- }
- restoredProver.checkTree(postProof = false)
- val restoredState = new UtxoState(restoredProver, version = VersionTag @@@ blockId, store, settings)
- restoredState.stateContext.currentHeight shouldBe (epochLength - 1)
- bh.sortedBoxes.foreach { box =>
- restoredState.boxById(box.id).isDefined shouldBe true
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/VerifyADHistorySpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/VerifyADHistorySpecification.scala
deleted file mode 100644
index 0240d00afb..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/VerifyADHistorySpecification.scala
+++ /dev/null
@@ -1,497 +0,0 @@
-package org.ergoplatform.nodeView.history
-
-import org.ergoplatform.modifiers.history.extension.Extension
-import org.ergoplatform.modifiers.history.HeaderChain
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.{ErgoFullBlock, BlockSection}
-import org.ergoplatform.nodeView.ErgoModifiersCache
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.utils.HistoryTestHelpers
-import scorex.core.consensus.ProgressInfo
-import scorex.core.consensus.ModifierSemanticValidity.{Absent, Invalid, Unknown, Valid}
-import scorex.testkit.utils.NoShrink
-
-import scala.collection.mutable.ArrayBuffer
-import scala.util.Random
-
-class VerifyADHistorySpecification extends HistoryTestHelpers with NoShrink {
-
- type PM = BlockSection
-
- private def genHistory(blocksNum: Int = 0,
- minFullHeight: Option[Int] = Some(ErgoHistory.GenesisHeight)): (ErgoHistory, Seq[ErgoFullBlock]) = {
- val inHistory = generateHistory(verifyTransactions = true, StateType.Digest, PoPoWBootstrap = false, BlocksToKeep)
- minFullHeight.foreach { h =>
- inHistory.writeMinimalFullBlockHeight(h)
- inHistory.isHeadersChainSyncedVar = true
- }
-
- if (blocksNum > 0) {
- val chain = genChain(blocksNum, inHistory)
- (applyChain(inHistory, chain), chain)
- } else {
- (inHistory, Seq.empty)
- }
- }
-
- property("Forks that include genesis block") {
- var (history, _) = genHistory()
- val fork1 = genChain(3, history)
- val fork2 = genChain(2, history)
- val fork3 = genChain(4, history)
-
- // apply 3 headers long chain
- history = applyChain(history, fork1)
- history.bestFullBlockOpt.get.header shouldBe history.bestHeaderOpt.get
- history.bestHeaderOpt.get shouldBe fork1.last.header
-
- // apply 2 headers long chain, should stay on previous one
- history = applyChain(history, fork2)
- history.bestFullBlockOpt.get.header shouldBe history.bestHeaderOpt.get
- history.bestHeaderOpt.get shouldBe fork1.last.header
-
- // apply 4 headers long chain, should update chain
- history = applyChain(history, fork3)
- history.bestHeaderOpt.get shouldBe fork3.last.header
- history.bestFullBlockOpt.get.header.height shouldBe fork3.last.header.height
-
- }
-
-
- property("ErgoModifiersCache.findCandidateKey() should find headers in case of forks") {
- val modifiersCache = new ErgoModifiersCache(Int.MaxValue)
-
- var (history, _) = genHistory(2)
-
- val fork1 = genChain(2, history).tail
- val fork2 = genChain(3, history).tail
-
- history = applyChain(history, fork1)
-
- fork2.foreach { fb =>
- modifiersCache.put(fb.header.id, fb.header)
- }
- history.applicable(fork2.head.header) shouldBe true
- modifiersCache.contains(fork2.head.header.id) shouldBe true
- modifiersCache.findCandidateKey(history).isDefined shouldBe true
- }
-
- property("should not be able to apply blocks older than blocksToKeep") {
- var history = genHistory()._1
- history.bestFullBlockOpt shouldBe None
-
- val chain = genChain(BlocksToKeep * 2)
-
- history = applyHeaderChain(history, HeaderChain(chain.map(_.header)))
- history.bestHeaderOpt.get shouldBe chain.last.header
- history.bestFullBlockOpt shouldBe None
-
- val fullBlocksToApply = chain.tail
- history.updateBestFullBlock(fullBlocksToApply(BlocksToKeep - 1).header)
-
- history.applicable(chain.head.blockTransactions) shouldBe false
-
- history = applyBlock(history, fullBlocksToApply.head)
- history.bestFullBlockOpt.get.header shouldBe fullBlocksToApply.head.header
-
- history.applicable(chain.head.blockTransactions) shouldBe false
-
- fullBlocksToApply.tail.foreach { f =>
- history = applyBlock(history, f)
- }
- history.bestFullBlockOpt.get.header shouldBe fullBlocksToApply.last.header
-
- //block sections should be already pruned
- fullBlocksToApply.head.header.sectionIds.foreach(id => history.contains(id._2) shouldBe false)
-
- //block transactions should not be able to apply since they are too far back in history
- fullBlocksToApply.head.blockSections.foreach(s => history.applicable(s) shouldBe false)
- }
-
- property("proofs and transactions application in random order with forks") {
- forAll(smallInt, positiveLongGen) { (chainHeight, seed) =>
- whenever(chainHeight > 0) {
- val (history, chain) = genHistory(1)
- val r = new Random(seed)
- val genesis = chain.head
- history.bestFullBlockOpt shouldBe Some(genesis)
-
- val chains = Seq(genChain(chainHeight, genesis), genChain(chainHeight + 1, genesis)).map(_.tail)
- chains.foreach(chain => applyHeaderChain(history, HeaderChain(chain.map(_.header))))
- val indices: Seq[(Int, Int)] = chains.indices.flatMap { chainIndex =>
- val chain = chains(chainIndex)
- chain.indices.map(blockIndex => (chainIndex, blockIndex))
- }
-
- val appended: ArrayBuffer[ErgoFullBlock] = ArrayBuffer.empty
-
- def findBestBlock(appendedToCheck: Seq[ErgoFullBlock]): ErgoFullBlock = {
- def firstInAppended(h: Header): Header = {
- appended.find(_.header.id == h.parentId).map(_.header) match {
- case Some(prev) => firstInAppended(prev)
- case None => h
- }
- }
-
- if (appendedToCheck.isEmpty) {
- genesis
- } else {
- val best = appendedToCheck.maxBy(_.header.height)
- if (firstInAppended(best.header).parentId == genesis.id) {
- best
- } else {
- findBestBlock(appendedToCheck.filterNot(_.id == best.id))
- }
- }
- }
-
- r.shuffle(indices).foreach { i =>
- val block = chains(i._1)(i._2)
- val sectionsToAppend = block.blockSections.filterNot(_.modifierTypeId == Extension.modifierTypeId)
- r.shuffle(sectionsToAppend).foreach(s => history.append(s) shouldBe 'success)
-
- appended += block
-
- sectionsToAppend.forall(history.contains) shouldBe true
- }
- }
- }
- }
-
- property("apply proofs that link incomplete chain") {
- var history = genHistory()._1
- val chain = genChain(4)
-
- val block0 = chain.head
- val block1 = chain(1)
- val block2 = chain(2)
- val block3 = chain(3)
-
- applyHeaderChain(history, HeaderChain(chain.map(_.header)))
- history.bestFullBlockOpt shouldBe None
- history.bestHeaderOpt shouldBe Some(block3.header)
-
- history = applySection(history, block0.adProofs.get)
- history.contains(block0.adProofs.get.id) shouldBe true
-
- history = applySection(history, block2.adProofs.get)
- history.contains(block2.adProofs.get.id) shouldBe true
-
- history = applySection(history, block3.adProofs.get)
- history.contains(block3.adProofs.get.id) shouldBe true
-
- history = applySection(history, block1.adProofs.get)
- history.contains(block1.adProofs.get.id) shouldBe true
-
- history = applyBlock(history, block0)
- history = applyBlock(history, block1)
- history = applyBlock(history, block2)
- history = applyBlock(history, block3)
-
- history.bestFullBlockOpt shouldBe Some(block3)
- }
-
- property("bootstrap from headers and last full blocks") {
- var history = genHistory()._1
- history.bestFullBlockOpt shouldBe None
-
- val chain = genChain(BlocksToKeep * 2)
-
- history = applyHeaderChain(history, HeaderChain(chain.map(_.header)))
- history.bestHeaderOpt.value shouldBe chain.last.header
- history.bestFullBlockOpt shouldBe None
- history.updateBestFullBlock(chain.last.header)
-
- val fullBlocksToApply = chain.takeRight(BlocksToKeep)
-
- history = applyBlock(history, fullBlocksToApply.head)
- history.bestFullBlockOpt.value.header shouldBe fullBlocksToApply.head.header
- }
-
- property("syncInfo()") {
- val (history, chain) = genHistory(BlocksInChain)
-
- val si = history.syncInfoV1.asInstanceOf[ErgoSyncInfoV1]
- si.lastHeaderIds.last shouldEqual chain.last.header.id
- }
-
- property("reportModifierIsValid should set isSemanticallyValid() result") {
- var history = genHistory(1)._1
- history.bestFullBlockOpt.isDefined shouldBe true
-
- val chain = genChain(BlocksInChain, history).tail
- chain.head.parentId shouldEqual history.bestFullBlockOpt.value.id
-
- chain.foreach { fullBlock =>
- history.bestHeaderOpt.foreach(b => b.id shouldEqual fullBlock.parentId)
- history.bestFullBlockOpt.foreach(b => b.header shouldBe history.bestHeaderOpt.value)
-
- history.isSemanticallyValid(fullBlock.header.id) shouldBe Absent
- fullBlock.blockSections.foreach(s => history.isSemanticallyValid(s.id) shouldBe Absent)
-
- history = applyBlock(history, fullBlock)
-
- history.bestFullBlockOpt.value.header shouldBe history.bestHeaderOpt.value
- history.bestHeaderOpt.value.id shouldEqual fullBlock.header.id
-
- history.isSemanticallyValid(fullBlock.header.id) shouldBe Unknown
- fullBlock.blockSections.foreach(s => history.isSemanticallyValid(s.id) shouldBe Unknown)
-
- history.reportModifierIsValid(fullBlock.header)
- fullBlock.blockSections.foreach(s => history.reportModifierIsValid(s))
-
- history.reportModifierIsValid(fullBlock)
-
- history.isSemanticallyValid(fullBlock.header.id) shouldBe Valid
- fullBlock.blockSections.foreach(s => history.isSemanticallyValid(s.id) shouldBe Valid)
- }
- }
-
- property("reportModifierIsInvalid should set isSemanticallyValid() result for all linked modifiers") {
- var history = genHistory(1)._1
-
- history.bestFullBlockOpt should not be None
-
- val chain = genChain(BlocksInChain, history.bestFullBlockOpt.get).tail
- (chain.head.header.parentId == Header.GenesisParentId) shouldBe false
-
- history = applyChain(history, chain)
-
- chain.reverse.foreach { fullBlock =>
- history.isSemanticallyValid(fullBlock.header.id) shouldBe Unknown
- history.isSemanticallyValid(fullBlock.adProofs.value.id) shouldBe Unknown
- history.isSemanticallyValid(fullBlock.blockTransactions.id) shouldBe Unknown
-
-
- val progressInfo = ProgressInfo[PM](Option(fullBlock.header.parentId), Seq(fullBlock), Seq.empty, Seq.empty)
- history.reportModifierIsInvalid(fullBlock.header, progressInfo)
-
- history.isSemanticallyValid(fullBlock.header.id) shouldBe Invalid
- history.isSemanticallyValid(fullBlock.adProofs.value.id) shouldBe Invalid
- history.isSemanticallyValid(fullBlock.blockTransactions.id) shouldBe Invalid
- }
- }
-
- property("reportModifierIsInvalid should mark invalid all forks containing this header") {
- var (history, inChain) = genHistory(2)
-
- val fork1 = genChain(3, history).tail
- val fork2 = genChain(3, history).tail
- fork1.head.parentId shouldEqual fork2.head.parentId
-
- history = applyChain(history, fork1)
- history = applyChain(history, fork2)
-
- val progressInfo = ProgressInfo[PM](Some(inChain.last.parentId), fork2, Seq.empty, Seq.empty)
- history.reportModifierIsInvalid(inChain.last.header, progressInfo)
-
- fork1.foreach { fullBlock =>
- history.isSemanticallyValid(fullBlock.header.id) shouldBe Invalid
- history.isSemanticallyValid(fullBlock.adProofs.value.id) shouldBe Invalid
- history.isSemanticallyValid(fullBlock.blockTransactions.id) shouldBe Invalid
- }
-
- fork2.foreach { fullBlock =>
- history.isSemanticallyValid(fullBlock.header.id) shouldBe Invalid
- history.isSemanticallyValid(fullBlock.adProofs.value.id) shouldBe Invalid
- history.isSemanticallyValid(fullBlock.blockTransactions.id) shouldBe Invalid
- }
- }
-
- property("reportModifierIsInvalid should return blocks to rollback and to process") {
- var history = genHistory(3)._1
- val common = history.bestFullBlockOpt.value
-
- val fork1 = genChain(3, common).tail
- val fork2 = genChain(2, common).tail
-
- history = applyChain(history, fork1)
- history = applyChain(history, fork2)
-
- history.bestHeaderOpt.value shouldBe fork1.last.header
-
- val progressInfo = ProgressInfo[PM](Some(common.parentId), fork1, Seq.empty, Seq.empty)
- history.reportModifierIsInvalid(fork1.head.header, progressInfo)
-
- history.bestHeaderOpt.value shouldBe fork2.last.header
- history.bestFullBlockOpt.value shouldBe fork2.last
- }
-
- property("reportModifierIsInvalid for non-last block in best chain without better forks") {
- var (history, chain) = genHistory(BlocksInChain)
-
- history.bestFullBlockOpt.value.header shouldBe history.bestHeaderOpt.value
- history.bestHeaderOpt.value shouldEqual chain.last.header
-
- val invalidChain = chain.takeRight(2)
-
- val progressInfo = ProgressInfo[PM](Some(invalidChain.head.parentId), invalidChain, Seq.empty, Seq.empty)
- val report = history.reportModifierIsInvalid(invalidChain.head.header, progressInfo).get
- history = report._1
- val processInfo = report._2
- processInfo.toApply.isEmpty shouldBe true
- processInfo.branchPoint.value shouldEqual invalidChain.head.header.parentId
- processInfo.toRemove shouldEqual invalidChain
-
- history.bestFullBlockOpt.value.header shouldBe history.bestHeaderOpt.value
- history.bestHeaderOpt.value.id shouldEqual invalidChain.head.parentId
- }
-
- property("Report invalid for best full block") {
- val (history, chain) = genHistory(BlocksInChain)
-
- chain.takeRight(BlocksToKeep - 2).reverse.foreach { fullBlock =>
- history.bestFullBlockOpt.value.header shouldBe history.bestHeaderOpt.value
- history.bestHeaderOpt.value shouldEqual fullBlock.header
-
- val parentHeader = history.typedModifierById[Header](fullBlock.header.parentId).value
- history.contains(parentHeader.transactionsId) shouldBe true
- history.contains(parentHeader.ADProofsId) shouldBe true
-
- val progressInfo = ProgressInfo[PM](Some(parentHeader.id), Seq(fullBlock), Seq.empty, Seq.empty)
- val (repHistory, _) = history.reportModifierIsInvalid(fullBlock.blockTransactions, progressInfo).get
- repHistory.bestFullBlockOpt.value.header shouldBe history.bestHeaderOpt.value
- repHistory.bestHeaderOpt.value shouldBe parentHeader
- }
- }
-
- property("prune old blocks test") {
- val blocksToPrune = 20
-
- val (history, chain) = genHistory(BlocksToKeep + blocksToPrune + 1)
-
- history.bestHeaderOpt.value shouldBe chain.last.header
- history.bestFullBlockOpt.value.header shouldBe chain.last.header
-
- //genesis block is not pruned
- chain.take(blocksToPrune).tail.foreach { b =>
- history.modifierById(b.header.transactionsId) shouldBe None
- history.modifierById(b.header.ADProofsId) shouldBe None
- }
-
- chain.takeRight(BlocksToKeep).foreach { b =>
- history.modifierById(b.header.transactionsId).isDefined shouldBe true
- history.modifierById(b.header.ADProofsId).isDefined shouldBe true
- }
- }
-
- property("process fork from genesis") {
- var (history, c) = genHistory(1)
- val genesis = c.head
- val fork1 = genChain(1, history.bestFullBlockOpt.value).tail
- val fork2 = genChain(2, history.bestFullBlockOpt.value).tail
-
- history = applyChain(history, fork1)
- history.bestHeaderOpt.value shouldBe fork1.last.header
-
- history = applyChain(history, fork2.dropRight(1))
- val lastBlock = fork2.last
- history = history.append(lastBlock.header).get._1
- .append(lastBlock.blockTransactions).get._1
- .append(lastBlock.extension).get._1
-
- val changes = history.append(lastBlock.adProofs.value).get
- history = changes._1
- history.bestHeaderOpt.value shouldBe fork2.last.header
-
- val processInfo = changes._2
- processInfo.branchPoint.get shouldEqual genesis.id
- processInfo.toRemove should contain theSameElementsAs fork1
- processInfo.toApply should contain theSameElementsAs fork2
-
- }
-
- property("process fork from existing chain") {
- var history = genHistory(BlocksInChain)._1
-
- history.bestFullBlockOpt.isDefined should not be None
- forAll(smallPositiveInt) { forkLength: Int =>
- whenever(forkLength > 0) {
- val branchPoint = history.bestFullBlockOpt.value
- val fork1 = genChain(forkLength, branchPoint).tail
- val fork2 = genChain(forkLength + 1, branchPoint).tail
-
- history = applyChain(history, fork1)
- history.bestHeaderOpt.value shouldBe fork1.last.header
-
- history = applyChain(history, fork2.dropRight(1))
- val lastBlock = fork2.last
- history = history.append(lastBlock.header).get._1
- .append(lastBlock.extension).get._1
- .append(lastBlock.blockTransactions).get._1
-
- val changes = history.append(lastBlock.adProofs.value).get
- history = changes._1
- history.bestHeaderOpt.value shouldBe fork2.last.header
-
- val processInfo = changes._2
- processInfo.branchPoint.value shouldEqual branchPoint.id
- processInfo.toRemove should contain theSameElementsAs fork1
- processInfo.toApply should contain theSameElementsAs fork2
- }
- }
- }
-
- property("Appended full blocks to best chain in full history") {
- var history = genHistory(1)._1
- history.bestFullBlockOpt.nonEmpty shouldBe true
-
- val chain = genChain(BlocksInChain, history).tail
- chain.foreach { fullBlock =>
- val startFullBlock = history.bestFullBlockOpt.value
- val header = fullBlock.header
- val txs = fullBlock.blockTransactions
- val proofs = fullBlock.adProofs.value
- val extension = fullBlock.extension
- history.contains(header) shouldBe false
- history.contains(txs) shouldBe false
- history.contains(proofs) shouldBe false
- history.contains(extension) shouldBe false
- history.applicable(header) shouldBe true
- history.applicable(proofs) shouldBe false
- history.applicable(txs) shouldBe false
- history.applicable(extension) shouldBe false
-
- history = history.append(header).get._1
-
- history.contains(header) shouldBe true
- history.contains(txs) shouldBe false
- history.contains(proofs) shouldBe false
- history.contains(extension) shouldBe false
- history.applicable(header) shouldBe false
- history.applicable(proofs) shouldBe true
- history.applicable(txs) shouldBe true
- history.applicable(extension) shouldBe true
- history.bestHeaderOpt.get shouldBe header
- history.bestFullBlockOpt.get shouldBe startFullBlock
-
- history = history.append(txs).get._1
-
- history.contains(header) shouldBe true
- history.contains(txs) shouldBe true
- history.contains(proofs) shouldBe false
- history.contains(extension) shouldBe false
- history.applicable(header) shouldBe false
- history.applicable(proofs) shouldBe true
- history.applicable(extension) shouldBe true
- history.applicable(txs) shouldBe false
- history.bestHeaderOpt.get shouldBe header
- history.bestFullBlockOpt.get shouldBe startFullBlock
-
- history = history.append(proofs).get._1
- history = history.append(extension).get._1
-
- history.contains(header) shouldBe true
- history.contains(txs) shouldBe true
- history.contains(proofs) shouldBe true
- history.contains(extension) shouldBe true
- history.applicable(header) shouldBe false
- history.applicable(proofs) shouldBe false
- history.applicable(extension) shouldBe false
- history.applicable(txs) shouldBe false
- history.bestHeaderOpt.value shouldBe header
- history.bestFullBlockOpt.value shouldBe fullBlock
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/VerifyNonADHistorySpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/VerifyNonADHistorySpecification.scala
deleted file mode 100644
index cb024dd9bb..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/VerifyNonADHistorySpecification.scala
+++ /dev/null
@@ -1,217 +0,0 @@
-package org.ergoplatform.nodeView.history
-
-import org.ergoplatform.modifiers.{ErgoFullBlock, NetworkObjectTypeId}
-import org.ergoplatform.modifiers.history._
-import org.ergoplatform.modifiers.history.extension.Extension
-import org.ergoplatform.modifiers.history.header.HeaderSerializer
-import org.ergoplatform.nodeView.history.storage.modifierprocessors.FullBlockProcessor
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.settings.Algos
-import org.ergoplatform.utils.HistoryTestHelpers
-import scorex.core.consensus.ProgressInfo
-
-class VerifyNonADHistorySpecification extends HistoryTestHelpers {
- import scorex.core.utils.MapPimp
-
- private def genHistory() =
- generateHistory(verifyTransactions = true, StateType.Utxo, PoPoWBootstrap = false, BlocksToKeep)
-
- property("block sections application in incorrect order") {
- var history = genHistory()
- val chain = genChain(6, history)
- if (!history.isHeadersChainSynced) {
- history.updateBestFullBlock(chain.last.header)
- }
- history = applyHeaderChain(history, HeaderChain(chain.map(_.header)))
- chain.foreach(fb => history.append(fb.extension).get)
-
- history = history.append(chain(1).blockTransactions).get._1
- history.bestFullBlockOpt shouldBe None
- val pi1 = history.append(chain(0).blockTransactions).get._2
- history.bestFullBlockOpt.value shouldBe chain(1)
- pi1.toApply.length shouldBe 2
-
- chain.drop(3).foreach(c => history.append(c.blockTransactions))
- history.bestFullBlockOpt.value.header.height shouldBe chain(1).header.height
-
- val (hi, pi) = history.append(chain(2).blockTransactions).get
- val expected = chain.drop(2)
-
- expected.forall(b => hi.asInstanceOf[FullBlockProcessor].isInBestFullChain(b.id)) shouldBe true
-
- pi.toApply.map(_.asInstanceOf[ErgoFullBlock]) shouldBe expected
- }
-
- property("full chain status updating") {
-
- def isInBestChain(b: ErgoFullBlock, h: ErgoHistory): Boolean = {
- h.asInstanceOf[FullBlockProcessor].isInBestFullChain(b.id)
- }
-
- var history = genHistory()
- val initChain = genChain(6, history)
-
- val stableChain = initChain.take(3)
- val altChain = genChain(8, stableChain.last).tail
-
- // apply initial initChain (1 to 6)
- history = applyChain(history, initChain)
-
- history.bestFullBlockIdOpt.get shouldEqual initChain.last.id
- initChain.forall(b => isInBestChain(b, history)) shouldBe true
-
- // apply better initChain forking initial one (1 to 3 (init initChain), 3 to 11 (new initChain))
- history = applyChain(history, altChain)
-
- history.bestFullBlockIdOpt.get shouldEqual altChain.last.id
- // first blocks from init chain are still marked as best chain
- stableChain.forall(b => isInBestChain(b, history)) shouldBe true
- // other blocks from init chain are no more in best chain
- initChain.drop(3).forall(b => !isInBestChain(b, history)) shouldBe true
- // all blocks from fork are marked as best chain
- altChain.forall(b => isInBestChain(b, history)) shouldBe true
-
- val invalidChainHead = altChain.head
-
- // invalidate modifier from fork
- history.reportModifierIsInvalid(invalidChainHead.blockTransactions,
- ProgressInfo(None, Seq.empty, Seq.empty, Seq.empty))
-
- history.bestFullBlockIdOpt.get shouldEqual initChain.last.id
-
- // all blocks from init chain are marked as best chain again
- initChain.forall(b => isInBestChain(b, history)) shouldBe true
- // blocks from fork no longer marked as best chain
- altChain.forall(b => !isInBestChain(b, history)) shouldBe true
- }
-
- property("bootstrap from headers and last full blocks") {
- var history = genHistory()
- history.bestFullBlockOpt shouldBe None
-
- val chain = genChain(BlocksToKeep * 2)
-
- history = applyHeaderChain(history, HeaderChain(chain.map(_.header)))
- history.bestHeaderOpt.value shouldBe chain.last.header
- history.bestFullBlockOpt shouldBe None
-
- if (!history.isHeadersChainSynced) {
- history.updateBestFullBlock(chain.last.header)
- }
-
- // Until UTXO snapshot synchronization is implemented, we should always start to apply full blocks from genesis
- val fullBlocksToApply = chain
-
- history = history.append(fullBlocksToApply.head.blockTransactions).get._1
- history = history.append(fullBlocksToApply.head.extension).get._1
- history.bestFullBlockOpt.get.header shouldBe fullBlocksToApply.head.header
- }
-
- property("nextModifiersToDownload") {
- var history = genHistory()
- val chain = genChain(BlocksToKeep)
- history = applyBlock(history, chain.head)
- history.bestFullBlockOpt.value shouldBe chain.head
- history = applyHeaderChain(history, HeaderChain(chain.map(_.header).tail))
-
- val missedChain = chain.tail.toList
- val missedBS = missedChain.flatMap { fb =>
- Seq((BlockTransactions.modifierTypeId, fb.blockTransactions.encodedId), (Extension.modifierTypeId, fb.extension.encodedId))
- }.foldLeft(Map.empty[NetworkObjectTypeId.Value, Seq[String]]) { case (newAcc, (mType, mId)) =>
- newAcc.adjust(mType)(_.fold(Seq(mId))(_ :+ mId))
- }
-
- history.nextModifiersToDownload(1, (_, id) => !history.contains(id))
- .map(id => (id._1, id._2.map(Algos.encode))) shouldEqual missedBS.mapValues(_.take(1)).view.force
-
- history.nextModifiersToDownload(2 * (BlocksToKeep - 1), (_, id) => !history.contains(id))
- .map(id => (id._1, id._2.map(Algos.encode))) shouldEqual missedBS
-
- history.nextModifiersToDownload(2, (_, id) => !history.contains(id) && (id != missedChain.head.blockTransactions.id))
- .map(id => (id._1, id._2.map(Algos.encode))) shouldEqual missedBS.mapValues(_.take(2).filter( _ != missedChain.head.blockTransactions.id)).view.force
- }
-
- property("append header as genesis") {
- val history = genHistory()
- history.bestHeaderOpt shouldBe None
- val header = genHeaderChain(1, history, diffBitsOpt = None, useRealTs = false).head
- val updHistory = history.append(header).get._1
- updHistory.bestHeaderOpt shouldBe Some(header)
- val restoredHeader = updHistory.modifierById(header.id)
- restoredHeader shouldBe Some(header)
-
- val bytesFromSerializer = HeaderSerializer.toBytes(header)
- val bytesFromDb = updHistory.modifierBytesById(header.id).get
- bytesFromSerializer.sameElements(bytesFromDb) shouldBe true
- }
-
- property("append header as genesis - via applyHeaderChain") {
- val history = genHistory()
- history.bestHeaderOpt shouldBe None
- val header = genHeaderChain(1, history, diffBitsOpt = None, useRealTs = false).head
-
- val updHistory = applyHeaderChain(history, HeaderChain(Seq(header)))
- updHistory.bestHeaderOpt shouldBe Some(header)
- updHistory.modifierById(header.id) shouldBe Some(header)
- }
-
- property("append header to genesis - 2") {
- val (us, bh) = createUtxoState(settings)
-
- val block = validFullBlock(None, us, bh)
-
- val history = genHistory()
- history.bestHeaderOpt shouldBe None
- val header = block.header
-
- HeaderSerializer.parseBytes(HeaderSerializer.toBytes(header)) shouldBe header
-
- val actualHeader = history.append(header).get._1.bestHeaderOpt.value
- actualHeader shouldBe header
- }
-
- property("Appended headers and transactions blocks to best chain in tx history") {
- var history = genHistory()
-
- history = applyChain(history, genChain(BlocksInChain, history))
-
- genChain(BlocksInChain, history).tail.foreach { fullBlock =>
- val startFullBlock = history.bestFullBlockOpt.value
-
- val header = fullBlock.header
- val txs = fullBlock.blockTransactions
- val extension = fullBlock.extension
- history.contains(header) shouldBe false
- history.contains(txs) shouldBe false
- history.contains(extension) shouldBe false
- history.applicable(header) shouldBe true
- history.applicable(txs) shouldBe false
- history.applicable(extension) shouldBe false
-
- history = history.append(header).get._1
-
- history.contains(header) shouldBe true
- history.contains(txs) shouldBe false
- history.contains(extension) shouldBe false
- history.applicable(header) shouldBe false
- history.applicable(txs) shouldBe true
- history.applicable(extension) shouldBe true
- history.bestHeaderOpt.value shouldBe header
-
- history.bestFullBlockOpt.value shouldBe startFullBlock
-
- history = history.append(txs).get._1
- history = history.append(extension).get._1
-
- history.contains(header) shouldBe true
- history.contains(txs) shouldBe true
- history.contains(extension) shouldBe true
- history.applicable(header) shouldBe false
- history.applicable(txs) shouldBe false
- history.applicable(extension) shouldBe false
- history.bestHeaderOpt.value shouldBe header
- history.bestFullBlockOpt.value.header shouldBe fullBlock.header
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexerSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexerSpecification.scala
deleted file mode 100644
index a377e8a2e7..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexerSpecification.scala
+++ /dev/null
@@ -1,452 +0,0 @@
-package org.ergoplatform.nodeView.history.extra
-
-import org.ergoplatform.ErgoBox.TokenId
-import org.ergoplatform.ErgoLikeContext.Height
-import org.ergoplatform._
-import org.ergoplatform.mining.difficulty.DifficultySerializer
-import org.ergoplatform.mining.{AutolykosPowScheme, CandidateBlock, CandidateGenerator}
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.extension.{Extension, ExtensionCandidate}
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.history.popow.NipopowAlgos
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction}
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.history.extra.IndexedErgoAddressSerializer.hashErgoTree
-import org.ergoplatform.nodeView.history.extra.SegmentSerializer.{boxSegmentId, txSegmentId}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.SortingOption
-import org.ergoplatform.nodeView.state._
-import org.ergoplatform.settings.{ErgoSettings, NetworkType, NipopowSettings, NodeConfigurationSettings, UtxoSettings}
-import org.ergoplatform.utils.{ErgoPropertyTest, ErgoTestHelpers, HistoryTestHelpers}
-import scorex.util.{ModifierId, bytesToId}
-import sigmastate.Values
-import sigmastate.crypto.DLogProtocol.ProveDlog
-import sigmastate.eval.Extensions._
-import sigmastate.eval._
-import sigma.{Coll, Colls}
-import spire.implicits.cfor
-
-import java.io.File
-import scala.annotation.tailrec
-import scala.collection.mutable
-import scala.collection.mutable.ArrayBuffer
-import scala.concurrent.duration.{DurationInt, FiniteDuration}
-import scala.reflect.ClassTag
-import scala.util.{Random, Try}
-
-class ExtraIndexerSpecification extends ErgoPropertyTest with ExtraIndexerBase with HistoryTestHelpers {
-
- type ID_LL = mutable.HashMap[ModifierId,(Long,Long)]
-
- override protected val saveLimit: Int = 1 // save every block
- override protected implicit val segmentTreshold: Int = 8 // split to smaller segments
- override protected implicit val addressEncoder: ErgoAddressEncoder = initSettings.chainSettings.addressEncoder
-
- val nodeSettings: NodeConfigurationSettings = NodeConfigurationSettings(StateType.Utxo, verifyTransactions = true,
- -1, UtxoSettings(utxoBootstrap = false, 0, 2), NipopowSettings(nipopowBootstrap = false, 1), mining = false,
- ChainGenerator.txCostLimit, ChainGenerator.txSizeLimit, useExternalMiner = false, internalMinersCount = 1,
- internalMinerPollingInterval = 1.second, miningPubKeyHex = None, offlineGeneration = false,
- 200, 5.minutes, 100000, 1.minute, mempoolSorting = SortingOption.FeePerByte, rebroadcastCount = 20,
- 1000000, 100, adProofsSuffixLength = 112 * 1024, extraIndex = false)
-
- val HEIGHT: Int = 50
- val BRANCHPOINT: Int = HEIGHT / 2
-
- def createDB(): Unit = {
- val dir: File = createTempDir
- dir.mkdirs()
-
- val fullHistorySettings: ErgoSettings = ErgoSettings(dir.getAbsolutePath, NetworkType.TestNet, initSettings.chainSettings,
- nodeSettings, settings.scorexSettings, settings.walletSettings, settings.cacheSettings)
-
- _history = ErgoHistory.readOrGenerate(fullHistorySettings)(null)
-
- ChainGenerator.generate(HEIGHT, dir)(_history)
-
- // reset all variables
- indexedHeight = 0
- globalTxIndex = 0L
- globalBoxIndex = 0L
- lastWroteToDB = 0
- caughtUp = false
- rollback = false
- general.clear()
- boxes.clear()
- trees.clear()
- tokens.clear()
- segments.clear()
- }
-
- def manualIndex(limit: Int): (ID_LL, // address -> (erg,tokenSum)
- ID_LL, // tokenId -> (boxesCount,_)
- Int, // txs indexed
- Int) = { // boxes indexed
- var txsIndexed = 0
- var boxesIndexed = 0
- val addresses: ID_LL = mutable.HashMap[ModifierId,(Long,Long)]()
- val indexedTokens: ID_LL = mutable.HashMap[ModifierId,(Long,Long)]()
- cfor(1)(_ <= limit, _ + 1) { i =>
- _history.getReader.bestBlockTransactionsAt(i).get.txs.foreach { tx =>
- txsIndexed += 1
- if (i != 1) {
- tx.inputs.foreach { input =>
- val iEb: IndexedErgoBox = _history.getReader.typedExtraIndexById[IndexedErgoBox](bytesToId(input.boxId)).get
- val address = hashErgoTree(ExtraIndexer.getAddress(iEb.box.ergoTree)(addressEncoder).script)
- val prev = addresses(address)
- addresses.put(address, (prev._1 - iEb.box.value, prev._2 - iEb.box.additionalTokens.toArray.map(_._2).sum))
- }
- }
- tx.outputs.foreach { output =>
- boxesIndexed += 1
- val address = hashErgoTree(addressEncoder.fromProposition(output.ergoTree).get.script)
- val prev = addresses.getOrElse(address, (0L, 0L))
- addresses.put(address, (prev._1 + output.value, prev._2 + output.additionalTokens.toArray.map(_._2).sum))
- cfor(0)(_ < output.additionalTokens.length, _ + 1) { j =>
- val token = IndexedToken.fromBox(new IndexedErgoBox(i, None, None, output, 0), j)
- val prev2 = indexedTokens.getOrElse(token.id, (0L, 0L))
- indexedTokens.put(token.id, (prev2._1 + 1, 0))
- }
- }
- }
- }
- (addresses, indexedTokens, txsIndexed, boxesIndexed)
- }
-
- def checkSegmentables[T <: Segment[_] : ClassTag](segmentables: ID_LL,
- isChild: Boolean = false,
- check: ((T, (Long, Long))) => Boolean
- ): Int = {
- var errors: Int = 0
- segmentables.foreach { segmentable =>
- history.typedExtraIndexById[T](segmentable._1) match {
- case Some(obj: T) =>
- if(isChild) { // this is a segment
- // check tx segments
- val txSegments: ID_LL = mutable.HashMap.empty[ModifierId,(Long,Long)]
- txSegments ++= (0 until obj.txSegmentCount).map(n => obj.idMod(txSegmentId(obj.parentId, n))).map(Tuple2(_, (0L, 0L)))
- checkSegmentables(txSegments, isChild = true, check) shouldBe 0
- // check box segments
- val boxSegments: ID_LL = mutable.HashMap.empty[ModifierId,(Long,Long)]
- boxSegments ++= (0 until obj.boxSegmentCount).map(n => obj.idMod(boxSegmentId(obj.parentId, n))).map(Tuple2(_, (0L, 0L)))
- checkSegmentables(boxSegments, isChild = true, check) shouldBe 0
- }else { // this is the parent object
- // check properties of object
- if(!check((obj, segmentable._2)))
- errors += 1
- // check boxes in memory
- obj.boxes.foreach { boxNum =>
- NumericBoxIndex.getBoxByNumber(history, boxNum) match {
- case Some(iEb) =>
- if (iEb.isSpent)
- boxNum.toInt should be <= 0
- else
- boxNum.toInt should be >= 0
- case None =>
- System.err.println(s"Box $boxNum not found in database")
- errors += 1
- }
- }
- // check txs in memory
- obj.txs.foreach { txNum =>
- NumericTxIndex.getTxByNumber(history, txNum) shouldNot be(empty)
- }
- }
- case None =>
- System.err.println(s"Segmentable object ${segmentable._1} should exist, but was not found")
- errors += 1
- }
- }
- errors
- }
-
- def checkAddresses(addresses: ID_LL): Int =
- checkSegmentables[IndexedErgoAddress](addresses, isChild = false, seg => {
- seg._1.balanceInfo.get.nanoErgs == seg._2._1 && seg._1.balanceInfo.get.tokens.map(_._2).sum == seg._2._2
- })
-
- def checkTokens(indexedTokens: ID_LL): Int =
- checkSegmentables[IndexedToken](indexedTokens, isChild = false, seg => {
- seg._1.boxCount == seg._2._1
- })
-
- property("extra indexer transactions") {
- createDB()
- run()
- cfor(0)(_ < globalTxIndex, _ + 1) {n =>
- val id = history.typedExtraIndexById[NumericTxIndex](bytesToId(NumericTxIndex.indexToBytes(n)))
- id shouldNot be(empty)
- history.typedExtraIndexById[IndexedErgoTransaction](id.get.m) shouldNot be(empty)
- }
- }
-
- property("extra indexer boxes") {
- createDB()
- run()
- cfor(0)(_ < globalBoxIndex, _ + 1) { n =>
- val id = history.typedExtraIndexById[NumericBoxIndex](bytesToId(NumericBoxIndex.indexToBytes(n)))
- id shouldNot be(empty)
- history.typedExtraIndexById[IndexedErgoBox](id.get.m) shouldNot be(empty)
- }
- }
-
- property("extra indexer addresses") {
- createDB()
- run()
- val (addresses, _, _, _) = manualIndex(HEIGHT)
- checkAddresses(addresses) shouldBe 0
- }
-
- property("extra indexer tokens") {
- createDB()
- run()
- val (_, indexedTokens, _, _) = manualIndex(HEIGHT)
- checkTokens(indexedTokens) shouldBe 0
- }
-
- property("extra indexer rollback") {
- createDB()
-
- run()
-
- val txIndexBefore = globalTxIndex
- val boxIndexBefore = globalBoxIndex
-
- // manually count balances
- val (addresses, indexedTokens, txsIndexed, boxesIndexed) = manualIndex(BRANCHPOINT)
-
- // perform rollback
- removeAfter(BRANCHPOINT)
-
- // address balances
- checkAddresses(addresses) shouldBe 0
-
- // token indexes
- checkTokens(indexedTokens) shouldBe 0
-
- // check indexnumbers
- globalTxIndex shouldBe txsIndexed
- globalBoxIndex shouldBe boxesIndexed
-
- // check txs
- cfor(0)(_ < txIndexBefore, _ + 1) {txNum =>
- val txOpt = history.typedExtraIndexById[NumericTxIndex](bytesToId(NumericTxIndex.indexToBytes(txNum)))
- if(txNum < globalTxIndex)
- txOpt shouldNot be(empty)
- else
- txOpt shouldBe None
- }
-
- // check boxes
- cfor(0)(_ < boxIndexBefore, _ + 1) { boxNum =>
- val boxOpt = history.typedExtraIndexById[NumericBoxIndex](bytesToId(NumericBoxIndex.indexToBytes(boxNum)))
- if (boxNum < globalBoxIndex)
- boxOpt shouldNot be(empty)
- else
- boxOpt shouldBe None
- }
-
- // -------------------------------------------------------------------
- // restart indexer to catch up
- run()
-
- // Check addresses again
- val (addresses2, indexedTokens2, _, _) = manualIndex(HEIGHT)
- checkAddresses(addresses2) shouldBe 0
- checkTokens(indexedTokens2) shouldBe 0
-
- // check indexnumbers again
- globalTxIndex shouldBe txIndexBefore
- globalBoxIndex shouldBe boxIndexBefore
-
- // check txs after caught up
- cfor(0)(_ < txIndexBefore, _ + 1) { txNum =>
- history.typedExtraIndexById[NumericTxIndex](bytesToId(NumericTxIndex.indexToBytes(txNum))) shouldNot be(empty)
- }
-
- // check boxes after caught up
- cfor(0)(_ < boxIndexBefore, _ + 1) { boxNum =>
- history.typedExtraIndexById[NumericBoxIndex](bytesToId(NumericBoxIndex.indexToBytes(boxNum))) shouldNot be(empty)
- }
-
- }
-
-}
-
-object ChainGenerator extends ErgoTestHelpers {
-
- val pow: AutolykosPowScheme = new AutolykosPowScheme(powScheme.k, powScheme.n)
- val blockInterval: FiniteDuration = 2.minute
- val EmissionTxCost: Long = 20000
- val MinTxAmount: Long = 2000000
- val RewardDelay: Int = initSettings.chainSettings.monetary.minerRewardDelay
- val MaxTxsPerBlock: Int = 10
- val minerPk: ProveDlog = defaultProver.hdKeys.head.publicImage
- val selfAddressScript: Values.ErgoTree = P2PKAddress(minerPk).script
- val minerProp: Values.ErgoTree = ErgoTreePredef.rewardOutputScript(RewardDelay, minerPk)
- val votingEpochLength: Height = votingSettings.votingLength
- val protocolVersion: Byte = initSettings.chainSettings.protocolVersion
- val minimalSuffix = 2
- val txCostLimit: Height = initSettings.nodeSettings.maxTransactionCost
- val txSizeLimit: Height = initSettings.nodeSettings.maxTransactionSize
-
- var startTime: Long = 0
-
- def generate(length: Int, dir: File)(history: ErgoHistory): Unit = {
- val stateDir = new File(s"${dir.getAbsolutePath}/state")
- stateDir.mkdirs()
- val (state, _) = ErgoState.generateGenesisUtxoState(stateDir, initSettings)
- System.out.println(s"Going to generate a chain at ${dir.getAbsolutePath} starting from ${history.bestFullBlockOpt}")
- startTime = System.currentTimeMillis() - (blockInterval * (length - 1)).toMillis
- val chain = loop(state, None, None, Seq())(history)
- System.out.println(s"Chain of length ${chain.length} generated")
- history.bestHeaderOpt shouldBe history.bestFullBlockOpt.map(_.header)
- history.bestFullBlockOpt.get.id shouldBe chain.last
- System.out.println("History was generated successfully")
- }
-
- @tailrec
- private def loop(state: UtxoState,
- initBox: Option[ErgoBox],
- last: Option[Header],
- acc: Seq[ModifierId])(history: ErgoHistory): Seq[ModifierId] = {
- val time: Long = last.map(_.timestamp + blockInterval.toMillis).getOrElse(startTime)
- if (time < System.currentTimeMillis()) {
- val (txs, lastOut) = genTransactions(last.map(_.height).getOrElse(ErgoHistory.GenesisHeight),
- initBox, state.stateContext)
-
- val candidate = genCandidate(defaultProver.hdPubKeys.head.key, last, time, txs, state)(history)
- val block = proveCandidate(candidate.get)
-
- history.append(block.header).get
- block.blockSections.foreach(s => if (!history.contains(s)) history.append(s).get)
-
- val outToPassNext = if (last.isEmpty) {
- block.transactions.flatMap(_.outputs).find(_.ergoTree == minerProp)
- } else {
- lastOut
- }
-
- assert(outToPassNext.isDefined)
-
- log.info(
- s"Block ${block.id} with ${block.transactions.size} transactions at height ${block.header.height} generated")
-
- loop(state.applyModifier(block, None)(_ => ()).get, outToPassNext, Some(block.header), acc :+ block.id)(history)
- } else {
- acc
- }
- }
-
- private def moveTokens(inOpt: Option[ErgoBox], cond: Boolean): Coll[(TokenId, Long)] = {
- val tokens: ArrayBuffer[(TokenId, Long)] = ArrayBuffer.empty[(TokenId, Long)]
- inOpt match {
- case Some(input) if cond =>
- tokens += Tuple2(input.id.toTokenId, math.abs(Random.nextInt()))
- case Some(tokenBox) if !cond =>
- tokenBox.additionalTokens.toArray.foreach(tokens += _)
- case _ =>
- }
- Colls.fromArray(tokens.toArray)
- }
-
- private def genTransactions(height: Height,
- inOpt: Option[ErgoBox],
- ctx: ErgoStateContext): (Seq[ErgoTransaction], Option[ErgoBox]) = {
- inOpt
- .find { bx =>
- val canUnlock = (bx.creationHeight + RewardDelay <= height) || (bx.ergoTree != minerProp)
- canUnlock && bx.ergoTree != initSettings.chainSettings.monetary.emissionBoxProposition && bx.value >= MinTxAmount
- }
- .map { input =>
- val qty = MaxTxsPerBlock
- val amount = input.value
- val outs = (0 until qty).map(i => new ErgoBoxCandidate(amount, selfAddressScript, height, moveTokens(inOpt, i == 0)))
- var i = 0
- val x = outs
- .foldLeft((Seq.empty[ErgoTransaction], input)) { case ((acc, in), out) =>
- val inputs = IndexedSeq(in)
- val newOut =
- if (i > 0)
- new ErgoBoxCandidate(amount, selfAddressScript, height, moveTokens(acc.lastOption.map(_.outputs.head), cond = false))
- else
- out
- val unsignedTx = UnsignedErgoTransaction(inputs.map(box => new UnsignedInput(box.id)), IndexedSeq(newOut))
- i += 1
- defaultProver.sign(unsignedTx, inputs, emptyDataBoxes, ctx)
- .fold(_ => acc -> in, tx => (acc :+ ErgoTransaction(tx)) -> unsignedTx.outputs.head)
- }
- ._1
- (x, Some(x.last.outputs.head))
- }
- .getOrElse(Seq.empty -> inOpt)
- }
-
- private def genCandidate(minerPk: ProveDlog,
- lastHeaderOpt: Option[Header],
- ts: Long,
- txsFromPool: Seq[ErgoTransaction],
- state: UtxoStateReader)(history: ErgoHistory): Try[CandidateBlock] = Try {
- val stateContext = state.stateContext
- val nBits: Long = lastHeaderOpt
- .map(parent => history.requiredDifficultyAfter(parent))
- .map(d => DifficultySerializer.encodeCompactBits(d))
- .getOrElse(settings.chainSettings.initialNBits)
-
- val interlinks = lastHeaderOpt
- .flatMap { h =>
- history.typedModifierById[Extension](h.extensionId)
- .flatMap(ext => NipopowAlgos.unpackInterlinks(ext.fields).toOption)
- .map(nipopowAlgos.updateInterlinks(h, _))
- }
- .getOrElse(Seq.empty)
- val interlinksExtension = nipopowAlgos.interlinksToExtension(interlinks)
-
- val (extensionCandidate, votes: Array[Byte], version: Byte) = lastHeaderOpt.map { header =>
- val newHeight = header.height + 1
- val currentParams = stateContext.currentParameters
- val betterVersion = protocolVersion > header.version
- val votingFinishHeight: Option[Height] = currentParams.softForkStartingHeight
- .map(_ + votingSettings.votingLength * votingSettings.softForkEpochs)
- val forkVotingAllowed = votingFinishHeight.forall(fh => newHeight < fh)
- val forkOrdered = settings.votingTargets.softFork != 0
- val voteForFork = betterVersion && forkOrdered && forkVotingAllowed
-
- if (newHeight % votingEpochLength == 0 && newHeight > 0) {
- val (newParams, _) = currentParams.update(newHeight, voteForFork, stateContext.votingData.epochVotes, emptyVSUpdate, votingSettings)
- (newParams.toExtensionCandidate ++ interlinksExtension,
- newParams.suggestVotes(settings.votingTargets.targets, voteForFork),
- newParams.blockVersion)
- } else {
- (nipopowAlgos.interlinksToExtension(interlinks),
- currentParams.vote(settings.votingTargets.targets, stateContext.votingData.epochVotes, voteForFork),
- currentParams.blockVersion)
- }
- }.getOrElse((interlinksExtension, Array(0: Byte, 0: Byte, 0: Byte), Header.InitialVersion))
-
- val emissionTxOpt = CandidateGenerator.collectEmission(state, minerPk, emptyStateContext)
- val txs = emissionTxOpt.toSeq ++ txsFromPool
-
- state.proofsForTransactions(txs).map { case (adProof, adDigest) =>
- CandidateBlock(lastHeaderOpt, version, nBits, adDigest, adProof, txs, ts, extensionCandidate, votes)
- }
- }.flatten
-
- @tailrec
- private def proveCandidate(candidate: CandidateBlock): ErgoFullBlock = {
- log.info(s"Trying to prove block with parent ${candidate.parentOpt.map(_.encodedId)} and timestamp ${candidate.timestamp}")
-
- pow.proveCandidate(candidate, defaultProver.hdKeys.head.privateInput.w) match {
- case Some(fb) => fb
- case _ =>
- val interlinks = candidate.parentOpt
- .map(nipopowAlgos.updateInterlinks(_, NipopowAlgos.unpackInterlinks(candidate.extension.fields).get))
- .getOrElse(Seq.empty)
- val minerTag = scorex.utils.Random.randomBytes(Extension.FieldKeySize)
- proveCandidate {
- candidate.copy(
- extension = ExtensionCandidate(Seq(Array(0: Byte, 2: Byte) -> minerTag)) ++ nipopowAlgos.interlinksToExtension(interlinks)
- )
- }
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/storage/HistoryStorageSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/storage/HistoryStorageSpec.scala
deleted file mode 100644
index 7020d1fee7..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/history/storage/HistoryStorageSpec.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.ergoplatform.nodeView.history.storage
-
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.modifiers.history.ADProofs
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.settings.Algos
-import org.ergoplatform.utils.HistoryTestHelpers
-import org.scalacheck.Gen
-import scorex.db.ByteArrayWrapper
-import scorex.util.{ModifierId, idToBytes}
-
-class HistoryStorageSpec extends HistoryTestHelpers {
-
- val db = HistoryStorage(settings)
-
- property("Write Read Remove") {
- val headers: Array[Header] = Gen.listOfN(20, defaultHeaderGen).sample.get.toArray
- val modifiers: Array[ADProofs] = Gen.listOfN(20, randomADProofsGen).sample.get.toArray
- def validityKey(id: ModifierId) = ByteArrayWrapper(Algos.hash("validity".getBytes(ErgoHistory.CharsetName) ++ idToBytes(id)))
- val indexes = headers.flatMap(h => Array(validityKey(h.id) -> Array(1.toByte)))
- db.insert(indexes, (headers ++ modifiers).asInstanceOf[Array[BlockSection]]) shouldBe 'success
-
- headers.forall(h => db.contains(h.id)) shouldBe true
- modifiers.forall(m => db.contains(m.id)) shouldBe true
-
- headers.forall(h => db.get(h.id).exists(_.nonEmpty)) shouldBe true
- modifiers.forall(m => db.get(m.id).exists(_.nonEmpty)) shouldBe true
- indexes.forall(i => db.getIndex(i._1).exists(_.nonEmpty)) shouldBe true
-
- db.remove(indexes.map(_._1), headers.map(_.id) ++ modifiers.map(_.id))
-
- headers.forall(h => !db.contains(h.id)) shouldBe true
- modifiers.forall(m => !db.contains(m.id)) shouldBe true
-
- headers.forall(h => !db.get(h.id).exists(_.nonEmpty)) shouldBe true
- modifiers.forall(m => !db.get(m.id).exists(_.nonEmpty)) shouldBe true
- indexes.forall(i => !db.getIndex(i._1).exists(_.nonEmpty)) shouldBe true
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/mempool/ErgoMemPoolSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/mempool/ErgoMemPoolSpec.scala
deleted file mode 100644
index 38aaa799d3..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/mempool/ErgoMemPoolSpec.scala
+++ /dev/null
@@ -1,398 +0,0 @@
-package org.ergoplatform.nodeView.mempool
-
-import org.ergoplatform.{ErgoBoxCandidate, Input}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.SortingOption
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.ProcessingOutcome
-import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
-import org.ergoplatform.settings.ErgoSettings
-import org.ergoplatform.utils.ErgoTestHelpers
-import org.ergoplatform.utils.generators.ErgoGenerators
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-import sigmastate.Values.{ByteArrayConstant, TrueLeaf}
-import sigmastate.interpreter.{ContextExtension, ProverResult}
-
-class ErgoMemPoolSpec extends AnyFlatSpec
- with ErgoGenerators
- with ErgoTestHelpers
- with ScalaCheckPropertyChecks {
-
- it should "accept valid transaction" in {
- val (us, bh) = createUtxoState(settings)
- val genesis = validFullBlock(None, us, bh)
- val wus = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get
- val txs = validTransactionsFromUtxoState(wus)
- val pool0 = ErgoMemPool.empty(settings)
- val poolAfter = txs.foldLeft(pool0) { case (pool, tx) =>
- val (p, outcome) = pool.process(UnconfirmedTransaction(tx, None), us)
- if (!outcome.isInstanceOf[ProcessingOutcome.Accepted]) {
- throw new Exception("Transaction not accepted")
- }
- p
- }
- poolAfter.spentInputs.size shouldBe txs.flatMap(_.inputs).size
-
- // light mode
- val poolLight = ErgoMemPool.empty(lightModeSettings)
- txs.foreach { tx =>
- poolLight.process(UnconfirmedTransaction(tx, None), us)._2.isInstanceOf[ProcessingOutcome.Accepted] shouldBe true
- }
- }
-
- it should "respect given sorting order" in {
- implicit val ms = settings.chainSettings.monetary
- val (us, bh) = createUtxoState(settings)
- val genesis = validFullBlock(None, us, bh)
- val wus = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get
- val inputBox = wus.takeBoxes(1).head
- val feeOut = new ErgoBoxCandidate(inputBox.value, feeProp, creationHeight = 0)
- val tx = ErgoTransaction(
- IndexedSeq(new Input(inputBox.id, ProverResult.empty)),
- IndexedSeq(feeOut)
- )
-
- // Randomly initialized
- settings.nodeSettings.mempoolSorting should (be (SortingOption.FeePerByte) or be (SortingOption.FeePerCycle))
-
- val sortBySizeSettings: ErgoSettings = settings.copy(
- nodeSettings = settings.nodeSettings.copy(
- mempoolSorting = SortingOption.FeePerByte,
- ))
-
- var poolSize = ErgoMemPool.empty(sortBySizeSettings)
- poolSize = poolSize.process(UnconfirmedTransaction(tx, None), wus)._1
- val size = tx.size
- poolSize.pool.orderedTransactions.firstKey.weight shouldBe OrderedTxPool.weighted(tx, size).weight
-
- val sortByCostSettings: ErgoSettings = settings.copy(
- nodeSettings = settings.nodeSettings.copy(
- mempoolSorting = SortingOption.FeePerCycle,
- ))
-
- var poolCost = ErgoMemPool.empty(sortByCostSettings)
- poolCost = poolCost.process(UnconfirmedTransaction(tx, None), wus)._1
- val validationContext = wus.stateContext.simplifiedUpcoming()
- val cost = wus.validateWithCost(tx, validationContext, Int.MaxValue, None).get
- poolCost.pool.orderedTransactions.firstKey.weight shouldBe OrderedTxPool.weighted(tx, cost).weight
- }
-
- it should "decline already contained transaction" in {
- val (us, bh) = createUtxoState(settings)
- val genesis = validFullBlock(None, us, bh)
- val wus = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get
- val txs = validTransactionsFromUtxoState(wus)
- var pool = ErgoMemPool.empty(settings)
- txs.foreach { tx =>
- pool = pool.put(UnconfirmedTransaction(tx, None))
- }
- txs.foreach { tx =>
- pool.process(UnconfirmedTransaction(tx, None), us)._2.isInstanceOf[ProcessingOutcome.Declined] shouldBe true
- }
- }
-
- it should "reject double-spending transaction if it is paying no more than one already sitting in the pool" in {
- forAll(smallPositiveInt, smallPositiveInt) { case (n1, n2) =>
- whenever(n1 != n2) {
- val (us, bh) = createUtxoState(settings)
- val genesis = validFullBlock(None, us, bh)
- val wus = WrappedUtxoState(us, bh, settings, extendedParameters).applyModifier(genesis)(_ => ()).get
-
- val feeProp = settings.chainSettings.monetary.feeProposition
- val inputBox = wus.takeBoxes(100).collectFirst{
- case box if box.ergoTree == TrueLeaf.toSigmaProp.treeWithSegregation => box
- }.get
- val feeOut = new ErgoBoxCandidate(inputBox.value, feeProp, creationHeight = 0)
-
- def rndContext(n: Int): ContextExtension = ContextExtension(Map(
- (1: Byte) -> ByteArrayConstant(Array.fill(1 + n)(0: Byte)))
- )
-
- val tx1Like = ErgoTransaction(
- IndexedSeq(new Input(inputBox.id, new ProverResult(Array.emptyByteArray, rndContext(n1)))),
- IndexedSeq(feeOut)
- )
-
- val tx2Like = ErgoTransaction(
- IndexedSeq(new Input(inputBox.id, new ProverResult(Array.emptyByteArray, rndContext(n2)))),
- IndexedSeq(feeOut)
- )
-
- val tx1 = UnconfirmedTransaction(ErgoTransaction(tx1Like.inputs, tx1Like.outputCandidates), None)
- val tx2 = UnconfirmedTransaction(ErgoTransaction(ErgoTransaction(tx2Like.inputs, tx2Like.outputCandidates)), None)
-
- val pool0 = ErgoMemPool.empty(settings)
- val (pool, tx1Outcome) = pool0.process(tx1, us)
-
- tx1Outcome.isInstanceOf[ProcessingOutcome.Accepted] shouldBe true
-
- // tx1 and tx2 are spending the same input, and paying the same fee.
- // So if tx2 is about a bigger or equal size, it should be rejected as it is paying less for a byte.
- // Otherwise, tx2 is paying more for a byte and then it is replacing tx1.
- if (tx2.transaction.size >= tx1.transaction.size) {
- pool.process(tx2, us)._2.isInstanceOf[ProcessingOutcome.DoubleSpendingLoser] shouldBe true
- } else {
- val (updPool, outcome) = pool.process(tx2, us)
- outcome.isInstanceOf[ProcessingOutcome.Accepted] shouldBe true
- updPool.size shouldBe 1
- updPool.take(1).head.transaction.id shouldBe tx2.transaction.id
- }
- }
- }
- }
-
- it should "decline transactions invalidated earlier" in {
- val us = createUtxoState(settings)._1
- var pool = ErgoMemPool.empty(settings)
- forAll(invalidBlockTransactionsGen) { blockTransactions =>
- val unconfirmedTxs = blockTransactions.txs.map(tx => UnconfirmedTransaction(tx, None))
- unconfirmedTxs.foreach(tx => pool = pool.process(tx, us)._1)
- unconfirmedTxs.foreach(tx =>
- pool.process(tx, us)._2.isInstanceOf[ProcessingOutcome.Declined] shouldBe true)
- }
- }
-
- it should "decline transactions not meeting min fee" in {
- val (us, bh) = createUtxoState(settings)
- val genesis = validFullBlock(None, us, bh)
- val wus = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get
- val txs = validTransactionsFromUtxoState(wus)
- val unconfirmedTxs = txs.map(tx => UnconfirmedTransaction(tx, None))
-
- val maxSettings = settings.copy(nodeSettings = settings.nodeSettings.copy(minimalFeeAmount = Long.MaxValue))
- val pool = ErgoMemPool.empty(maxSettings)
- unconfirmedTxs.foreach { tx =>
- val (_, outcome) = pool.process(tx, us)
- outcome.isInstanceOf[ProcessingOutcome.Declined] shouldBe true
- outcome.asInstanceOf[ProcessingOutcome.Declined]
- .e.getMessage.contains("Min fee not met") shouldBe true
- }
-
- val minSettings = settings.copy(nodeSettings = settings.nodeSettings.copy(minimalFeeAmount = 0))
- val pool2 = ErgoMemPool.empty(minSettings)
- unconfirmedTxs.foreach { tx =>
- val (_, outcome) = pool2.process(tx, us)
- outcome.isInstanceOf[ProcessingOutcome.Accepted] shouldBe true
- }
- }
-
- it should "invalidate or reject invalid transaction" in {
- val us = createUtxoState(settings)._1
- val pool = ErgoMemPool.empty(settings)
- forAll(invalidBlockTransactionsGen) { blockTransactions =>
- blockTransactions.txs.forall{tx =>
- val valRes = pool.process(UnconfirmedTransaction(tx, None), us)._2
- valRes.isInstanceOf[ProcessingOutcome.Invalidated] ||
- valRes.isInstanceOf[ProcessingOutcome.Declined]} shouldBe true
- }
- }
-
- it should "accept only unique transactions" in {
- val pool = ErgoMemPool.empty(settings)
- val tx = UnconfirmedTransaction(invalidErgoTransactionGen.sample.get, None)
- pool.put(Seq(tx, tx, tx)).size shouldBe 1
- }
-
- it should "drop less prioritized transaction in case of pool overflow" in {
- val limitedPoolSettings = settings.copy(nodeSettings = settings.nodeSettings.copy(mempoolCapacity = 4))
- var pool = ErgoMemPool.empty(limitedPoolSettings)
- val masterTx = invalidErgoTransactionGen.sample.get
- val proposition = settings.chainSettings.monetary.feeProposition
- val txsWithAscendingPriority = (0 to 4).foldLeft(Seq.empty[ErgoTransaction]) { case (acc, idx) =>
- val c = masterTx.outputCandidates.head
- acc :+ masterTx.copy(outputCandidates = IndexedSeq(
- new ErgoBoxCandidate(idx * 10000 + 1, proposition, c.creationHeight, c.additionalTokens, c.additionalRegisters)))
- }
- val lessPrioritizedTxs = txsWithAscendingPriority.init.map(tx => UnconfirmedTransaction(tx, None))
- val mostPrioritizedTx = UnconfirmedTransaction(txsWithAscendingPriority.last, None)
- pool = pool.put(lessPrioritizedTxs)
-
- pool.size shouldBe 4
- pool.getAll should contain only (lessPrioritizedTxs: _*)
- pool = pool.put(Seq(mostPrioritizedTx))
- pool.size shouldBe 4
- pool.getAll should contain only (mostPrioritizedTx +: lessPrioritizedTxs.tail: _*)
- }
-
- it should "Accept output of pooled transactions" in {
- val (us, bh) = createUtxoState(settings)
- val genesis = validFullBlock(None, us, bh)
- val wus = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get
- val txs = validTransactionsFromUtxoState(wus).map(tx => UnconfirmedTransaction(tx, None))
- var pool = ErgoMemPool.empty(settings)
- txs.foreach { tx =>
- pool = pool.put(tx)
- }
- txs.foreach { tx =>
- val spendingBox = tx.transaction.outputs.head
- val unconfirmedTransaction = UnconfirmedTransaction(tx.transaction.copy(
- inputs = IndexedSeq(new Input(spendingBox.id, emptyProverResult)),
- outputCandidates = IndexedSeq(spendingBox)), None)
- val (newPool, outcome) = pool.process(unconfirmedTransaction, us)
- outcome.isInstanceOf[ProcessingOutcome.Accepted] shouldBe true
- pool = newPool
- }
- }
-
- it should "consider families for replacement policy" in {
- val (us, bh) = createUtxoState(settings)
- val genesis = validFullBlock(None, us, bh)
- val wus = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get
- var txs = validTransactionsFromUtxoState(wus).map(tx => UnconfirmedTransaction(tx, None))
- val family_depth = 10
- val limitedPoolSettings = settings.copy(nodeSettings = settings.nodeSettings.copy(mempoolCapacity = (family_depth + 1) * txs.size))
- var pool = ErgoMemPool.empty(limitedPoolSettings)
- txs.foreach { tx =>
- pool = pool.put(tx)
- }
- for (_ <- 1 to family_depth) {
- txs = txs.map(tx => {
- val spendingBox = tx.transaction.outputs.head
- val newTx = UnconfirmedTransaction(tx.transaction.copy(inputs = IndexedSeq(new Input(spendingBox.id, emptyProverResult)),
- outputCandidates = IndexedSeq(spendingBox)), None)
- val (newPool, outcome) = pool.process(newTx, us)
- outcome.isInstanceOf[ProcessingOutcome.Accepted] shouldBe true
- pool = newPool
- newTx
- })
- }
- pool.size shouldBe (family_depth + 1) * txs.size
- txs.foreach { utx =>
- val tx = utx.transaction
- val sb = tx.outputs.head
- val txToDecline = tx.copy(inputs = IndexedSeq(new Input(sb.id, emptyProverResult)),
- outputCandidates = IndexedSeq(new ErgoBoxCandidate(sb.value, sb.ergoTree, sb.creationHeight, sb.additionalTokens, sb.additionalRegisters)))
- val res = pool.process(UnconfirmedTransaction(txToDecline, None), us)._2
- res.isInstanceOf[ProcessingOutcome.Declined] shouldBe true
- res.asInstanceOf[ProcessingOutcome.Declined].e.getMessage.contains("pays less") shouldBe true
- pool.size shouldBe (family_depth + 1) * txs.size
- }
- }
-
- it should "correctly remove transaction from pool and rebuild families" in {
- val (us, bh) = createUtxoState(settings)
- val genesis = validFullBlock(None, us, bh)
- val wus = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get
- var txs = validTransactionsFromUtxoState(wus).map(tx => UnconfirmedTransaction(tx, None))
- var allTxs = txs
- val family_depth = 10
- val limitedPoolSettings = settings.copy(nodeSettings = settings.nodeSettings.copy(mempoolCapacity = (family_depth + 1) * txs.size))
- var pool = ErgoMemPool.empty(limitedPoolSettings)
- txs.foreach { tx =>
- pool = pool.put(tx)
- }
- for (_ <- 1 to family_depth) {
- txs = txs.map(tx => {
- val spendingBox = tx.transaction.outputs.head
- val newTx = UnconfirmedTransaction(tx.transaction.copy(inputs = IndexedSeq(new Input(spendingBox.id, emptyProverResult)),
- outputCandidates = IndexedSeq(spendingBox)), None)
- val (newPool, outcome) = pool.process(newTx, us)
- outcome.isInstanceOf[ProcessingOutcome.Accepted] shouldBe true
- pool = newPool
- allTxs = allTxs :+ newTx
- newTx
- })
- }
- pool.size shouldBe (family_depth + 1) * txs.size
- allTxs.foreach { tx =>
- pool = pool.remove(tx.transaction)
- }
- pool.size shouldBe 0
- }
-
- it should "return results take / getAll / getAllPrioritized sorted by priority" in {
- val feeProp = settings.chainSettings.monetary.feeProposition
-
- val (us, bh) = createUtxoState(settings)
- val genesis = validFullBlock(None, us, bh)
- val wus = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get
- var txs = validTransactionsFromUtxoState(wus).map(tx => UnconfirmedTransaction(tx, None))
- val family_depth = 10
- val limitedPoolSettings = settings.copy(nodeSettings = settings.nodeSettings.copy(mempoolCapacity = (family_depth + 1) * txs.size))
- var pool = ErgoMemPool.empty(limitedPoolSettings)
- txs.foreach { tx =>
- pool = pool.put(tx)
- }
- for (_ <- 1 to family_depth) {
- txs = txs.map(tx => {
- val spendingBox = tx.transaction.outputs.head
-
- val sc = spendingBox.toCandidate
- val out0 = new ErgoBoxCandidate(sc.value - 55000, sc.ergoTree, sc.creationHeight)
- val out1 = new ErgoBoxCandidate(55000, feeProp, sc.creationHeight)
-
- val newTx = UnconfirmedTransaction(tx.transaction.copy(inputs = IndexedSeq(new Input(spendingBox.id, emptyProverResult)),
- outputCandidates = IndexedSeq(out0, out1)), None)
- val (newPool, outcome) = pool.process(newTx, us)
- outcome.isInstanceOf[ProcessingOutcome.Accepted] shouldBe true
- pool = newPool
- newTx
- })
- }
-
- val weights = pool.weightedTransactionIds(11)
- val ids = weights.map(_.id)
-
- pool.take(11).toSeq.map(_.transaction.id) shouldBe ids
- pool.getAll.map(_.transaction.id) shouldBe ids
- pool.getAllPrioritized.map(_.transaction.id) shouldBe ids
-
- val conformingTxs = pool.take(3).toSeq
- val stateWithTxs = wus.withUnconfirmedTransactions(conformingTxs)
-
- conformingTxs.map(_.transaction).flatMap(_.inputs).map(_.boxId).forall(bIb => stateWithTxs.boxById(bIb)
- .isDefined) shouldBe true
- }
-
- it should "add removed transaction to mempool statistics" in {
- val (us, bh) = createUtxoState(settings)
- val genesis = validFullBlock(None, us, bh)
- val wus = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get
- var txs = validTransactionsFromUtxoState(wus).map(tx => UnconfirmedTransaction(tx, None))
- var allTxs = txs
- val family_depth = 10
- val limitedPoolSettings = settings.copy(nodeSettings = settings.nodeSettings.copy(mempoolCapacity = (family_depth + 1) * txs.size))
- var pool = ErgoMemPool.empty(limitedPoolSettings)
- txs.foreach { tx =>
- pool = pool.put(tx)
- }
- for (_ <- 1 to family_depth) {
- txs = txs.map(tx => {
- val spendingBox = tx.transaction.outputs.head
- val newTx = UnconfirmedTransaction(tx.transaction.copy(inputs = IndexedSeq(new Input(spendingBox.id, emptyProverResult)),
- outputCandidates = IndexedSeq(spendingBox)), None)
- val (newPool, outcome) = pool.process(newTx, us)
- outcome.isInstanceOf[ProcessingOutcome.Accepted] shouldBe true
- pool = newPool
- allTxs = allTxs :+ newTx
- newTx
- })
- }
- pool.size shouldBe (family_depth + 1) * txs.size
- pool.stats.histogram shouldBe MemPoolStatistics(System.currentTimeMillis(),0,System.currentTimeMillis()).histogram
- pool.stats.takenTxns shouldBe MemPoolStatistics(System.currentTimeMillis(),0,System.currentTimeMillis()).takenTxns
- pool.stats.snapTakenTxns shouldBe MemPoolStatistics(System.currentTimeMillis(),0,System.currentTimeMillis()).snapTakenTxns
-
- allTxs.foreach { tx =>
- pool = pool.remove(tx.transaction)
- }
- pool.size shouldBe 0
- pool.stats.takenTxns shouldBe (family_depth + 1) * txs.size
- }
-
- it should "put not adding transaction twice" in {
- val pool = ErgoMemPool.empty(settings).pool
- val tx = invalidErgoTransactionGen.sample.get
- val now = System.currentTimeMillis()
-
- val utx1 = new UnconfirmedTransaction(tx, None, now, now, None, None)
- val utx2 = new UnconfirmedTransaction(tx, None, now, now, None, None)
- val utx3 = new UnconfirmedTransaction(tx, None, now + 1, now + 1, None, None)
- val updPool = pool.put(utx1, 100).remove(utx1).put(utx2, 500).put(utx3, 5000)
- updPool.size shouldBe 1
- updPool.get(utx3.id).get.lastCheckedTime shouldBe (now + 1)
- }
-
-}
-
-
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/mempool/ExpiringApproximateCacheSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/mempool/ExpiringApproximateCacheSpec.scala
deleted file mode 100644
index fac02822a2..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/mempool/ExpiringApproximateCacheSpec.scala
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.ergoplatform.nodeView.mempool
-
-import org.scalactic.TripleEqualsSupport
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-import java.util.UUID
-import scala.concurrent.duration._
-
-class ExpiringApproximateCacheSpec
- extends AnyFlatSpec
- with Matchers
- with TripleEqualsSupport {
-
- it should "behave as fixed sized FIFO collection of bloom filters" in {
- val cache = ExpiringApproximateCache.empty(
- frontCacheSize = 100,
- frontCacheExpiration = 1.hour
- )
- cache.bloomFilterQueueSize shouldBe 4
- val fullCache =
- (1 to 500).map(_.toString).foldLeft(cache) { case (acc, n) => acc.put(n) }
-
- (1 to 400).foreach { n =>
- assert(fullCache.mightContain(n.toString), s"$n should be in bloom filter")
- }
-
- println("size: " + fullCache.bloomFilterQueue.size)
-
- fullCache.bloomFilterQueue.size shouldBe 4
- assert(
- fullCache.approximateElementCount > 430,
- "At least 430 elements must be present"
- )
-
- // add some more elements over limit
- val newCache =
- (501 to 1000).map(_.toString).foldLeft(fullCache) { case (acc, n) => acc.put(n) }
- newCache.bloomFilterQueue.size shouldBe 4
- assert(newCache.approximateElementCount < 570, "Max 600 elements must be present")
-
- (601 to 800).foreach { n =>
- assert(newCache.mightContain(n.toString), s"$n should be in bloom filter")
- }
- }
-
- it should "have a fixed size expiring cache before bloom filters" in {
- val cache = ExpiringApproximateCache.empty(
- frontCacheSize = 100,
- frontCacheExpiration = 50.millis
- )
- // let's add 100 elems directly to front cache
- val fullCache =
- (1 to 100).map(_.toString).foldLeft(cache) { case (acc, n) => acc.put(n) }
-
- (1 to 100).foreach { n =>
- assert(fullCache.mightContain(n.toString), s"$n should be in front cache")
- }
- fullCache.frontCache.size shouldBe 100
- // now let's add another element which won't with to front cache so it goes to bloom filters
- val updatedCache = fullCache.put("101")
- updatedCache.frontCache.size shouldBe 1
- updatedCache.frontCache.contains("101") shouldBe true
- assert(updatedCache.mightContain("100"), s"100 should be in bloom filter")
-
- val expiringCache = (102 to 200).map(_.toString).foldLeft(updatedCache) { case (acc, n) =>
- acc.put(n)
- }
-
- expiringCache.frontCache.size shouldBe 100
-
- // test that all elements in front cache expire
- Thread.sleep(200)
- val expriredCache = expiringCache.put("201")
- expriredCache.frontCache.size shouldBe 1
- // expired elements are not in the filters as well
- val fp = (102 to 200).map(_.toString).count(expriredCache.mightContain)
- (fp < 5) shouldBe true // no more than 5% false positives, with some extra buffer given
- }
-
- it should "overflow properly" in {
- val cache = ExpiringApproximateCache.empty(
- frontCacheSize = 10000,
- frontCacheExpiration = 1.hour
- )
- // let's add 2M of realistic elems to cache
- val elemCount = 2000000
- val uuids = (1 to elemCount).map(_ => UUID.randomUUID().toString)
- val fullCache = uuids.foldLeft(cache) { case (acc, n) => acc.put(n) }
-
- uuids.forall(fullCache.mightContain) shouldBe false
- uuids.takeRight(10000).forall(fullCache.mightContain) shouldBe true // last elements there
- // first ids forgotten, except of false positives (with some buffer we add)
- val fp = uuids.take(10000).count(id => fullCache.mightContain(id))
- (fp < 100) shouldBe true // we allow up to 1% false positives
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/mempool/ScriptsSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/mempool/ScriptsSpec.scala
deleted file mode 100644
index 7f2f6b7cca..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/mempool/ScriptsSpec.scala
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.ergoplatform.nodeView.mempool
-
-import org.ergoplatform.ErgoAddressEncoder.TestnetNetworkPrefix
-import org.ergoplatform.ErgoTreePredef.boxCreationHeight
-import org.ergoplatform.nodeView.state.{BoxHolder, ErgoState, UtxoState}
-import org.ergoplatform.settings.Algos
-import org.ergoplatform.utils.{ErgoPropertyTest, RandomWrapper}
-import org.ergoplatform.{ErgoBox, ErgoTreePredef, Height, Self}
-import scorex.crypto.authds.avltree.batch.Remove
-import sigmastate.Values._
-import sigmastate._
-import sigmastate.crypto.CryptoConstants.dlogGroup
-import sigmastate.crypto.DLogProtocol.ProveDlog
-import sigmastate.eval.{CompiletimeIRContext, IRContext}
-import sigmastate.lang.Terms._
-import sigmastate.lang.{CompilerSettings, SigmaCompiler, TransformingSigmaBuilder}
-
-import scala.util.Try
-
-class ScriptsSpec extends ErgoPropertyTest {
-
- val compiler = SigmaCompiler(
- CompilerSettings(TestnetNetworkPrefix, TransformingSigmaBuilder, lowerMethodCalls = true)
- )
- val delta = emission.settings.minerRewardDelay
- val fixedBox: ErgoBox = ergoBoxGen(fromString("1 == 1"), heightGen = 0).sample.get
- implicit lazy val context: IRContext = new CompiletimeIRContext
-
- property("simple operations without cryptography") {
- // true/false
- applyBlockSpendingScript(Values.TrueLeaf.toSigmaProp) shouldBe 'success
- applyBlockSpendingScript(Values.FalseLeaf.toSigmaProp) shouldBe 'failure
- // eq
- applyBlockSpendingScript(EQ(IntConstant(1), IntConstant(1)).toSigmaProp) shouldBe 'success
- applyBlockSpendingScript(EQ(IntConstant(1), IntConstant(2)).toSigmaProp) shouldBe 'failure
- // math
- applyBlockSpendingScript(EQ(Plus(1, 2), Minus(6, 3)).toSigmaProp) shouldBe 'success
- applyBlockSpendingScript(EQ(Multiply(1, 2), Divide(7, 3)).toSigmaProp) shouldBe 'success
- // context
- applyBlockSpendingScript(EQ(IntConstant(1), Height).toSigmaProp) shouldBe 'success
- applyBlockSpendingScript(fromString("CONTEXT.preHeader.height == 1")) shouldBe 'success
- applyBlockSpendingScript(fromString("CONTEXT.headers.size == 0")) shouldBe 'success
- applyBlockSpendingScript(fromString(s"CONTEXT.dataInputs.exists{ (box: Box) => box.value == ${fixedBox.value}L}")) shouldBe 'success
- // todo other common operations: tokens, data from registers, context extension, etc.
- }
-
- property("simple crypto") {
- applyBlockSpendingScript(defaultMinerPk) shouldBe 'success
- applyBlockSpendingScript(SigmaAnd(defaultProver.hdKeys.map(s => SigmaPropConstant(s.publicImage)))) shouldBe 'success
- applyBlockSpendingScript(SigmaAnd(defaultMinerPk, ProveDlog(dlogGroup.generator))) shouldBe 'failure
- applyBlockSpendingScript(SigmaOr(defaultMinerPk, ProveDlog(dlogGroup.generator))) shouldBe 'success
- }
-
- property("predef scripts") {
- delta shouldBe -1000
-
- applyBlockSpendingScript(GE(Height, Plus(boxCreationHeight(Self), IntConstant(delta))).toSigmaProp) shouldBe 'success
- applyBlockSpendingScript(ErgoTreePredef.rewardOutputScript(delta, defaultMinerPk)) shouldBe 'success
-// applyBlockSpendingScript(ErgoScriptPredef.feeProposition(delta)) shouldBe 'success
- }
-
-
- private def fromString(str: String): ErgoTree = {
- compiler.compile(Map(), str).buildTree.asBoolValue.toSigmaProp
- }
-
- private def applyBlockSpendingScript(script: ErgoTree): Try[UtxoState] = {
- val scriptBox = ergoBoxGen(script, heightGen = 0).sample.get
- val bh = BoxHolder(Seq(fixedBox, scriptBox))
- val us = UtxoState.fromBoxHolder(bh, None, createTempDir, settings, parameters)
- bh.boxes.map(b => us.boxById(b._2.id) shouldBe Some(b._2))
- val tx = validTransactionsFromBoxHolder(bh, new RandomWrapper(Some(1)), 201)._1
- tx.size shouldBe 1
- tx.head.inputs.size shouldBe 2
- ErgoState.boxChanges(tx).get._1.foreach { case Remove(boxId) =>
- assert(us.boxById(boxId).isDefined, s"Box ${Algos.encode(boxId)} missed")
- }
- val block = validFullBlock(None, us, tx, Some(1234L))
- us.applyModifier(block, None)(_ => ())
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/DigestStateSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/DigestStateSpecification.scala
deleted file mode 100644
index 7cf71def1a..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/DigestStateSpecification.scala
+++ /dev/null
@@ -1,134 +0,0 @@
-package org.ergoplatform.nodeView.state
-
-import org.ergoplatform.{DataInput, Input}
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.ADProofs
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.utils.{ErgoPropertyTest, RandomWrapper}
-import scorex.core._
-import scorex.crypto.authds.ADDigest
-import sigmastate.interpreter.ProverResult
-
-class DigestStateSpecification extends ErgoPropertyTest {
-
- private val emptyVersion: VersionTag = bytesToVersion(Array.fill(32)(0: Byte))
- private val emptyAdDigest: ADDigest = ADDigest @@ Array.fill(32)(0: Byte)
-
- property("reopen") {
- forAll(boxesHolderGen) { bh =>
- val us = createUtxoState(bh, parameters)
- bh.sortedBoxes.foreach(box => us.boxById(box.id) should not be None)
-
- val fb = validFullBlock(parentOpt = None, us, bh)
- val dir2 = createTempDir
- val ds = DigestState.create(Some(us.version), Some(us.rootDigest), dir2, settings)
- ds.applyModifier(fb, None)(_ => ()) shouldBe 'success
- ds.close()
-
- val state = DigestState.create(None, None, dir2, settings)
- state.version shouldEqual fb.header.id
- state.rootDigest shouldEqual fb.header.stateRoot
- }
- }
-
- property("validate() - valid block") {
- var (us, bh) = createUtxoState(settings)
- var ds = createDigestState(us.version, us.rootDigest)
- var parentOpt: Option[ErgoFullBlock] = None
-
- forAll { seed: Int =>
- val blBh = validFullBlockWithBoxHolder(parentOpt, us, bh, new RandomWrapper(Some(seed)))
- val block = blBh._1
- bh = blBh._2
- ds = ds.applyModifier(block, None)(_ => ()).get
- us = us.applyModifier(block, None)(_ => ()).get
- parentOpt = Some(block)
- }
- }
-
- property("validate() - invalid block") {
- forAll(invalidErgoFullBlockGen) { b =>
- val state = createDigestState(emptyVersion, emptyAdDigest)
- state.validate(b).isFailure shouldBe true
- }
- }
-
- property("applyModifier() - valid block") {
- forAll(boxesHolderGen) { bh =>
- val us = createUtxoState(bh, parameters)
- bh.sortedBoxes.foreach(box => us.boxById(box.id) should not be None)
-
- val block = validFullBlock(parentOpt = None, us, bh)
- block.blockTransactions.transactions.exists(_.dataInputs.nonEmpty) shouldBe true
-
- val ds = createDigestState(us.version, us.rootDigest)
- ds.applyModifier(block, None)(_ => ()) shouldBe 'success
- }
- }
-
- property("applyModifier() - invalid block") {
- forAll(invalidErgoFullBlockGen) { b =>
- val state = createDigestState(emptyVersion, emptyAdDigest)
- state.applyModifier(b, None)(_ => ()).isFailure shouldBe true
- }
- }
-
- property("rollback & rollback versions") {
- forAll(boxesHolderGen) { bh =>
- val us = createUtxoState(bh, parameters)
- bh.sortedBoxes.foreach(box => us.boxById(box.id) should not be None)
-
- val block = validFullBlock(parentOpt = None, us, bh)
-
- val ds = createDigestState(us.version, us.rootDigest)
-
- ds.rollbackVersions.size shouldEqual 1
-
- val ds2 = ds.applyModifier(block, None)(_ => ()).get
-
- ds2.rollbackVersions.size shouldEqual 2
-
- ds2.stateContext.lastHeaders.size shouldEqual 1
-
- java.util.Arrays.equals(ds2.rootDigest, ds.rootDigest) shouldBe false
-
- val ds3 = ds2.rollbackTo(ds.version).get
- ds3.rootDigest shouldBe ds.rootDigest
-
- ds3.stateContext.lastHeaders.size shouldEqual 0
-
- ds3.applyModifier(block, None)(_ => ()).get.rootDigest shouldBe ds2.rootDigest
- }
- }
-
- property("validateTransactions() - dataInputs") {
- forAll(boxesHolderGen) { bh =>
- val us = createUtxoState(bh, parameters)
- val ds = createDigestState(us.version, us.rootDigest)
-
- // generate 2 independent transactions spending state boxes only
- val headTx = validTransactionsFromBoxes(1, bh.boxes.take(10).values.toSeq, new RandomWrapper())._1.head
- val nextTx = validTransactionsFromBoxes(1, bh.boxes.takeRight(10).values.toSeq, new RandomWrapper())._1.head
- headTx.inputs.intersect(nextTx.inputs) shouldBe empty
-
- // trying to apply transactions with data inputs same as inputs of the next tx
- val dataInputs = nextTx.inputs.filter(i => us.boxById(i.boxId).isDefined).map(i => DataInput(i.boxId))
- val inputs = headTx.outputs.map(b => Input(b.id, ProverResult.empty))
- val txWithDataInputs = ErgoTransaction(inputs, dataInputs, headTx.outputCandidates)
-
- val txs1 = IndexedSeq(headTx, nextTx, txWithDataInputs)
- val (proofBytes1, digest1) = us.proofsForTransactions(txs1).get
- val proof1 = ADProofs(defaultHeaderGen.sample.get.id, proofBytes1)
- ds.validateTransactions(txs1, digest1, proof1, emptyStateContext) shouldBe 'success
-
- val txs2 = IndexedSeq(headTx, txWithDataInputs, nextTx)
- val (proofBytes2, digest2) = us.proofsForTransactions(txs2).get
- val proof2 = ADProofs(defaultHeaderGen.sample.get.id, proofBytes2)
- ds.validateTransactions(txs2, digest2, proof2, emptyStateContext) shouldBe 'success
-
- val txs3 = IndexedSeq(txWithDataInputs, headTx, nextTx)
- ds.validateTransactions(txs3, digest2, proof2, emptyStateContext) shouldBe 'failure
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateContextSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateContextSpec.scala
deleted file mode 100644
index e5db6a6cbf..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateContextSpec.scala
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.ergoplatform.nodeView.state
-
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.extension.Extension
-import org.ergoplatform.modifiers.history.popow.NipopowAlgos
-import org.ergoplatform.settings.Parameters._
-import org.ergoplatform.utils.HistoryTestHelpers
-
-class ErgoStateContextSpec extends HistoryTestHelpers {
-
- property("Header votes") {
- val fb = genChain(1).head
- val header = fb.header
-
- def fbWithVotes(votes: Array[Byte], h: Int = 1): ErgoFullBlock = {
- val newHeader = header.copy(votes = votes, version = 0: Byte, height = h)
- fb.copy(header = newHeader)
- }
-
- //double vote
- val wrongVotes1 = Array(StorageFeeFactorIncrease, StorageFeeFactorIncrease, NoParameter)
- emptyStateContext.appendFullBlock(fbWithVotes(wrongVotes1)) shouldBe 'failure
-
- //contradictory votes
- val wrongVotes2 = Array(StorageFeeFactorIncrease, StorageFeeFactorDecrease, NoParameter)
- emptyStateContext.appendFullBlock(fbWithVotes(wrongVotes2)) shouldBe 'failure
-
- //too many votes - only two ordinary changes allowed per epoch
- val wrongVotes3 = Array(StorageFeeFactorIncrease, MaxBlockCostIncrease, MaxBlockSizeDecrease)
- emptyStateContext.appendFullBlock(fbWithVotes(wrongVotes3)) shouldBe 'failure
-
- //a vote proposed on non-existing parameter - breaks rule #215
- //voting epoch length is 1024 blocks long
- val wrongVotes4 = Array((-50).toByte, NoParameter, MaxBlockSizeDecrease)
- emptyStateContext.appendFullBlock(fbWithVotes(wrongVotes4, 1024)) shouldBe 'failure
-
- //correct votes
- val correctVotes = Array(StorageFeeFactorIncrease, MaxBlockSizeDecrease, NoParameter)
- emptyStateContext.appendFullBlock(fbWithVotes(correctVotes)) shouldBe 'success
-
-
- //a vote for non-existing parameter in the middle of epoch - does not break rule #215
- //voting epoch length is 1024 blocks long
- val correctVotes2 = Array((-50).toByte, NoParameter, MaxBlockSizeDecrease)
- emptyStateContext.appendFullBlock(fbWithVotes(correctVotes2, 2)) shouldBe 'success
-
- }
-
- property("Extension validation") {
- val chain = genChain(2)
- val sc = emptyStateContext.appendFullBlock(chain.head).get
- val fb = chain.last
- val extension = fb.extension
- val oldFields = extension.fields
-
- def fbWithFields(newFields: Seq[(Array[Byte], Array[Byte])]): ErgoFullBlock = {
- val newExtension = extension.copy(fields = newFields)
- fb.copy(extension = newExtension)
- }
-
- // checks, specific for extension
- // validation of field keys size
- val imvKey = extensionKvGen(Extension.FieldKeySize - 1, Extension.FieldValueMaxSize).sample.get
- sc.appendFullBlock(fbWithFields(imvKey +: oldFields)) shouldBe 'failure
-
- // validation of field value sizes
- val imvValue = extensionKvGen(Extension.FieldKeySize, Extension.FieldValueMaxSize + 1).sample.get
- sc.appendFullBlock(fbWithFields(imvValue +: oldFields)) shouldBe 'failure
-
- // validation of incorrect interlinks
- val invalidInterlinks = nipopowAlgos.interlinksToExtension(
- NipopowAlgos.unpackInterlinks(fb.extension.fields).get ++ Seq(fb.header.id)
- ).fields
- sc.appendFullBlock(fbWithFields(invalidInterlinks ++ oldFields)) shouldBe 'failure
-
- // validation of key duplicates in fields
- val validMKV = extensionKvGen(Extension.FieldKeySize, Extension.FieldValueMaxSize).sample.get
- sc.appendFullBlock(fbWithFields(Seq(validMKV, validMKV) ++ oldFields)) shouldBe 'failure
-
- // valid application of correct extension
- sc.appendFullBlock(fbWithFields(validMKV +: oldFields)) shouldBe 'success
-
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala
deleted file mode 100644
index 059b4e0d1c..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala
+++ /dev/null
@@ -1,190 +0,0 @@
-package org.ergoplatform.nodeView.state
-
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.BlockTransactions
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.settings.{Args, ErgoSettings}
-import org.ergoplatform.utils.{ErgoPropertyTest, RandomWrapper}
-import org.ergoplatform.wallet.boxes.ErgoBoxSerializer
-import org.scalacheck.Gen
-import scorex.core.bytesToVersion
-import scorex.core.validation.ValidationResult.Valid
-import scorex.db.ByteArrayWrapper
-
-import scala.collection.mutable
-import scala.util.{Failure, Try}
-
-class ErgoStateSpecification extends ErgoPropertyTest {
-
- property("applyModifier() - double spending") {
- forAll(boxesHolderGen, Gen.choose(1: Byte, 2: Byte)) { case (bh, version) =>
- val us = createUtxoState(bh, parameters)
- val ds = createDigestState(bytesToVersion(Array.fill(32)(100: Byte)), us.rootDigest)
-
- val validBlock = validFullBlock(None, us, bh)
- val dsTxs = validBlock.transactions ++ validBlock.transactions
- ErgoState.stateChanges(dsTxs) shouldBe 'failure
-
- val dsRoot = BlockTransactions.transactionsRoot(dsTxs, version)
- val dsHeader = validBlock.header.copy(transactionsRoot = dsRoot)
- val bt = BlockTransactions(dsHeader.id, version, dsTxs)
- val doubleSpendBlock = ErgoFullBlock(dsHeader, bt, validBlock.extension, validBlock.adProofs)
-
- us.applyModifier(doubleSpendBlock, None)(_ => ()) shouldBe 'failure
- us.applyModifier(validBlock, None)(_ => ()) shouldBe 'success
-
- ds.applyModifier(doubleSpendBlock, None)(_ => ()) shouldBe 'failure
- ds.applyModifier(validBlock, None)(_ => ()) shouldBe 'success
- }
- }
-
- property("stateContext should be the same for Utxo and Digest states") {
- def requireEqualStateContexts(s1: ErgoStateContext, s2: ErgoStateContext, lastHeaders: Seq[Header]): Unit = {
- s1.currentHeight shouldBe lastHeaders.headOption.map(_.height).getOrElse(0)
- s1.currentHeight shouldBe s2.currentHeight
- s1.previousStateDigest shouldEqual s2.previousStateDigest
- s1.lastHeaders shouldEqual s2.lastHeaders
- s1.lastHeaders shouldEqual lastHeaders
- s1.currentParameters shouldEqual s2.currentParameters
- s1.votingData shouldEqual s2.votingData
- s1.genesisStateDigest shouldBe s2.genesisStateDigest
- }
-
- var (us, bh) = createUtxoState(settings)
- var ds = createDigestState(us.version, us.rootDigest)
- var lastBlocks: Seq[ErgoFullBlock] = Seq()
- forAll { seed: Int =>
- val blBh = validFullBlockWithBoxHolder(lastBlocks.headOption, us, bh, new RandomWrapper(Some(seed)))
- val block = blBh._1
- bh = blBh._2
- ds = ds.applyModifier(block, None)(_ => ()).get
- us = us.applyModifier(block, None)(_ => ()).get
- lastBlocks = block +: lastBlocks
- requireEqualStateContexts(us.stateContext, ds.stateContext, lastBlocks.map(_.header))
- }
- }
-
- property("generateGenesisUtxoState & generateGenesisDigestState are compliant") {
- val settings = ErgoSettings.read(Args.empty)
- val dir = createTempDir
- val rootHash = createUtxoState(settings)._1.rootDigest
- val expectedRootHash = ErgoState.generateGenesisDigestState(dir, settings).rootDigest
- rootHash shouldBe expectedRootHash
- }
-
- property("ErgoState.boxChanges() should generate operations in the same order") {
- var (us, bh) = createUtxoState(settings)
- var parentOpt: Option[ErgoFullBlock] = None
-
- forAll { seed: Int =>
- val blBh = validFullBlockWithBoxHolder(parentOpt, us, bh, new RandomWrapper(Some(seed)))
- val block = blBh._1
- parentOpt = Some(block)
- bh = blBh._2
- us = us.applyModifier(block, None)(_ => ()).get
-
- val changes1 = ErgoState.boxChanges(block.transactions).get
- val changes2 = ErgoState.boxChanges(block.transactions).get
- changes1._1 shouldBe changes2._1
- changes1._2 shouldBe changes2._2
- }
- }
-
- property("ErgoState.boxChanges() double spend attempt") {
- val (_, bh) = createUtxoState(settings)
- val emissionBox = genesisBoxes.head
-
- forAll { seed: Int =>
- val txs = validTransactionsFromBoxHolder(bh, new RandomWrapper(Some(seed)))._1
- whenever(txs.lengthCompare(2) > 0) {
- // valid transaction should spend the only existing genesis box
- ErgoState.boxChanges(txs).get._1.length shouldBe 1
- ErgoState.boxChanges(txs).get._1.head.key shouldBe emissionBox.id
-
- // second transaction input should be an input created by the first transaction
- val inputToDoubleSpend = txs(1).inputs.head
- txs.head.outputs.find(b => java.util.Arrays.equals(b.id, inputToDoubleSpend.boxId)) should not be None
- val doubleSpendTx = txs.last.copy(inputs = inputToDoubleSpend +: txs.last.inputs.tail)
- val invalidTxs = txs.dropRight(1) :+ doubleSpendTx
- invalidTxs.length shouldBe txs.length
- invalidTxs.count(_.inputs.contains(inputToDoubleSpend)) shouldBe 2
-
- ErgoState.boxChanges(invalidTxs).get._1.length shouldBe 2
- }
- }
- }
-
- property("ErgoState.stateChanges()") {
- val bh = createUtxoState(settings)._2
- val emissionBox = genesisBoxes.head
-
- forAll { seed: Int =>
- val txs = validTransactionsFromBoxHolder(bh, new RandomWrapper(Some(seed)))._1
- whenever(txs.lengthCompare(1) > 0) {
- val changes = ErgoState.stateChanges(txs).get
- val removals = changes.toRemove
- // should remove the only genesis box from the state
- removals.length shouldBe 1
- removals.head.key shouldEqual emissionBox.id
- // number of inputs should be more than 1 - we create boxes and spend them in the same block
- txs.flatMap(_.inputs).length should be > 1
-
- val insertions = changes.toAppend
- // sum of coins in outputs should equal to genesis value
- insertions.map(_.value).map(ErgoBoxSerializer.parseBytes).map(_.value).sum shouldBe emissionBox.value
-
- // if output was spend and then created - it is in both toInsert and toRemove
- val changesRev = ErgoState.stateChanges(txs.reverse).get
- val removalsRev = changesRev.toRemove
- val insertionsRev = changesRev.toAppend
- removalsRev.length should be > removals.length
- insertionsRev.length should be > insertions.length
- }
- }
- }
-
- property("ErgoState.execTransactions()") {
- val bh = BoxHolder(genesisBoxes)
- def generateTxs =
- (1 to 15).foldLeft(mutable.WrappedArray.newBuilder[ErgoTransaction]) { case (txAcc, _) =>
- val (transactions, _) = validTransactionsFromBoxes(10000, bh.boxes.values.toSeq, new RandomWrapper())
- val allBoxIds = bh.boxes.keys.toSet
- val txsFromBoxesOnly = transactions.filter { tx =>
- tx.inputs.map(i => ByteArrayWrapper(i.boxId)).forall(allBoxIds.contains) &&
- tx.dataInputs.map(i => ByteArrayWrapper(i.boxId)).forall(allBoxIds.contains)
- }
- txAcc ++= txsFromBoxesOnly
- }.result()
-
- val txs = generateTxs
- val boxes = bh.boxes
- val stateContext = emptyStateContext
- val expectedCost = 185160
-
- // successful validation
- ErgoState.execTransactions(txs, stateContext)(id => Try(boxes(ByteArrayWrapper(id)))) shouldBe Valid(expectedCost)
-
- // cost limit exception expected when crossing MaxBlockCost
- val tooManyTxs = (1 to 10).flatMap(_ => generateTxs)
- assert(
- ErgoState.execTransactions(tooManyTxs, stateContext)(id => Try(boxes(ByteArrayWrapper(id)))).errors.head.message.contains(
- "Accumulated cost of block transactions should not exceed "
- )
- )
-
- // missing box in state
- ErgoState.execTransactions(txs, stateContext)(_ => Failure(new RuntimeException)).errors.head.message shouldBe
- "Every input of the transaction should be in UTXO. null"
-
- // tx validation should kick in and detect block height violation
- val invalidTx = invalidErgoTransactionGen.sample.get
- assert(
- ErgoState.execTransactions(txs :+ invalidTx, stateContext)(id => Try(boxes.getOrElse(ByteArrayWrapper(id), invalidTx.outputs.head)))
- .errors.head.message.startsWith("Transaction outputs should have creationHeight not exceeding block height.")
- )
-
- // no transactions are valid
- assert(ErgoState.execTransactions(Seq.empty, stateContext)(id => Try(boxes(ByteArrayWrapper(id)))).isValid)
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/SnapshotsDbSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/SnapshotsDbSpecification.scala
deleted file mode 100644
index f273749ca7..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/SnapshotsDbSpecification.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.ergoplatform.nodeView.state
-
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.scalacheck.Gen
-import scorex.crypto.hash.Digest32
-import scorex.util.{ModifierId, bytesToId, idToBytes}
-
-import scala.util.Random
-
-class SnapshotsDbSpecification extends ErgoPropertyTest {
-
- def seededDatabase(manifestIds: Seq[ModifierId]): (SnapshotsInfo, SnapshotsDb) = {
- val m = manifestIds.map { mid =>
- Random.nextInt(1000000) -> (Digest32 @@ idToBytes(mid))
- }.toMap
- val si = new SnapshotsInfo(m)
- val dir = createTempDir.getAbsolutePath
- val db = SnapshotsDb.create(dir)
- db.writeSnapshotsInfo(si)
- si -> db
- }
-
- property("snapshotsInfo round-trip") {
- forAll(Gen.nonEmptyListOf(modifierIdGen)) { manifestIds =>
- val (si, db) = seededDatabase(manifestIds)
- val read = db.readSnapshotsInfo.availableManifests.mapValues(bs => bytesToId(bs))
- val siTocompare = si.availableManifests.mapValues(bs => bytesToId(bs))
- read shouldBe siTocompare
- }
- }
-
- property("pruneSnapshots choosing snapshots correctly") {
- forAll(Gen.nonEmptyListOf(modifierIdGen)) { manifestIds =>
- val (si, db) = seededDatabase(manifestIds)
-
- val toStore = Random.nextInt(manifestIds.size + 3)
-
- db.pruneSnapshots(toStore)
-
- val after = db.readSnapshotsInfo
-
- if (toStore >= manifestIds.size) {
- after.availableManifests.size == manifestIds.size
- } else {
- val storedKeys = si.availableManifests.keySet.toSeq.sorted.takeRight(toStore)
- val stored = si.availableManifests.filterKeys(h => storedKeys.contains(h))
- after.availableManifests.mapValues(bytesToId) shouldBe stored.mapValues(bytesToId)
- }
- }
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/SnapshotsInfoSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/SnapshotsInfoSpecification.scala
deleted file mode 100644
index 4f3b0ffe79..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/SnapshotsInfoSpecification.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.ergoplatform.nodeView.state
-
-import org.ergoplatform.utils.ErgoPropertyTest
-
-class SnapshotsInfoSpecification extends ErgoPropertyTest {
-
- property("makeEmpty / nonEmpty / withNewManifest") {
- val empty = SnapshotsInfo.empty
- empty.nonEmpty shouldBe false
-
- val h = 10
- val d = digest32Gen.sample.get
- val nonEmpty = empty.withNewManifest(h, d)
- nonEmpty.nonEmpty shouldBe true
- nonEmpty.availableManifests(h).sameElements(d) shouldBe true
-
- val h2 = 20
- val d2 = digest32Gen.sample.get
- val ne2 = nonEmpty.withNewManifest(h2, d2)
- nonEmpty.availableManifests.size shouldBe 1
- ne2.availableManifests(h).sameElements(d) shouldBe true
- ne2.availableManifests(h2).sameElements(d2) shouldBe true
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala
deleted file mode 100644
index e3dc146a8c..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala
+++ /dev/null
@@ -1,528 +0,0 @@
-package org.ergoplatform.nodeView.state
-
-import java.util.concurrent.Executors
-import org.ergoplatform.ErgoBox.{BoxId, R4}
-import org.ergoplatform._
-import org.ergoplatform.mining._
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.extension.Extension
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.history.{ADProofs, BlockTransactions}
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction}
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
-import org.ergoplatform.settings.Constants
-import org.ergoplatform.utils.{ErgoPropertyTest, RandomWrapper}
-import org.ergoplatform.utils.generators.ErgoTransactionGenerators
-import scorex.core._
-import scorex.core.transaction.TooHighCostError
-import scorex.crypto.authds.ADKey
-import scorex.db.ByteArrayWrapper
-import scorex.util.{ModifierId, bytesToId}
-import scorex.util.encode.Base16
-import sigmastate.Values.ByteArrayConstant
-import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog}
-import sigmastate.interpreter.ProverResult
-import sigmastate.helpers.TestingHelpers._
-
-import scala.concurrent.duration.Duration
-import scala.concurrent.{Await, ExecutionContext, ExecutionContextExecutor, Future}
-import scala.util.Try
-
-
-class UtxoStateSpecification extends ErgoPropertyTest with ErgoTransactionGenerators {
-
- private val emptyModifierId: ModifierId = bytesToId(Array.fill(32)(0.toByte))
-
- property("Founders box workflow") {
- var (us, bh) = createUtxoState(settings)
- var foundersBox = genesisBoxes.last
- var lastBlock = validFullBlock(parentOpt = None, us, bh)
- us = us.applyModifier(lastBlock, None)(_ => ()).get
-
- // spent founders box, leaving the same proposition
- (0 until 10) foreach { _ =>
- val height = us.stateContext.currentHeight
- val inputs = IndexedSeq(Input(foundersBox.id, emptyProverResult))
- val remaining = emission.remainingFoundationRewardAtHeight(height)
- val newFoundersBox = testBox(remaining, foundersBox.ergoTree, height, Seq(), Map(R4 -> foundersBox.additionalRegisters(R4)))
- val rewardBox = testBox(foundersBox.value - remaining, defaultProver.hdKeys.last.publicImage, height)
- val newBoxes = IndexedSeq(newFoundersBox, rewardBox)
- val unsignedTx = new UnsignedErgoTransaction(inputs, IndexedSeq(), newBoxes)
- val tx: ErgoTransaction = ErgoTransaction(defaultProver.sign(unsignedTx, IndexedSeq(foundersBox), emptyDataBoxes, us.stateContext).get)
- val txCostLimit = initSettings.nodeSettings.maxTransactionCost
- us.validateWithCost(tx, us.stateContext.simplifiedUpcoming(), txCostLimit, None).get should be <= 100000
- val block1 = validFullBlock(Some(lastBlock), us, Seq(ErgoTransaction(tx)))
- us = us.applyModifier(block1, None)(_ => ()).get
- foundersBox = tx.outputs.head
- lastBlock = block1
- }
- }
-
- property("Founders should be able to spend genesis founders box") {
- var (us, bh) = createUtxoState(settings)
- val foundersBox = genesisBoxes.last
- var height: Int = ErgoHistory.GenesisHeight
-
- val settingsPks = settings.chainSettings.foundersPubkeys
- .map(str => groupElemFromBytes(Base16.decode(str).get))
- .map(pk => ProveDlog(pk))
- settingsPks.count(defaultProver.hdPubKeys.map(_.key).contains) shouldBe 2
-
- forAll(defaultHeaderGen) { header =>
- val rewardPk = new DLogProverInput(BigInt(header.height).bigInteger).publicImage
-
- val t = validTransactionsFromBoxHolder(bh, new RandomWrapper(Some(height)))
- val txs = t._1
- bh = t._2
- val (adProofBytes, adDigest) = us.proofsForTransactions(txs).get
- val realHeader = header.copy(stateRoot = adDigest,
- ADProofsRoot = ADProofs.proofDigest(adProofBytes),
- height = height,
- parentId = us.stateContext.lastHeaderOpt.map(_.id).getOrElse(Header.GenesisParentId))
- val adProofs = ADProofs(realHeader.id, adProofBytes)
- val bt = BlockTransactions(realHeader.id, Header.InitialVersion, txs)
- val fb = ErgoFullBlock(realHeader, bt, genExtension(realHeader, us.stateContext), Some(adProofs))
- us = us.applyModifier(fb, None)(_ => ()).get
- val remaining = emission.remainingFoundationRewardAtHeight(height)
-
- // check validity of transaction, spending founders box
- val inputs = IndexedSeq(Input(foundersBox.id, emptyProverResult))
- val newBoxes = IndexedSeq(
- testBox(remaining, foundersBox.ergoTree, height, Seq(), foundersBox.additionalRegisters),
- testBox(foundersBox.value - remaining, rewardPk, height, Seq())
- )
- val unsignedTx = new UnsignedErgoTransaction(inputs, IndexedSeq(), newBoxes)
- val tx = ErgoTransaction(defaultProver.sign(unsignedTx, IndexedSeq(foundersBox), emptyDataBoxes, us.stateContext).get)
- val validationContext = us.stateContext.simplifiedUpcoming()
- val validationRes1 = us.validateWithCost(tx, validationContext, 100000, None)
- validationRes1 shouldBe 'success
- val txCost = validationRes1.get
-
- val validationRes2 = us.validateWithCost(tx, validationContext, txCost - 1, None)
- validationRes2 shouldBe 'failure
- validationRes2.toEither.left.get.isInstanceOf[TooHighCostError] shouldBe true
-
- us.validateWithCost(tx, validationContext, txCost + 1, None) shouldBe 'success
-
- us.validateWithCost(tx, validationContext, txCost, None) shouldBe 'success
-
- height = height + 1
- }
- }
-
- property("Correct genesis state") {
- val (us, bh) = createUtxoState(settings)
- val boxes = bh.boxes.values.toList
- boxes.size shouldBe 3
-
- // check tests consistency
- genesisBoxes.length shouldBe bh.boxes.size
- genesisBoxes.foreach { b =>
- us.boxById(b.id).isDefined shouldBe true
- bh.boxes.contains(ByteArrayWrapper(b.id)) shouldBe true
- }
-
- // check total supply
- boxes.map(_.value).sum shouldBe coinsTotal
-
- // boxes should contain all no-premine proofs in registers
- val additionalRegisters = boxes.flatMap(_.additionalRegisters.values)
- initSettings.chainSettings.noPremineProof.foreach { pStr =>
- val pBytes = ByteArrayConstant(pStr.getBytes("UTF-8"))
- additionalRegisters should contain(pBytes)
- }
-
- }
-
- property("extractEmissionBox() should extract correct box") {
- var (us, bh) = createUtxoState(settings)
- us.emissionBoxOpt should not be None
- var lastBlockOpt: Option[ErgoFullBlock] = None
- forAll { seed: Int =>
- val blBh = validFullBlockWithBoxHolder(lastBlockOpt, us, bh, new RandomWrapper(Some(seed)))
- val block = blBh._1
- us.extractEmissionBox(block) should not be None
- lastBlockOpt = Some(block)
- bh = blBh._2
- us = us.applyModifier(block, None)(_ => ()).get
- }
- }
-
- property("fromBoxHolder") {
- forAll(boxesHolderGen) { bh =>
- val us = createUtxoState(bh, parameters)
- bh.take(1000)._1.foreach { box =>
- us.boxById(box.id) shouldBe Some(box)
- }
- }
- }
-
- property("proofsForTransactions") {
- var (us: UtxoState, bh) = createUtxoState(settings)
- var height: Int = ErgoHistory.GenesisHeight
- forAll(defaultHeaderGen) { header =>
- val t = validTransactionsFromBoxHolder(bh, new RandomWrapper(Some(height)))
- val txs = t._1
- bh = t._2
- val (adProofBytes, adDigest) = us.proofsForTransactions(txs).get
- val realHeader = header.copy(stateRoot = adDigest,
- ADProofsRoot = ADProofs.proofDigest(adProofBytes),
- height = height,
- parentId = us.stateContext.lastHeaderOpt.map(_.id).getOrElse(Header.GenesisParentId))
- val adProofs = ADProofs(realHeader.id, adProofBytes)
- val bt = BlockTransactions(realHeader.id, 1: Byte, txs)
- val fb = ErgoFullBlock(realHeader, bt, genExtension(realHeader, us.stateContext), Some(adProofs))
- us = us.applyModifier(fb, None)(_ => ()).get
- height = height + 1
- }
- }
-
- property("concurrent applyModifier() and proofsForTransactions()") {
- implicit val ec: ExecutionContextExecutor = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(4))
-
- var bh = BoxHolder(Seq(genesisEmissionBox))
- var us = createUtxoState(bh, parameters)
-
- var height: Int = ErgoHistory.GenesisHeight
- // generate chain of correct full blocks
- val chain = (0 until 10) map { _ =>
- val header = defaultHeaderGen.sample.value
- val t = validTransactionsFromBoxHolder(bh, new RandomWrapper(Some(height)))
- val txs = t._1
- bh = t._2
- val (adProofBytes, adDigest) = us.proofsForTransactions(txs).get
- val realHeader = header.copy(stateRoot = adDigest,
- ADProofsRoot = ADProofs.proofDigest(adProofBytes),
- height = height,
- parentId = us.stateContext.lastHeaderOpt.map(_.id).getOrElse(Header.GenesisParentId))
- val adProofs = ADProofs(realHeader.id, adProofBytes)
- height = height + 1
- val bt = BlockTransactions(realHeader.id, Header.InitialVersion, txs)
- val fb = ErgoFullBlock(realHeader, bt, genExtension(realHeader, us.stateContext), Some(adProofs))
- us = us.applyModifier(fb, None)(_ => ()).get
- fb
- }
- // create new genesis state
- var us2 = createUtxoState(BoxHolder(Seq(genesisEmissionBox)), parameters)
- val stateReader = us2.getReader.asInstanceOf[UtxoState]
- // parallel thread that generates proofs
- val f = Future {
- (0 until 1000) foreach { _ =>
- Try {
- val boxes = stateReader.randomBox().toSeq
- val txs = validTransactionsFromBoxes(400, boxes, new RandomWrapper)._1
- stateReader.proofsForTransactions(txs).get
- }
- }
- }
- // apply chain of headers full block to state
- chain.foreach { fb =>
- us2 = us2.applyModifier(fb, None)(_ => ()).get
- }
- Await.result(f, Duration.Inf)
- }
-
- property("proofsForTransactions() to be deterministic") {
- forAll(boxesHolderGen) { bh =>
- val us = createUtxoState(bh, parameters)
- val txs = validTransactionsFromBoxHolder(bh)._1
-
- val (proof1, digest1) = us.proofsForTransactions(txs).get
- val (proof2, digest2) = us.proofsForTransactions(txs).get
-
- ADProofs.proofDigest(proof1) shouldBe ADProofs.proofDigest(proof2)
- digest1 shouldBe digest2
- }
- }
-
- property("applyTransactions() - simple case for transaction with dataInputs") {
- forAll(boxesHolderGen) { bh =>
- val txsIn = validTransactionsFromBoxHolder(bh)._1
- val headTx = txsIn.head
- val us = createUtxoState(bh, parameters)
- val existingBoxes: IndexedSeq[BoxId] = bh.boxes.takeRight(3).map(_._2.id).toIndexedSeq
-
- // trying to apply transactions with missing data inputs
- val missedId: BoxId = ADKey @@ scorex.util.Random.randomBytes()
- us.boxById(missedId) shouldBe None
- val missingDataInputs = (missedId +: existingBoxes).map(DataInput).toIndexedSeq
- val txWithMissedDataInputs = ErgoTransaction(headTx.inputs, missingDataInputs, headTx.outputCandidates)
- val incorrectTransactions = IndexedSeq(txWithMissedDataInputs)
- // proof for transaction works correctly, providing proof-of-non-existence for missed input
- val digest2 = us.proofsForTransactions(incorrectTransactions).get._2
- us.applyTransactions(incorrectTransactions, emptyModifierId, digest2, emptyStateContext) shouldBe 'failure
-
- // trying to apply transactions with correct data inputs
- val existingDataInputs = existingBoxes.map(DataInput).toIndexedSeq
- existingDataInputs.foreach(b => us.boxById(b.boxId) should not be None)
- val txWithDataInputs = ErgoTransaction(headTx.inputs, existingDataInputs, headTx.outputCandidates)
- val correctTransactions = IndexedSeq(txWithDataInputs)
- val digest = us.proofsForTransactions(correctTransactions).get._2
- us.applyTransactions(correctTransactions, emptyModifierId, digest, emptyStateContext).get
- }
- }
-
- property("applyTransactions() - dataInputs intersect with inputs") {
- forAll(boxesHolderGen) { bh =>
- val us = createUtxoState(bh, parameters)
-
- // generate 2 independent transactions, that only spend state boxes
- val headTx = validTransactionsFromBoxes(1, bh.boxes.take(10).values.toSeq, new RandomWrapper())._1.head
- val nextTx = validTransactionsFromBoxes(1, bh.boxes.takeRight(10).values.toSeq, new RandomWrapper())._1.head
- headTx.inputs.intersect(nextTx.inputs) shouldBe empty
-
- // trying to apply transactions with data inputs same as inputs of the next tx
- val dataInputs = nextTx.inputs.filter(i => us.boxById(i.boxId).isDefined).map(i => DataInput(i.boxId))
- val txWithDataInputs = ErgoTransaction(headTx.inputs, dataInputs, headTx.outputCandidates)
-
- val txs1 = IndexedSeq(headTx, nextTx)
- val txs2 = IndexedSeq(txWithDataInputs, nextTx)
- val sc1 = ErgoState.stateChanges(txs1).get
- val sc2 = ErgoState.stateChanges(IndexedSeq(txWithDataInputs, nextTx)).get
- // check that the only difference between txs1 and txs2 are dataInputs and Lookup tree operations
- txs1.flatMap(_.inputs) shouldBe txs2.flatMap(_.inputs)
- txs1.flatMap(_.outputCandidates) shouldBe txs2.flatMap(_.outputCandidates)
- sc1.toAppend.size shouldBe sc2.toAppend.size
- sc1.toRemove shouldBe sc2.toRemove
-
- us.proofsForTransactions(txs1) shouldBe 'success
- us.proofsForTransactions(txs2) shouldBe 'success
-
- val inputs = headTx.outputs.map(b => Input(b.id, ProverResult.empty))
- val txWithDataInputs2 = ErgoTransaction(inputs, dataInputs, headTx.outputCandidates)
-
- val version = us.version
-
- val txs3 = IndexedSeq(headTx, nextTx, txWithDataInputs2)
- val (_, digest3) = us.proofsForTransactions(txs3).get
- us.applyTransactions(txs3, emptyModifierId, digest3, emptyStateContext) shouldBe 'success
- us.rollbackTo(version)
-
- val txs4 = IndexedSeq(headTx, txWithDataInputs2, nextTx)
- val (_, digest4) = us.proofsForTransactions(txs4).get
- us.applyTransactions(txs4, emptyModifierId, digest4, emptyStateContext) shouldBe 'success
- us.rollbackTo(version)
-
- val txs5 = IndexedSeq(txWithDataInputs2, headTx, nextTx)
- us.proofsForTransactions(txs5) shouldBe 'failure
- us.applyTransactions(txs5, emptyModifierId, digest4, emptyStateContext) shouldBe 'failure
- us.rollbackTo(version)
-
- // trying to apply transactions with data inputs same as outputs of the previous tx
- val dataInputsNext = headTx.outputs.take(1).map(i => DataInput(i.id))
- dataInputsNext should not be empty
- val nextTxWithDataInputs = ErgoTransaction(nextTx.inputs, dataInputsNext, nextTx.outputCandidates)
- val txsNext = IndexedSeq(headTx, nextTxWithDataInputs)
- // proof of non-existence
- val d2 = us.proofsForTransactions(txsNext).get._2
- us.applyTransactions(txsNext, emptyModifierId, d2, emptyStateContext) shouldBe 'success
- }
- }
-
- property("applyTransactions() - simple case") {
- forAll(boxesHolderGen) { bh =>
- val txs = validTransactionsFromBoxHolder(bh)._1
-
- val created = txs.flatMap(_.outputs.map(_.id)).map(ByteArrayWrapper.apply)
- val boxIds = txs.flatMap(_.inputs.map(_.boxId)).map(ByteArrayWrapper.apply)
- boxIds.distinct.size shouldBe boxIds.size
- val toRemove = boxIds.filterNot(id => created.contains(id))
- toRemove.foreach(id => bh.get(id) should not be None)
-
- val us = createUtxoState(bh, parameters)
- bh.sortedBoxes.foreach(box => us.boxById(box.id) should not be None)
- val digest = us.proofsForTransactions(txs).get._2
- val wBlock = invalidErgoFullBlockGen.sample.get
- val block = wBlock.copy(header = wBlock.header.copy(height = 1))
- val newSC = us.stateContext.appendFullBlock(block).get
- us.applyTransactions(txs, emptyModifierId, digest, newSC).get
- }
- }
-
- property("applyTransactions() - a transaction is spending an output created by a previous transaction") {
- forAll(boxesHolderGen) { bh =>
- val txsFromHolder = validTransactionsFromBoxHolder(bh)._1
-
- val boxToSpend = txsFromHolder.last.outputs.head
-
- val spendingTxInput = Input(boxToSpend.id, emptyProverResult)
- val spendingTx = ErgoTransaction(
- IndexedSeq(spendingTxInput),
- IndexedSeq(),
- IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.TrueLeaf, creationHeight = startHeight))
- )
- val txs = txsFromHolder :+ spendingTx
-
- val us = createUtxoState(bh, parameters)
- val digest = us.proofsForTransactions(txs).get._2
-
- val header = invalidHeaderGen.sample.get.copy(stateRoot = digest, height = 1)
- val bt = new BlockTransactions(header.id, 1: Byte, txs)
- val fb = new ErgoFullBlock(header, bt, genExtension(header, us.stateContext), None)
- val newSC = us.stateContext.appendFullBlock(fb).get
- us.applyTransactions(txs, emptyModifierId, digest, newSC).get
- }
- }
-
- property("applyTransactions() - no double-spend of an output created in a block is possible") {
- forAll(boxesHolderGen) { bh =>
- val txsFromHolder = validTransactionsFromBoxHolder(bh)._1
-
- val boxToSpend = txsFromHolder.last.outputs.head
-
- val spendingTxInput = Input(boxToSpend.id, emptyProverResult)
- val spendingTx = ErgoTransaction(
- IndexedSeq(spendingTxInput),
- IndexedSeq(),
- IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.TrueLeaf, creationHeight = startHeight))
- )
-
- val spending2Tx = ErgoTransaction(
- IndexedSeq(Input(spendingTx.outputs.head.id, emptyProverResult)),
- IndexedSeq(),
- IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.TrueLeaf, creationHeight = startHeight))
- )
-
- val spending3Tx = ErgoTransaction(
- IndexedSeq(Input(spending2Tx.outputs.head.id, emptyProverResult)),
- IndexedSeq(),
- IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.TrueLeaf, creationHeight = startHeight))
- )
-
- val spending4Tx = ErgoTransaction(
- IndexedSeq(Input(spending2Tx.outputs.head.id, emptyProverResult)),
- IndexedSeq(),
- IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.FalseLeaf, creationHeight = startHeight))
- )
-
- val txs = txsFromHolder ++ Seq(spendingTx, spending2Tx, spending3Tx, spending4Tx)
-
- val us = createUtxoState(bh, parameters)
-
- // Fails on generating state root digest for the block
- us.proofsForTransactions(txs).isSuccess shouldBe false
- }
- }
-
- property("proofsForTransactions() fails if a transaction is spending an output created by a follow-up transaction") {
- forAll(boxesHolderGen) { bh =>
- val txsFromHolder = validTransactionsFromBoxHolder(bh)._1
-
- val boxToSpend = txsFromHolder.last.outputs.head
-
- val spendingTxInput = Input(boxToSpend.id, emptyProverResult)
- val spendingTx = ErgoTransaction(
- IndexedSeq(spendingTxInput),
- IndexedSeq(),
- IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.TrueLeaf, creationHeight = startHeight)))
-
- val txs = spendingTx +: txsFromHolder
-
- val us = createUtxoState(bh, parameters)
- us.proofsForTransactions(txs).isSuccess shouldBe false
- }
- }
-
- property("applyModifier() - valid full block") {
- forAll(boxesHolderGen) { bh =>
- val us = createUtxoState(bh, parameters)
- bh.sortedBoxes.foreach(box => us.boxById(box.id) should not be None)
-
- val block = validFullBlock(parentOpt = None, us, bh)
- us.applyModifier(block, None)(_ => ()).get
- }
- }
-
- property("applyModifier() - invalid block") {
- forAll(invalidErgoFullBlockGen) { b =>
- val state = createUtxoState(settings)._1
- state.applyModifier(b, None)(_ => ()).isFailure shouldBe true
- }
- }
-
- property("applyModifier() - valid full block after invalid one") {
- val (us, bh) = createUtxoState(settings)
- val validBlock = validFullBlock(parentOpt = None, us, bh)
-
- //Different state
- val (us2, bh2) = {
- lazy val initialBoxes: Seq[ErgoBox] = (1 to 1).map(_ => ergoBoxGenNoProp.sample.get)
-
- val bh = BoxHolder(initialBoxes)
-
- createUtxoState(bh, parameters) -> bh
- }
- val invalidBlock = validFullBlock(parentOpt = None, us2, bh2)
-
- us.applyModifier(invalidBlock, None)(_ => ()).isSuccess shouldBe false
- us.applyModifier(validBlock, None)(_ => ()).isSuccess shouldBe true
- }
-
-
- property("2 forks switching") {
- val (us, bh) = createUtxoState(settings)
- val genesis = validFullBlock(parentOpt = None, us, bh)
- val wusAfterGenesis = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get
- val chain1block1 = validFullBlock(Some(genesis), wusAfterGenesis)
- val wusChain1Block1 = wusAfterGenesis.applyModifier(chain1block1)(_ => ()).get
- val chain1block2 = validFullBlock(Some(chain1block1), wusChain1Block1)
-
- val (us2, bh2) = createUtxoState(settings)
- val wus2AfterGenesis = WrappedUtxoState(us2, bh2, settings, parameters).applyModifier(genesis)(_ => ()).get
- val chain2block1 = validFullBlock(Some(genesis), wus2AfterGenesis)
- val wusChain2Block1 = wus2AfterGenesis.applyModifier(chain2block1)(_ => ()).get
- val chain2block2 = validFullBlock(Some(chain2block1), wusChain2Block1)
-
- var (state, _) = createUtxoState(settings)
- state = state.applyModifier(genesis, None)(_ => ()).get
-
- state = state.applyModifier(chain1block1, None)(_ => ()).get
-
- state = state.rollbackTo(idToVersion(genesis.id)).get
- state = state.applyModifier(chain2block1, None)(_ => ()).get
- state = state.applyModifier(chain2block2, None)(_ => ()).get
-
- state = state.rollbackTo(idToVersion(genesis.id)).get
- state = state.applyModifier(chain1block1, None)(_ => ()).get
- state = state.applyModifier(chain1block2, None)(_ => ()).get
-
- }
-
- property("rollback n blocks and apply again") {
- forAll(boxesHolderGen, smallPositiveInt) { (bh, depth) =>
- whenever(depth > 0 && depth <= 5) {
- val us = createUtxoState(bh, parameters)
- bh.sortedBoxes.foreach(box => us.boxById(box.id) should not be None)
- val genesis = validFullBlock(parentOpt = None, us, bh)
- val wusAfterGenesis = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get
- wusAfterGenesis.rootDigest shouldEqual genesis.header.stateRoot
-
- val (finalState: WrappedUtxoState, chain: Seq[ErgoFullBlock]) = (0 until depth)
- .foldLeft((wusAfterGenesis, Seq(genesis))) { (sb, _) =>
- val state = sb._1
- val block = validFullBlock(parentOpt = Some(sb._2.last), state)
- (state.applyModifier(block)(_ => ()).get, sb._2 ++ Seq(block))
- }
- val finalRoot = finalState.rootDigest
- finalRoot shouldEqual chain.last.header.stateRoot
-
- val rollbackedState = finalState.rollbackTo(idToVersion(genesis.id)).get
- rollbackedState.rootDigest shouldEqual genesis.header.stateRoot
-
- val finalState2: WrappedUtxoState = chain.tail.foldLeft(rollbackedState) { (state, block) =>
- state.applyModifier(block)(_ => ()).get
- }
-
- finalState2.rootDigest shouldEqual finalRoot
- }
- }
- }
-
-
-
- private def genExtension(header: Header, sc: ErgoStateContext): Extension = {
- nipopowAlgos.interlinksToExtension(nipopowAlgos.updateInterlinks(sc.lastHeaderOpt, sc.lastExtensionOpt)).toExtension(header.id)
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedDigestState.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedDigestState.scala
deleted file mode 100644
index fe1933fad9..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedDigestState.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.ergoplatform.nodeView.state.wrapped
-
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedModifier
-import org.ergoplatform.ErgoLikeContext.Height
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.nodeView.state.DigestState
-import org.ergoplatform.settings.ErgoSettings
-import scorex.core.VersionTag
-
-import scala.util.Try
-
-class WrappedDigestState(val digestState: DigestState,
- val wrappedUtxoState: WrappedUtxoState,
- val settings: ErgoSettings)
- extends DigestState(digestState.version, digestState.rootDigest, digestState.store, settings) {
-
- override def applyModifier(mod: BlockSection, estimatedTip: Option[Height])
- (generate: LocallyGeneratedModifier => Unit): Try[WrappedDigestState] = {
- wrapped(super.applyModifier(mod, estimatedTip)(_ => ()), wrappedUtxoState.applyModifier(mod, estimatedTip)(_ => ()))
- }
-
- override def rollbackTo(version: VersionTag): Try[WrappedDigestState] = {
- wrapped(super.rollbackTo(version), wrappedUtxoState.rollbackTo(version))
- }
-
- private def wrapped(digestT: Try[DigestState], utxoT: Try[WrappedUtxoState]): Try[WrappedDigestState] =
- digestT.flatMap(digest => utxoT.map(utxo => new WrappedDigestState(digest, utxo, settings)))
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedUtxoState.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedUtxoState.scala
deleted file mode 100644
index d747a4b5be..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedUtxoState.scala
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.ergoplatform.nodeView.state.wrapped
-
-import java.io.File
-
-import akka.actor.ActorRef
-import org.ergoplatform.ErgoBox
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedModifier
-import org.ergoplatform.ErgoLikeContext.Height
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.nodeView.state._
-import org.ergoplatform.settings.{ErgoSettings, Parameters}
-import org.ergoplatform.settings.Algos.HF
-import org.ergoplatform.wallet.boxes.ErgoBoxSerializer
-import scorex.core.{TransactionsCarryingPersistentNodeViewModifier, VersionTag, idToVersion}
-import scorex.crypto.authds.avltree.batch._
-import scorex.crypto.hash.Digest32
-import scorex.db.{ByteArrayWrapper, LDBVersionedStore}
-
-import scala.util.{Failure, Success, Try}
-
-class WrappedUtxoState(prover: PersistentBatchAVLProver[Digest32, HF],
- override val version: VersionTag,
- store: LDBVersionedStore,
- val versionedBoxHolder: VersionedInMemoryBoxHolder,
- settings: ErgoSettings)
- extends UtxoState(prover, version, store, settings) {
-
- def size: Int = versionedBoxHolder.size
-
- def takeBoxes(count: Int): Seq[ErgoBox] = versionedBoxHolder.take(count)._1
-
- override def rollbackTo(version: VersionTag): Try[WrappedUtxoState] = super.rollbackTo(version) match {
- case Success(us) =>
- val updHolder = versionedBoxHolder.rollback(us.version)
- Success(new WrappedUtxoState(us.persistentProver, version, us.store, updHolder, settings))
- case Failure(e) => Failure(e)
- }
-
- override def applyModifier(mod: BlockSection, estimatedTip: Option[Height] = None)
- (generate: LocallyGeneratedModifier => Unit): Try[WrappedUtxoState] =
- super.applyModifier(mod, estimatedTip)(generate) match {
- case Success(us) =>
- mod match {
- case ct: TransactionsCarryingPersistentNodeViewModifier =>
- // You can not get block with transactions not being of ErgoTransaction type so no type checks here.
-
- val changes = ErgoState.stateChanges(ct.transactions).get
- val updHolder = versionedBoxHolder.applyChanges(
- us.version,
- changes.toRemove.map(_.key).map(ByteArrayWrapper.apply),
- changes.toAppend.map(_.value).map(ErgoBoxSerializer.parseBytes))
- Success(new WrappedUtxoState(us.persistentProver, idToVersion(mod.id), us.store, updHolder, settings))
- case _ =>
- val updHolder = versionedBoxHolder.applyChanges(us.version, Seq(), Seq())
- Success(new WrappedUtxoState(us.persistentProver, idToVersion(mod.id), us.store, updHolder, settings))
- }
- case Failure(e) => Failure(e)
- }
-}
-
-object WrappedUtxoState {
-
- def apply(boxHolder: BoxHolder,
- dir: File,
- nodeViewHolderRef: Option[ActorRef],
- parameters: Parameters,
- settings: ErgoSettings): WrappedUtxoState = {
- val emissionBox = ErgoState.genesisBoxes(settings.chainSettings).headOption
- val us = UtxoState.fromBoxHolder(boxHolder, emissionBox, dir, settings, parameters)
- WrappedUtxoState(us, boxHolder, settings, parameters)
- }
-
- def apply(us: UtxoState, boxHolder: BoxHolder, settings: ErgoSettings, parameters: Parameters): WrappedUtxoState = {
- val boxes = boxHolder.boxes
-
- val version = us.version
- val vbh = new VersionedInMemoryBoxHolder(
- boxes,
- IndexedSeq(version),
- Map(version -> (Seq() -> boxHolder.sortedBoxes.toSeq))
- )
-
- new WrappedUtxoState(us.persistentProver, ErgoState.genesisStateVersion, us.store, vbh, settings)
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/viewholder/ErgoNodeViewHolderSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/viewholder/ErgoNodeViewHolderSpec.scala
deleted file mode 100644
index 83e9243ad9..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/viewholder/ErgoNodeViewHolderSpec.scala
+++ /dev/null
@@ -1,553 +0,0 @@
-package org.ergoplatform.nodeView.viewholder
-
-import java.io.File
-import org.ergoplatform.ErgoBoxCandidate
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.mempool.UnconfirmedTransaction
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.state.StateType.Utxo
-import org.ergoplatform.nodeView.state._
-import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
-import org.ergoplatform.settings.{Algos, Constants, ErgoSettings}
-import org.ergoplatform.utils.{ErgoPropertyTest, HistoryTestHelpers, NodeViewTestConfig, NodeViewTestOps, TestCase}
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages._
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages._
-import org.ergoplatform.nodeView.ErgoNodeViewHolder
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.ChainProgress
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.ProcessingOutcome.Accepted
-import scorex.crypto.authds.{ADKey, SerializedAdProof}
-import scorex.testkit.utils.NoShrink
-import scorex.util.{ModifierId, bytesToId}
-
-class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers with NodeViewTestOps with NoShrink {
-
- private val t0 = TestCase("check chain is healthy") { fixture =>
- val (us, bh) = createUtxoState(settings)
- val block = validFullBlock(None, us, bh)
-
- val history = generateHistory(true, StateType.Utxo, false, 2)
-
- // too big chain update delay
- val notAcceptableDelay = System.currentTimeMillis() - (initSettings.nodeSettings.acceptableChainUpdateDelay.toMillis + 100)
- val invalidProgress = ChainProgress(block, 2, 3, notAcceptableDelay)
- ErgoNodeViewHolder.checkChainIsHealthy(invalidProgress, history, initSettings).isInstanceOf[ChainIsStuck] shouldBe true
-
- // acceptable chain update delay
- val acceptableDelay = System.currentTimeMillis() - 5
- val validProgress = ChainProgress(block, 2, 3, acceptableDelay)
- ErgoNodeViewHolder.checkChainIsHealthy(validProgress, history, initSettings) shouldBe ChainIsHealthy
- }
-
-
- private val t1 = TestCase("check genesis state") { fixture =>
- import fixture._
- getCurrentState.rootDigest shouldBe getGenesisStateDigest
- }
-
- private val t2 = TestCase("check history after genesis") { fixture =>
- import fixture._
- getBestHeaderOpt shouldBe None
- }
-
- private val t3 = TestCase("apply valid block header") { fixture =>
- import fixture._
- val (us, bh) = createUtxoState(fixture.settings)
- val block = validFullBlock(None, us, bh)
-
- getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
-
- subscribeEvents(classOf[SyntacticallySuccessfulModifier])
-
- //sending header
- nodeViewHolderRef ! LocallyGeneratedModifier(block.header)
- expectMsgType[SyntacticallySuccessfulModifier]
-
- getHistoryHeight shouldBe ErgoHistory.GenesisHeight
- getHeightOf(block.header.id) shouldBe Some(ErgoHistory.GenesisHeight)
- getLastHeadersLength(10) shouldBe 1
- getBestHeaderOpt shouldBe Some(block.header)
- }
-
- private val t3a = TestCase("do not apply block headers in invalid order") { fixture =>
- import fixture._
- val (us, bh) = createUtxoState(fixture.settings)
- val parentBlock = validFullBlock(None, us, bh)
- val block = validFullBlock(Some(parentBlock), us, bh)
-
- getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
-
- subscribeEvents(classOf[SyntacticallySuccessfulModifier])
-
- //sending child header without parent header
- nodeViewHolderRef ! ModifiersFromRemote(List(block.header))
- expectNoMsg()
-
- // sende correct header sequence
- nodeViewHolderRef ! ModifiersFromRemote(List(parentBlock.header))
- expectMsgType[SyntacticallySuccessfulModifier]
-
- nodeViewHolderRef ! ModifiersFromRemote(List(block.header))
- expectMsgType[SyntacticallySuccessfulModifier]
-
- getHistoryHeight shouldBe 2
- }
-
- private val t4 = TestCase("apply valid block as genesis") { fixture =>
- import fixture._
- val (us, bh) = createUtxoState(fixture.settings)
- val genesis = validFullBlock(parentOpt = None, us, bh)
-
- subscribeEvents(classOf[SyntacticallySuccessfulModifier])
- nodeViewHolderRef ! LocallyGeneratedModifier(genesis.header)
- expectMsgType[SyntacticallySuccessfulModifier]
-
- if (verifyTransactions) {
- nodeViewHolderRef ! LocallyGeneratedModifier(genesis.blockTransactions)
- expectMsgType[SyntacticallySuccessfulModifier]
- nodeViewHolderRef ! LocallyGeneratedModifier(genesis.adProofs.value)
- expectMsgType[SyntacticallySuccessfulModifier]
- nodeViewHolderRef ! LocallyGeneratedModifier(genesis.extension)
- expectMsgType[SyntacticallySuccessfulModifier]
- getBestFullBlockOpt shouldBe Some(genesis)
- }
- }
-
- private val t5 = TestCase("apply full blocks after genesis") { fixture =>
- import fixture._
- val (us, bh) = createUtxoState(fixture.settings)
- val genesis = validFullBlock(parentOpt = None, us, bh)
- val wusAfterGenesis =
- WrappedUtxoState(us, bh, fixture.settings, parameters).applyModifier(genesis) { mod =>
- nodeViewHolderRef ! mod
- }.get
- applyBlock(genesis) shouldBe 'success
-
- val block = validFullBlock(Some(genesis), wusAfterGenesis)
- applyBlock(block) shouldBe 'success
- if (verifyTransactions) {
- getBestFullBlockOpt shouldBe Some(block)
- }
-
- getBestHeaderOpt shouldBe Some(block.header)
- getHistoryHeight shouldBe block.header.height
- getLastHeadersLength(10) shouldBe 2
- }
-
- private val t6 = TestCase("add transaction to memory pool") { fixture =>
- import fixture._
- if (stateType == Utxo) {
- val (us, bh) = createUtxoState(fixture.settings)
- val genesis = validFullBlock(parentOpt = None, us, bh)
- applyBlock(genesis) shouldBe 'success
-
- val boxes = ErgoState.newBoxes(genesis.transactions).find(_.ergoTree == Constants.TrueLeaf)
- boxes.nonEmpty shouldBe true
-
- val tx = UnconfirmedTransaction(validTransactionFromBoxes(boxes.toIndexedSeq), None)
- subscribeEvents(classOf[FailedTransaction])
- nodeViewHolderRef ! LocallyGeneratedTransaction(tx)
- expectMsgType[Accepted]
- getPoolSize shouldBe 1
- }
- }
-
- private val t7 = TestCase("apply statefully invalid full block") { fixture =>
- import fixture._
- val (us, bh) = createUtxoState(fixture.settings)
- val genesis = validFullBlock(parentOpt = None, us, bh)
- val wusAfterGenesis =
- WrappedUtxoState(us, bh, fixture.settings, parameters).applyModifier(genesis) { mod =>
- nodeViewHolderRef ! mod
- }.get
- // TODO looks like another bug is still present here, see https://github.com/ergoplatform/ergo/issues/309
- if (verifyTransactions) {
- applyBlock(genesis) shouldBe 'success
-
- val block = validFullBlock(Some(genesis), wusAfterGenesis)
- val wusAfterBlock = wusAfterGenesis.applyModifier(block)(mod => nodeViewHolderRef ! mod).get
-
- applyBlock(block) shouldBe 'success
- getBestHeaderOpt shouldBe Some(block.header)
- if (verifyTransactions) {
- getRootHash shouldBe Algos.encode(wusAfterBlock.rootDigest)
- }
- getBestHeaderOpt shouldBe Some(block.header)
-
- val brokenBlock = generateInvalidFullBlock(Some(block), wusAfterBlock)
- applyBlock(brokenBlock) shouldBe 'success
-
- val brokenBlock2 = generateInvalidFullBlock(Some(block), wusAfterBlock)
- brokenBlock2.header should not be brokenBlock.header
- applyBlock(brokenBlock2) shouldBe 'success
-
- getBestFullBlockOpt shouldBe Some(block)
- getRootHash shouldBe Algos.encode(wusAfterBlock.rootDigest)
- getBestHeaderOpt shouldBe Some(block.header)
- }
- }
-
- /**
- * Generates statefuly invalid full block (contains invalid transactions).
- */
- private def generateInvalidFullBlock(parentBlockOpt: Option[ErgoFullBlock], parentState: WrappedUtxoState) = {
- val validInterlinks = nipopowAlgos.updateInterlinks(parentBlockOpt.map(_.header), parentBlockOpt.map(_.extension))
- val extensionIn = nipopowAlgos.interlinksToExtension(validInterlinks).toExtension(modifierIdGen.sample.get)
- val brokenBlockIn = validFullBlock(parentBlockOpt, parentState)
- val headTx = brokenBlockIn.blockTransactions.txs.head
- val wrongBoxId: ADKey = ADKey !@@ Algos.hash("wrong input")
- val newInput = headTx.inputs.head.copy(boxId = wrongBoxId)
- val brokenTransactionsIn = brokenBlockIn.blockTransactions
- .copy(txs = headTx.copy(inputs = newInput +: headTx.inputs.tail) +: brokenBlockIn.blockTransactions.txs.tail)
- val brokenHeader = brokenBlockIn.header
- .copy(transactionsRoot = brokenTransactionsIn.digest, extensionRoot = extensionIn.digest)
- val brokenTransactions = brokenTransactionsIn.copy(headerId = brokenHeader.id)
- val brokenProofs = brokenBlockIn.adProofs.value.copy(headerId = brokenHeader.id)
- val extension = extensionIn.copy(headerId = brokenHeader.id)
- ErgoFullBlock(brokenHeader, brokenTransactions, extension, Some(brokenProofs))
- }
-
- private val t8 = TestCase("switching for a better chain") { fixture =>
- import fixture._
- val (us, bh) = createUtxoState(fixture.settings)
- val genesis = validFullBlock(parentOpt = None, us, bh)
- val wusAfterGenesis =
- WrappedUtxoState(us, bh, fixture.settings, parameters).applyModifier(genesis) { mod =>
- nodeViewHolderRef ! mod
- }.get
-
- applyBlock(genesis) shouldBe 'success
- getRootHash shouldBe Algos.encode(wusAfterGenesis.rootDigest)
-
- val chain1block1 = validFullBlock(Some(genesis), wusAfterGenesis)
- val expectedBestFullBlockOpt = if (verifyTransactions) Some(chain1block1) else None
- applyBlock(chain1block1) shouldBe 'success
- getBestFullBlockOpt shouldBe expectedBestFullBlockOpt
- getBestHeaderOpt shouldBe Some(chain1block1.header)
-
- val chain2block1 = validFullBlock(Some(genesis), wusAfterGenesis)
- applyBlock(chain2block1) shouldBe 'success
- getBestFullBlockOpt shouldBe expectedBestFullBlockOpt
- getBestHeaderOpt shouldBe Some(chain1block1.header)
-
- val wusChain2Block1 = wusAfterGenesis.applyModifier(chain2block1)(mod => nodeViewHolderRef ! mod).get
- val chain2block2 = validFullBlock(Some(chain2block1), wusChain2Block1)
- chain2block1.header.stateRoot shouldEqual wusChain2Block1.rootDigest
-
- applyBlock(chain2block2) shouldBe 'success
- if (verifyTransactions) {
- getBestFullBlockEncodedId shouldBe Some(chain2block2.header.encodedId)
- }
-
- getBestHeaderOpt shouldBe Some(chain2block2.header)
- getRootHash shouldBe Algos.encode(chain2block2.header.stateRoot)
- }
-
- private val t9 = TestCase("UTXO state should generate adProofs and put them in history") { fixture =>
- import fixture._
- if (stateType == StateType.Utxo) {
- val (us, bh) = createUtxoState(fixture.settings)
- val genesis = validFullBlock(parentOpt = None, us, bh)
-
- nodeViewHolderRef ! LocallyGeneratedModifier(genesis.header)
- nodeViewHolderRef ! LocallyGeneratedModifier(genesis.blockTransactions)
- nodeViewHolderRef ! LocallyGeneratedModifier(genesis.extension)
-
- getBestFullBlockOpt shouldBe Some(genesis)
- getModifierById(genesis.adProofs.value.id) shouldBe genesis.adProofs
- }
- }
-
- private val t10 = TestCase("NodeViewHolder start from inconsistent state") { fixture =>
- import fixture._
- val (us, bh) = createUtxoState(fixture.settings)
- val genesis = validFullBlock(parentOpt = None, us, bh)
- val wusAfterGenesis =
- WrappedUtxoState(us, bh, fixture.settings, parameters).applyModifier(genesis) { mod =>
- nodeViewHolderRef ! mod
- }.get
- applyBlock(genesis) shouldBe 'success
-
- val block1 = validFullBlock(Some(genesis), wusAfterGenesis)
- applyBlock(block1) shouldBe 'success
- getBestFullBlockOpt shouldBe Some(block1)
- getRootHash shouldBe Algos.encode(block1.header.stateRoot)
-
- stopNodeViewHolder()
- val stateDir = new File(s"${nodeViewDir.getAbsolutePath}/state")
- this.deleteRecursive(stateDir)
- startNodeViewHolder()
-
- getRootHash shouldBe Algos.encode(block1.header.stateRoot)
- }
-
- private val t11 = TestCase("apply payload in incorrect order (excluding extension)") { fixture =>
- import fixture._
- val (us, bh) = createUtxoState(fixture.settings)
- val genesis = validFullBlock(parentOpt = None, us, bh)
- val wusAfterGenesis =
- WrappedUtxoState(us, bh, fixture.settings, parameters).applyModifier(genesis) { mod =>
- nodeViewHolderRef ! mod
- }.get
-
- applyBlock(genesis) shouldBe 'success
- getRootHash shouldBe Algos.encode(wusAfterGenesis.rootDigest)
-
- val chain2block1 = validFullBlock(Some(genesis), wusAfterGenesis)
- val wusChain2Block1 = wusAfterGenesis.applyModifier(chain2block1)(mod => nodeViewHolderRef ! mod).get
- val chain2block2 = validFullBlock(Some(chain2block1), wusChain2Block1)
-
- subscribeEvents(classOf[RecoverableFailedModification])
- subscribeEvents(classOf[SyntacticallySuccessfulModifier])
- nodeViewHolderRef ! LocallyGeneratedModifier(chain2block1.header)
- expectMsgType[SyntacticallySuccessfulModifier]
-
- applyBlock(chain2block2, excludeExt = true) shouldBe 'success
- getBestHeaderOpt shouldBe Some(chain2block2.header)
- getBestFullBlockEncodedId shouldBe Some(genesis.header.encodedId)
-
- applyPayload(chain2block1, excludeExt = true) shouldBe 'success
- getBestHeaderEncodedId shouldBe Some(chain2block2.header.encodedId)
- }
-
- private val t12 = TestCase("Do not apply txs with wrong header id") { fixture =>
- import fixture._
-
- val (us, bh) = createUtxoState(fixture.settings)
- val block = validFullBlock(None, us, bh)
- getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
-
- subscribeEvents(classOf[RecoverableFailedModification])
- subscribeEvents(classOf[SyntacticallySuccessfulModifier])
- subscribeEvents(classOf[SyntacticallyFailedModification])
-
- //sending header
- nodeViewHolderRef ! LocallyGeneratedModifier(block.header)
- expectMsgType[SyntacticallySuccessfulModifier]
- val currentHeight = getHistoryHeight
- currentHeight shouldBe ErgoHistory.GenesisHeight
- getHeightOf(block.header.id) shouldBe Some(ErgoHistory.GenesisHeight)
-
- val randomId = modifierIdGen.sample.value
- val recoverableTxs = block.blockTransactions.copy(headerId = randomId)
- val invalidTxsWithWrongOutputs = {
- val txs = block.blockTransactions.transactions
- val tx = txs.head
- val wrongOutputs = tx.outputCandidates.map(o =>
- new ErgoBoxCandidate(o.value + 10L, o.ergoTree, currentHeight, o.additionalTokens, o.additionalRegisters)
- )
- val wrongTxs = tx.copy(outputCandidates = wrongOutputs) +: txs.tail
- block.blockTransactions.copy(txs = wrongTxs)
- }
- val invalidTxsWithWrongInputs = {
- val txs = block.blockTransactions.transactions
- val tx = txs.head
- val wrongInputs = tx.inputs.map { input =>
- input.copy(boxId = ADKey @@ input.boxId.reverse)
- }
- val wrongTxs = tx.copy(inputs = wrongInputs) +: txs.tail
- block.blockTransactions.copy(txs = wrongTxs)
- }
-
- nodeViewHolderRef ! LocallyGeneratedModifier(recoverableTxs)
- expectMsgType[RecoverableFailedModification]
-
- nodeViewHolderRef ! LocallyGeneratedModifier(invalidTxsWithWrongOutputs)
- expectMsgType[SyntacticallyFailedModification]
-
- nodeViewHolderRef ! LocallyGeneratedModifier(invalidTxsWithWrongInputs)
- expectMsgType[SyntacticallyFailedModification]
-
- nodeViewHolderRef ! LocallyGeneratedModifier(block.blockTransactions)
- expectMsgType[SyntacticallySuccessfulModifier]
- }
-
- private val t13 = TestCase("Do not apply wrong adProofs") { fixture =>
- import fixture._
-
- val (us, bh) = createUtxoState(fixture.settings)
- val block = validFullBlock(None, us, bh)
- getBestHeaderOpt shouldBe None
-
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
-
- subscribeEvents(classOf[RecoverableFailedModification])
- subscribeEvents(classOf[SyntacticallySuccessfulModifier])
- subscribeEvents(classOf[SyntacticallyFailedModification])
-
- //sending header
- nodeViewHolderRef ! LocallyGeneratedModifier(block.header)
- expectMsgType[SyntacticallySuccessfulModifier]
-
- val randomId = modifierIdGen.sample.value
- val wrongProofsBytes = SerializedAdProof @@ block.adProofs.value.proofBytes.reverse
- val wrongProofs1 = block.adProofs.map(_.copy(headerId = randomId))
- val wrongProofs2 = block.adProofs.map(_.copy(proofBytes = wrongProofsBytes))
-
- nodeViewHolderRef ! LocallyGeneratedModifier(wrongProofs1.value)
- expectMsgType[RecoverableFailedModification]
-
- nodeViewHolderRef ! LocallyGeneratedModifier(wrongProofs2.value)
- expectMsgType[SyntacticallyFailedModification]
-
- nodeViewHolderRef ! LocallyGeneratedModifier(block.adProofs.value)
- expectMsgType[SyntacticallySuccessfulModifier]
- }
-
- private val t14 = TestCase("do not apply genesis block header if " +
- "it's not equal to genesisId from config") { fixture =>
- import fixture._
- updateConfig(genesisIdConfig(modifierIdGen.sample))
- val (us, bh) = createUtxoState(fixture.settings)
- val block = validFullBlock(None, us, bh)
-
- getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
-
- subscribeEvents(classOf[RecoverableFailedModification])
- subscribeEvents(classOf[SyntacticallySuccessfulModifier])
- subscribeEvents(classOf[SyntacticallyFailedModification])
-
- //sending header
- nodeViewHolderRef ! LocallyGeneratedModifier(block.header)
- expectMsgType[SyntacticallyFailedModification]
- getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
- }
-
- private val t15 = TestCase("apply genesis block header if it's equal to genesisId from config") { fixture =>
- import fixture._
- val (us, bh) = createUtxoState(fixture.settings)
- val block = validFullBlock(None, us, bh)
- updateConfig(genesisIdConfig(Some(block.header.id)))
-
- getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
-
- subscribeEvents(classOf[RecoverableFailedModification])
- subscribeEvents(classOf[SyntacticallySuccessfulModifier])
- subscribeEvents(classOf[SyntacticallyFailedModification])
-
- nodeViewHolderRef ! LocallyGeneratedModifier(block.header)
- expectMsgType[SyntacticallySuccessfulModifier]
- getHistoryHeight shouldBe ErgoHistory.GenesisHeight
- getHeightOf(block.header.id) shouldBe Some(ErgoHistory.GenesisHeight)
- }
-
- private val t16 = TestCase("apply forks that include genesis block") { fixture =>
- import fixture._
-
- val (us, bh) = createUtxoState(fixture.settings)
- val wusGenesis = WrappedUtxoState(us, bh, fixture.settings, parameters)
-
-
- val chain1block1 = validFullBlock(parentOpt = None, us, bh)
- val expectedBestFullBlockOpt = if (verifyTransactions) Some(chain1block1) else None
- applyBlock(chain1block1) shouldBe 'success
- getBestFullBlockOpt shouldBe expectedBestFullBlockOpt
- getBestHeaderOpt shouldBe Some(chain1block1.header)
-
- val chain2block1 = validFullBlock(parentOpt = None, us, bh)
- applyBlock(chain2block1) shouldBe 'success
- getBestFullBlockOpt shouldBe expectedBestFullBlockOpt
- getBestHeaderOpt shouldBe Some(chain1block1.header)
-
- val wusChain2Block1 = wusGenesis.applyModifier(chain2block1)(mod => nodeViewHolderRef ! mod).get
- val chain2block2 = validFullBlock(Some(chain2block1), wusChain2Block1)
- chain2block1.header.stateRoot shouldEqual wusChain2Block1.rootDigest
-
- applyBlock(chain2block2) shouldBe 'success
- if (verifyTransactions) {
- getBestFullBlockEncodedId shouldBe Some(chain2block2.header.encodedId)
- }
-
- getBestHeaderOpt shouldBe Some(chain2block2.header)
- getRootHash shouldBe Algos.encode(chain2block2.header.stateRoot)
- }
-
- private val t17 = TestCase("apply invalid genesis header") { fixture =>
- import fixture._
- val (us, bh) = createUtxoState(fixture.settings)
- val header = validFullBlock(None, us, bh).header.copy(parentId = bytesToId(Array.fill(32)(9: Byte)))
-
- getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
-
- subscribeEvents(classOf[RecoverableFailedModification])
- subscribeEvents(classOf[SyntacticallySuccessfulModifier])
- subscribeEvents(classOf[SyntacticallyFailedModification])
-
- nodeViewHolderRef ! LocallyGeneratedModifier(header)
- expectMsgType[SyntacticallyFailedModification]
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
- getHeightOf(header.id) shouldBe None
- }
-
- private val t18 = TestCase("apply syntactically invalid genesis block") { fixture =>
- import fixture._
-
- val (us, bh) = createUtxoState(fixture.settings)
-
- val validBlock = validFullBlock(parentOpt = None, us, bh)
- val invalidBlock = validBlock.copy(header = validBlock.header.copy(parentId = bytesToId(Array.fill(32)(9: Byte))))
-
- applyBlock(invalidBlock) shouldBe 'failure
- getBestFullBlockOpt shouldBe None
- getBestHeaderOpt shouldBe None
- }
-
- private val t19 = TestCase("apply semantically invalid genesis block") { fixture =>
- import fixture._
-
- val (us, bh) = createUtxoState(fixture.settings)
- val wusGenesis = WrappedUtxoState(us, bh, fixture.settings, parameters)
-
- val invalidBlock = generateInvalidFullBlock(None, wusGenesis)
-
- if (verifyTransactions) {
-
- val initDigest = getCurrentState.rootDigest
-
- applyBlock(invalidBlock) shouldBe 'success
-
- getBestFullBlockOpt shouldBe None
- getBestHeaderOpt shouldBe None
- getCurrentState.rootDigest shouldEqual initDigest
- }
- }
-
- val cases: List[TestCase] = List(t0, t1, t2, t3, t3a, t4, t5, t6, t7, t8, t9)
-
- NodeViewTestConfig.allConfigs.foreach { c =>
- cases.foreach { t =>
- property(s"${t.name} - $c") {
- t.run(parameters, c)
- }
- }
- }
-
- val verifyingTxCases: List[TestCase] = List(t10, t11, t12, t13)
-
- NodeViewTestConfig.verifyTxConfigs.foreach { c =>
- verifyingTxCases.foreach { t =>
- property(s"${t.name} - $c") {
- t.run(parameters, c)
- }
- }
- }
-
- val genesisIdTestCases = List(t14, t15, t16, t17, t18, t19)
-
- def genesisIdConfig(expectedGenesisIdOpt: Option[ModifierId])(protoSettings: ErgoSettings): ErgoSettings = {
- protoSettings.copy(chainSettings = protoSettings.chainSettings.copy(genesisId = expectedGenesisIdOpt))
- }
-
- genesisIdTestCases.foreach { t =>
- property(t.name) {
- t.run(parameters, NodeViewTestConfig(StateType.Digest, verifyTransactions = true, popowBootstrap = true))
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/viewholder/PrunedNodeViewHolderSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/viewholder/PrunedNodeViewHolderSpec.scala
deleted file mode 100644
index 621a2119dd..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/viewholder/PrunedNodeViewHolderSpec.scala
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.ergoplatform.nodeView.viewholder
-
-import akka.actor.ActorRef
-import org.ergoplatform.mining.DefaultFakePowScheme
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
-import org.ergoplatform.nodeView.state.{DigestState, StateType}
-import org.ergoplatform.settings.{ErgoSettings, VotingSettings}
-import org.ergoplatform.utils.fixtures.NodeViewFixture
-import org.ergoplatform.utils.{ErgoPropertyTest, NodeViewTestOps}
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedModifier
-import scorex.testkit.utils.NoShrink
-
-import scala.concurrent.duration._
-
-/**
- * Test how node view holder is working in pruned mode
- */
-class PrunedNodeViewHolderSpec extends ErgoPropertyTest with NodeViewTestOps with NoShrink {
- private val BlockInterval = 2.minutes
-
- def prunedSettings(blocksToKeep: Int): ErgoSettings = {
- val defaultSettings = ErgoSettings.read()
- defaultSettings.copy(
- chainSettings = defaultSettings.chainSettings.copy(
- powScheme = new DefaultFakePowScheme(defaultSettings.chainSettings.powScheme.k, defaultSettings.chainSettings.powScheme.n),
- voting = VotingSettings(10, 10, 10, 10000, "01"),
- blockInterval = BlockInterval
- ),
- nodeSettings = defaultSettings.nodeSettings.copy(
- stateType = StateType.Digest,
- verifyTransactions = true,
- blocksToKeep = blocksToKeep
- )
- )
- }
-
- def genFullChain(genesisState: WrappedUtxoState, howMany: Int, nodeViewHolderRef: ActorRef): Seq[ErgoFullBlock] = {
- (1 to howMany).foldLeft((Seq[ErgoFullBlock](), genesisState, None: Option[ErgoFullBlock])) { case ((chain, wus, parentOpt), h) =>
- val time = System.currentTimeMillis() - (howMany - h) * (BlockInterval.toMillis * 20)
- val block = validFullBlock(parentOpt, wus, time)
- val newState = wus.applyModifier(block)(mod => nodeViewHolderRef ! mod).get
- (chain :+ block, newState, Some(block))
- }._1
- }
-
- private def testCode(fixture: NodeViewFixture, toSkip: Int, totalBlocks: Int = 20) = {
- import fixture._
-
- val (us, bh) = createUtxoState(fixture.settings)
- val wus = WrappedUtxoState(us, bh, fixture.settings, parameters)
-
- val fullChain = genFullChain(wus, totalBlocks, nodeViewHolderRef)
-
- fullChain.foreach { block =>
- applyHeader(block.header).isSuccess shouldBe true
- }
-
- fullChain.takeRight(totalBlocks - toSkip).foreach { block =>
- block.blockSections.foreach { section =>
- nodeViewHolderRef ! LocallyGeneratedModifier(section)
- Thread.sleep(50)
- }
- }
-
- val state = getCurrentState.asInstanceOf[DigestState]
- state.version shouldBe fullChain.last.id
- state.stateContext.lastHeaderOpt.get.id shouldBe fullChain.last.header.id
- }
-
- property(s"pruned chain bootstrapping - blocksToKeep = -1 - all the blocks are to be applied to the state") {
- new NodeViewFixture(prunedSettings(-1), parameters).apply(f => testCode(f, 0))
- }
-
- property(s"pruned chain bootstrapping - blocksToKeep = 3 - first 9 blocks out of 20 are not to be applied to the state") {
- new NodeViewFixture(prunedSettings(3), parameters).apply(f => testCode(f, 9))
- }
-
- property(s"pruned chain bootstrapping - blocksToKeep = 15 - all the blocks are to be applied to the state") {
- new NodeViewFixture(prunedSettings(15), parameters).apply(f => testCode(f, 0))
- }
-
- property(s"pruned chain bootstrapping - total = 30, blocksToKeep = 15 - first 9 blocks are not to be applied to the state") {
- new NodeViewFixture(prunedSettings(15), parameters).apply(f => testCode(f, 9, 30))
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletServiceSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletServiceSpec.scala
deleted file mode 100644
index c492591ac0..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletServiceSpec.scala
+++ /dev/null
@@ -1,345 +0,0 @@
-package org.ergoplatform.nodeView.wallet
-
-import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, R1}
-import org.ergoplatform._
-import org.ergoplatform.db.DBSpec
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.nodeView.mempool.ErgoMemPoolReader
-import org.ergoplatform.nodeView.wallet.WalletScanLogic.ScanResults
-import org.ergoplatform.nodeView.wallet.persistence.{OffChainRegistry, WalletRegistry, WalletStorage}
-import org.ergoplatform.nodeView.wallet.requests.{AssetIssueRequest, PaymentRequest}
-import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, ScanRequest, ScanWalletInteraction}
-import org.ergoplatform.sdk.wallet.secrets.{DerivationPath, ExtendedSecretKey}
-import org.ergoplatform.settings.ErgoSettings
-import org.ergoplatform.utils.fixtures.WalletFixture
-import org.ergoplatform.utils.generators.ErgoTransactionGenerators
-import org.ergoplatform.utils.{ErgoPropertyTest, MempoolTestHelpers, WalletTestOps}
-import org.ergoplatform.wallet.Constants.{PaymentsScanId, ScanId}
-import org.ergoplatform.wallet.boxes.BoxSelector.BoxSelectionResult
-import org.ergoplatform.wallet.boxes.{ErgoBoxSerializer, ReplaceCompactCollectBoxSelector, TrackedBox}
-import org.ergoplatform.wallet.crypto.ErgoSignature
-import org.ergoplatform.wallet.interface4j.SecretString
-import org.ergoplatform.wallet.mnemonic.Mnemonic
-import org.scalacheck.Gen
-import org.scalatest.BeforeAndAfterAll
-import scorex.db.{LDBKVStore, LDBVersionedStore}
-import scorex.util.encode.Base16
-import sigmastate.Values.{ByteArrayConstant, EvaluatedValue}
-import sigmastate.eval.Extensions.ArrayOps
-import sigmastate.helpers.TestingHelpers.testBox
-import sigmastate.{SType, Values}
-
-import scala.collection.compat.immutable.ArraySeq
-import scala.util.Random
-
-class ErgoWalletServiceSpec
- extends ErgoPropertyTest
- with MempoolTestHelpers
- with WalletTestOps
- with ErgoWalletSupport
- with ErgoTransactionGenerators
- with DBSpec
- with BeforeAndAfterAll {
-
- override val ergoSettings: ErgoSettings = settings
-
- private implicit val x: WalletFixture = new WalletFixture(settings, parameters, getCurrentView(_).vault)
- implicit override val generatorDrivenConfig: PropertyCheckConfiguration = PropertyCheckConfiguration(minSuccessful = 4, sizeRange = 4)
- private lazy val pks = getPublicKeys.toList
- private val masterKey = ExtendedSecretKey.deriveMasterKey(Mnemonic.toSeed(SecretString.create("edge talent poet tortoise trumpet dose")), usePre1627KeyDerivation = false)
-
- override def afterAll(): Unit = try super.afterAll() finally x.stop()
-
- private def initialState(store: LDBKVStore, versionedStore: LDBVersionedStore, mempool: Option[ErgoMemPoolReader] = None) = {
- ErgoWalletState(
- new WalletStorage(store, settings),
- secretStorageOpt = Option.empty,
- new WalletRegistry(versionedStore)(settings.walletSettings),
- OffChainRegistry.empty,
- outputsFilter = Option.empty,
- WalletVars(Some(defaultProver), Seq.empty, None),
- stateReaderOpt = Option.empty,
- mempoolReaderOpt = mempool,
- utxoStateReaderOpt = Option.empty,
- parameters,
- maxInputsToUse = 1000,
- rescanInProgress = false
- )
- }
-
- property("restoring wallet should fail if pruning is enabled") {
- withVersionedStore(2) { versionedStore =>
- withStore { store =>
- val walletState = initialState(store, versionedStore)
- val walletService = new ErgoWalletServiceImpl(settings)
- val settingsWithPruning = settings.copy(nodeSettings = settings.nodeSettings.copy(blocksToKeep = 0))
- walletService.restoreWallet(
- walletState,
- settingsWithPruning,
- mnemonic = SecretString.create("x"),
- mnemonicPassOpt = None,
- walletPass = SecretString.create("y"),
- usePre1627KeyDerivation = false
- ).failed.get.getMessage shouldBe "Unable to restore wallet when pruning is enabled"
- }
- }
- }
-
- property("it should prepare unsigned transaction") {
- val inputBoxes = {
- Seq(
- TrackedBox(
- ErgoLikeTransaction(IndexedSeq(), IndexedSeq()),
- creationOutIndex = 0,
- None,
- testBox(1L, Values.TrueLeaf.toSigmaProp, 0),
- Set(PaymentsScanId)
- )
- )
- }
-
- forAll(ergoBoxCandidateGen, ergoBoxCandidateGen, validErgoTransactionGen, proveDlogGen) {
- case (outputCandidate, outputChangeCandidate, (ergoBoxes, _), proveDlog) =>
- val selectionResult = new BoxSelectionResult(inputBoxes, Seq(outputChangeCandidate), None)
- val tx = prepareUnsignedTransaction(Seq(outputCandidate), startHeight, selectionResult, ergoBoxes, Option(proveDlog)).get
- tx.inputs shouldBe inputBoxes.map(_.box.id).map(id => new UnsignedInput(id))
- tx.dataInputs shouldBe ergoBoxes.map(dataInputBox => DataInput(dataInputBox.id))
- tx.outputCandidates.size shouldBe 2
- tx.outputCandidates.map(_.value).sum shouldBe outputCandidate.value + outputChangeCandidate.value
-
- val txWithChangeBoxesButNoChangeAddress =
- prepareUnsignedTransaction(Seq(outputCandidate), startHeight, selectionResult, ergoBoxes, Option.empty)
- txWithChangeBoxesButNoChangeAddress.isFailure shouldBe true
- }
- }
-
- property("it should generate valid box candidates from payment request") {
- forAll(validErgoTransactionGen) {
- case (ergoBoxes, _) =>
- val paymentRequest = PaymentRequest(pks.head, 1, Seq.empty, Map.empty)
- val paymentCandidates = requestsToBoxCandidates(Seq(paymentRequest), ergoBoxes.head.id, startHeight, parameters, pks).get
- paymentCandidates shouldBe List(new ErgoBoxCandidate(value = 1, ergoTree = pks.head.script, startHeight))
- }
- }
-
- property("it should generate valid box candidates from asset issue requests") {
- forAll(validErgoTransactionGen) {
- case (ergoBoxes, _) =>
- val ergoBox = ergoBoxes.head
-
- val registers: Option[Map[NonMandatoryRegisterId, EvaluatedValue[_ <: SType]]] = Option(Map(ErgoBox.R4 -> sigmastate.Values.FalseLeaf))
- val illegalAssetIssueRequest = AssetIssueRequest(address = pks.head, Some(1), amount = 1, "test", "test", 4, registers)
- val invalidCandidates = requestsToBoxCandidates(Seq(illegalAssetIssueRequest), ergoBox.id, startHeight, parameters, pks)
- invalidCandidates.failed.get.getMessage shouldBe "Additional registers contain R0...R6"
-
- val assetIssueRequestWithoutAddress = AssetIssueRequest(addressOpt = Option.empty, Some(1), amount = 1, "test", "test", 4, Option.empty)
- val missingAddressCandidates = requestsToBoxCandidates(Seq(assetIssueRequestWithoutAddress), ergoBox.id, startHeight, parameters, Seq.empty)
- missingAddressCandidates.failed.get.getMessage shouldBe "No address available for box locking"
-
- val assetIssueRequestWithoutValue = AssetIssueRequest(address = pks.head, valueOpt = Option.empty, amount = 1, "test", "test", 4, Option.empty)
- val missingValueCandidates = requestsToBoxCandidates(Seq(assetIssueRequestWithoutValue), ergoBox.id, startHeight, parameters, Seq.empty).get.head
- missingValueCandidates.value > 0 shouldBe true
-
- val assetIssueRequest = AssetIssueRequest(address = pks.head, Some(1), amount = 1, "test-name", "test-description", 4, Option.empty)
- val validCandidate = requestsToBoxCandidates(Seq(assetIssueRequest), ergoBox.id, startHeight, parameters, Seq.empty).get.head
- validCandidate.value shouldBe 1
- validCandidate.additionalRegisters shouldBe
- Map(
- ErgoBox.R4 -> ByteArrayConstant("test-name".getBytes("UTF-8")),
- ErgoBox.R5 -> ByteArrayConstant("test-description".getBytes("UTF-8")),
- ErgoBox.R6 -> ByteArrayConstant("4".getBytes("UTF-8")),
- )
- validCandidate.additionalTokens.toArray.toMap shouldBe Map(ergoBox.id.toColl -> 1)
- validCandidate.creationHeight shouldBe startHeight
- validCandidate.ergoTree shouldBe pks.head.script
- }
- }
-
- property("it should get scan confirmed and unconfirmed transactions") {
- forAll(Gen.nonEmptyListOf(trackedBoxGen), modifierIdGen) { case (boxes, txId) =>
- withVersionedStore(10) { versionedStore =>
- withStore { store =>
- val allBoxes = {
- val unspentBoxes = boxes.map(bx => bx.copy(spendingHeightOpt = None, spendingTxIdOpt = None, scans = Set(ScanId @@ 0.shortValue())))
- val spentBox = boxes.head.copy(spendingHeightOpt = Some(100), spendingTxIdOpt = Some(txId), scans = Set(ScanId @@ 0.shortValue()))
- unspentBoxes :+ spentBox
- }
- val encodedBoxes = allBoxes.map { box =>
- Base16.encode(ErgoBoxSerializer.toBytes(box.box))
- }
-
- val paymentRequest = PaymentRequest(pks.head, 50000, Seq.empty, Map.empty)
- val boxSelector = new ReplaceCompactCollectBoxSelector(settings.walletSettings.maxInputs, settings.walletSettings.optimalInputs, None)
-
- val walletService = new ErgoWalletServiceImpl(ergoSettings)
- val unconfirmedTx = UnconfirmedTransaction(
- walletService.generateTransaction(
- initialState(store, versionedStore),
- boxSelector,
- Seq(paymentRequest),
- inputsRaw = encodedBoxes,
- dataInputsRaw = Seq.empty,
- sign = true
- ).get.asInstanceOf[ErgoTransaction], None)
-
- // let's create wallet state with an unconfirmed transaction in mempool
- val wState = initialState(store, versionedStore, Some(new FakeMempool(Seq(unconfirmedTx))))
- val signedTx1 =
- walletService.generateTransaction(wState, boxSelector, Seq(paymentRequest), inputsRaw = encodedBoxes, dataInputsRaw = Seq.empty, sign = true)
- .get.asInstanceOf[ErgoTransaction]
- val walletTx1 = WalletTransaction(signedTx1, 100, Seq(ScanId @@ 0.shortValue()))
-
- // let's update wallet registry with a transaction from a block
- val genesisBlock = makeGenesisBlock(pks.head.pubkey, randomNewAsset)
- wState.registry.updateOnBlock(ScanResults(allBoxes, ArraySeq.empty, Seq(walletTx1)), genesisBlock.id, blockHeight = 100).get
-
- // transaction should be retrieved by only a scan id that was associated with it
- val txs1 = walletService.getScanTransactions(wState, ScanId @@ 0.shortValue(), 100)
- assert(txs1.nonEmpty)
- val txs2 = walletService.getScanTransactions(wState, ScanId @@ 1.shortValue(), 100)
- assert(txs2.isEmpty)
-
- // let's test that unconfirmed transaction is retrieved
- val scanId =
- walletService.addScan(wState, ScanRequest("foo", EqualsScanningPredicate(R1, ByteArrayConstant(pks.head.script.bytes)), Some(ScanWalletInteraction.Off), Some(false)))
- .get._1.scanId
-
- val txs3 = walletService.getScanTransactions(wState, scanId, 100, includeUnconfirmed = true)
- txs3.size shouldBe 1
-
- txs3.head.wtx.tx.id shouldBe unconfirmedTx.transaction.id
- }
- }
- }
- }
-
- property("it should get spent and unspent wallet boxes") {
- forAll(Gen.nonEmptyListOf(trackedBoxGen), modifierIdGen) { case (boxes, txId) =>
- withVersionedStore(10) { versionedStore =>
- withStore { store =>
- val wState = initialState(store, versionedStore)
- val blockId = modifierIdGen.sample.get
- val unspentBoxes = boxes.map(bx => bx.copy(spendingHeightOpt = None, spendingTxIdOpt = None, scans = Set(PaymentsScanId)))
- val spentBox = boxes.head.copy(spendingHeightOpt = Some(10000), spendingTxIdOpt = Some(txId), scans = Set(PaymentsScanId))
- val allBoxes = unspentBoxes :+ spentBox
- wState.registry.updateOnBlock(ScanResults(allBoxes, ArraySeq.empty, ArraySeq.empty), blockId, 100).get
-
- val walletService = new ErgoWalletServiceImpl(settings)
- val actualUnspentOnlyWalletBoxes = walletService.getWalletBoxes(wState, unspentOnly = true, considerUnconfirmed = false).toList
- val expectedUnspentOnlyWalletBoxes = unspentBoxes.map(x => WalletBox(x, wState.fullHeight)).sortBy(_.trackedBox.inclusionHeightOpt)
- actualUnspentOnlyWalletBoxes should contain theSameElementsAs expectedUnspentOnlyWalletBoxes
-
- val actualWalletBoxes = walletService.getWalletBoxes(wState, unspentOnly = false, considerUnconfirmed = false).toList
- val expectedWalletBoxes = allBoxes.map(x => WalletBox(x, wState.fullHeight)).sortBy(_.trackedBox.inclusionHeightOpt)
- actualWalletBoxes should contain theSameElementsAs expectedWalletBoxes
- }
- }
- }
- }
-
- property("it should generate signed and unsigned transaction") {
- withVersionedStore(2) { versionedStore =>
- withStore { store =>
- val wState = initialState(store, versionedStore)
-
- val encodedBoxes =
- boxesAvailable(makeGenesisBlock(pks.head.pubkey, randomNewAsset), pks.head.pubkey)
- .map { box =>
- Base16.encode(ErgoBoxSerializer.toBytes(box))
- }
- val paymentRequest = PaymentRequest(pks.head, 50000, Seq.empty, Map.empty)
- val boxSelector = new ReplaceCompactCollectBoxSelector(settings.walletSettings.maxInputs, settings.walletSettings.optimalInputs, None)
-
- val (tx, inputs, dataInputs) = generateUnsignedTransaction(wState, boxSelector, Seq(paymentRequest), inputsRaw = encodedBoxes, dataInputsRaw = Seq.empty).get
- dataInputs shouldBe empty
- inputs.size shouldBe 1
- tx.inputs.size shouldBe 1
- tx.outputs.size shouldBe 2
- tx.outputs.map(_.value).sum shouldBe inputs.map(_.value).sum
-
- val walletService = new ErgoWalletServiceImpl(settings)
- val signedTx = walletService.generateTransaction(wState, boxSelector, Seq(paymentRequest), inputsRaw = encodedBoxes, dataInputsRaw = Seq.empty, sign = true).get.asInstanceOf[ErgoTransaction]
-
- ErgoSignature.verify(signedTx.messageToSign, signedTx.inputs.head.spendingProof.proof, pks.head.pubkey.value) shouldBe true
- signedTx.inputs.size shouldBe 1
- signedTx.outputs.size shouldBe 2
-
- }
- }
- }
-
- property("it should process unlock using preEip3Derivation") {
- withVersionedStore(2) { versionedStore =>
- withStore { store =>
- val walletState = initialState(store, versionedStore)
- val unlockedWalletState = processUnlock(walletState, masterKey, usePreEip3Derivation = true).get
- unlockedWalletState.storage.readAllKeys().size shouldBe 1
- unlockedWalletState.storage.readAllKeys() should contain(masterKey.publicKey)
- unlockedWalletState.walletVars.proverOpt shouldNot be(empty)
- }
- }
- }
-
- property("it should process unlock without preEip3Derivation") {
- withVersionedStore(2) { versionedStore =>
- withStore { store =>
- val walletState = initialState(store, versionedStore)
- val unlockedWalletState = processUnlock(walletState, masterKey, usePreEip3Derivation = false).get
- unlockedWalletState.storage.readAllKeys().size shouldBe 1
- unlockedWalletState.storage.readChangeAddress shouldNot be(empty)
- unlockedWalletState.walletVars.proverOpt shouldNot be(empty)
- }
- }
- }
-
- property("it should lock/unlock wallet") {
- withVersionedStore(2) { versionedStore =>
- withStore { store =>
- val walletState = initialState(store, versionedStore)
- val walletService = new ErgoWalletServiceImpl(settings)
- val pass = Random.nextString(10)
- val initializedState = walletService.initWallet(walletState, settings, SecretString.create(pass), Option.empty).get._2
-
- // Wallet unlocked after init, so we're locking it
- val initLockedWalletState = walletService.lockWallet(initializedState)
- initLockedWalletState.secretStorageOpt.get.isLocked shouldBe true
- initLockedWalletState.walletVars.proverOpt shouldBe empty
-
- val unlockedWalletState = walletService.unlockWallet(initLockedWalletState, SecretString.create(pass), usePreEip3Derivation = true).get
- unlockedWalletState.secretStorageOpt.get.isLocked shouldBe false
- unlockedWalletState.storage.readAllKeys().size shouldBe 1
- unlockedWalletState.walletVars.proverOpt shouldNot be(empty)
-
- val lockedWalletState = walletService.lockWallet(unlockedWalletState)
- lockedWalletState.secretStorageOpt.get.isLocked shouldBe true
- lockedWalletState.walletVars.proverOpt shouldBe empty
-
- val finalUnlockedState = walletService.unlockWallet(lockedWalletState, SecretString.create(pass), usePreEip3Derivation = true).get
- finalUnlockedState.secretStorageOpt.get.isLocked shouldBe false
- finalUnlockedState.storage.readAllKeys().size shouldBe 1
- finalUnlockedState.walletVars.proverOpt shouldNot be(empty)
- }
- }
- }
-
- property("it should derive private key correctly") {
- withVersionedStore(2) { versionedStore =>
- withStore { store =>
-
- val pass = SecretString.create(Random.nextString(10))
- val mnemonic = "edge talent poet tortoise trumpet dose"
-
- val walletService = new ErgoWalletServiceImpl(settings)
- val ws1 = initialState(store, versionedStore)
- val ws2 = walletService.initWallet(ws1, settings, pass, Some(SecretString.create(mnemonic))).get._2
- ws2.secretStorageOpt.get.unlock(pass)
-
- val path = DerivationPath.fromEncoded("m/44/1/1/0/0").get
- val sk = ws2.secretStorageOpt.get.secret.get
- val pk = sk.derive(path).publicKey
-
- walletService.getPrivateKeyFromPath(ws2, pk.path).get.w shouldBe sk.derive(path).privateInput.w
- }
- }
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSpec.scala
deleted file mode 100644
index 5f5967d4d3..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSpec.scala
+++ /dev/null
@@ -1,1123 +0,0 @@
-package org.ergoplatform.nodeView.wallet
-
-import org.ergoplatform._
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction}
-import org.ergoplatform.nodeView.state.{ErgoStateContext, VotingData}
-import org.ergoplatform.nodeView.wallet.IdUtils._
-import org.ergoplatform.nodeView.wallet.persistence.{WalletDigest, WalletDigestSerializer}
-import org.ergoplatform.nodeView.wallet.requests.{AssetIssueRequest, BurnTokensRequest, ExternalSecret, PaymentRequest}
-import org.ergoplatform.sdk.wallet.secrets.PrimitiveSecretKey
-import org.ergoplatform.settings.{Algos, Constants}
-import org.ergoplatform.utils._
-import org.ergoplatform.utils.fixtures.WalletFixture
-import org.ergoplatform.wallet.boxes.BoxSelector.MinBoxValue
-import org.ergoplatform.wallet.boxes.ErgoBoxSerializer
-import org.ergoplatform.wallet.interpreter.{ErgoInterpreter, TransactionHintsBag}
-import org.scalacheck.Gen
-import org.scalatest.concurrent.Eventually
-import scorex.util.ModifierId
-import scorex.util.encode.Base16
-import sigmastate.crypto.DLogProtocol.DLogProverInput
-import sigmastate.eval.Extensions._
-import sigmastate.eval._
-import sigmastate.{CAND, CTHRESHOLD}
-
-import scala.concurrent.duration._
-
-class ErgoWalletSpec extends ErgoPropertyTest with WalletTestOps with Eventually {
-
- private implicit val verifier: ErgoInterpreter = ErgoInterpreter(parameters)
-
- property("assets in WalletDigest are deterministic against serialization") {
- forAll(Gen.listOfN(5, assetGen)) { preAssets =>
- val assets = preAssets.map { case (id, amt) => ModifierId @@ Algos.encode(id) -> amt }
- val wd0 = WalletDigest(1, 0, assets)
- val bs = WalletDigestSerializer.toBytes(wd0)
- WalletDigestSerializer.parseBytes(bs).walletAssetBalances shouldBe wd0.walletAssetBalances
- }
- }
-
- property("do not use inputs spent in off-chain transaction") {
- withFixture { implicit w =>
- val addresses = getPublicKeys
- val pubkey = addresses.head.pubkey
- addresses.length should be > 0
- val genesisBlock = makeGenesisBlock(pubkey, randomNewAsset)
- val genesisTx = genesisBlock.transactions.head
- applyBlock(genesisBlock) shouldBe 'success //scan by wallet happens during apply
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- val tx =
- eventually {
- val snap = getConfirmedBalances
- // prepare a lot of inputs
- val inputsToCreate = 50
- val sumToSpend = (snap.walletBalance - MinBoxValue) / (inputsToCreate + 1)
- val req = (0 until inputsToCreate).map(_ => PaymentRequest(addresses.head, sumToSpend, Seq.empty, Map.empty))
- log.info(s"Confirmed balance $snap")
- log.info(s"Payment request $req")
- val tx = await(wallet.generateTransaction(req)).get
- log.info(s"Generated transaction $tx")
- val context = new ErgoStateContext(Seq(genesisBlock.header), Some(genesisBlock.extension), startDigest, parameters, validationSettingsNoIl, VotingData.empty)
- val boxesToSpend = tx.inputs.map(i => genesisTx.outputs.find(o => java.util.Arrays.equals(o.id, i.boxId)).get)
- tx.statefulValidity(boxesToSpend, emptyDataBoxes, context) shouldBe 'success
- val block = makeNextBlock(getUtxoState, Seq(tx))
- applyBlock(block) shouldBe 'success //scan by wallet happens during apply
- tx
- }
- val (req2, tx2) =
- eventually {
- // generate transaction spending part of inputs
- val newSumToSpend = tx.outputs.head.value
- val req2 = Seq(PaymentRequest(addresses.head, newSumToSpend, Seq.empty, Map.empty))
- log.info(s"Payment requests 2 $req2")
- val tx2 = await(wallet.generateTransaction(req2)).get
- (req2, tx2)
- }
- log.info(s"Generated transaction $tx2")
- wallet.scanOffchain(tx2)
-
- eventually {
- tx2.inputs.size should be < tx.outputs.size
- // trying to create a new transaction
- val tx3 = await(wallet.generateTransaction(req2)).get
- // check that tx3 has inputs different from tx2
- tx3.inputs.foreach { in =>
- tx2.inputs.exists(tx2In => tx2In.boxId sameElements in.boxId) shouldBe false
- }
- }
- }
- }
-
- property("Generate asset issuing transaction") {
- withFixture { implicit w =>
- val address = getPublicKeys.head
- val genesisBlock = makeGenesisBlock(address.pubkey)
- val genesisTx = genesisBlock.transactions.head
- applyBlock(genesisBlock) shouldBe 'success //scan by wallet happens during apply
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 100.millis)
- eventually {
- val availableAmount = getConfirmedBalances.walletBalance
- val emissionAmount: Int = 100000000
- val tokenName: String = "ERG"
- val tokenDescription: String = s"ERG description"
- val tokenDecimals: Int = 9
- val feeAmount = availableAmount / 4
- val feeReq = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), feeAmount, Seq.empty, Map.empty)
- val req = AssetIssueRequest(address, None, emissionAmount, tokenName, tokenDescription, tokenDecimals)
- val tx = await(wallet.generateTransaction(Seq(feeReq, req))).get
- log.info(s"Generated transaction $tx")
- val context = new ErgoStateContext(
- Seq(genesisBlock.header),
- Some(genesisBlock.extension),
- startDigest,
- parameters,
- validationSettingsNoIl,
- VotingData.empty)
- val boxesToSpend = tx.inputs.map(i => genesisTx.outputs.find(o => java.util.Arrays.equals(o.id, i.boxId)).get)
- tx.statefulValidity(boxesToSpend, emptyDataBoxes, context) shouldBe 'success
- }
- }
- }
-
- property("Generate transaction with user-defined input") {
- withFixture { implicit w =>
- val pubKey = getPublicKeys.head.pubkey
- val genesisBlock = makeGenesisBlock(pubKey, randomNewAsset)
- val initialBoxes = boxesAvailable(genesisBlock, pubKey)
-
- val boxesToUseEncoded = initialBoxes.map { box =>
- Base16.encode(ErgoBoxSerializer.toBytes(box))
- }
-
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
-
- //pay out all the wallet balance:
- val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq
- assetToSpend should not be empty
- val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance, assetToSpend, Map.empty)
-
- val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get
- tx1.outputs.size shouldBe 1
- tx1.outputs.head.value shouldBe confirmedBalance
- toAssetMap(tx1.outputs.head.additionalTokens.toArray) shouldBe toAssetMap(assetToSpend)
-
- //change == 1:
- val assetToSpend2 = assetToSpend.map { case (tokenId, tokenValue) => (tokenId, tokenValue - 1) }
- val assetToReturn = assetToSpend.map { case (tokenId, _) => (tokenId, 1L) }
- val req2 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance - MinBoxValue, assetToSpend2, Map.empty)
-
- val tx2 = await(wallet.generateTransaction(Seq(req2))).get
- tx2.outputs.size shouldBe 2
- tx2.outputs.head.value shouldBe confirmedBalance - MinBoxValue
- toAssetMap(tx2.outputs.head.additionalTokens.toArray) shouldBe toAssetMap(assetToSpend2)
- tx2.outputs(1).value shouldBe MinBoxValue
- toAssetMap(tx2.outputs(1).additionalTokens.toArray) shouldBe toAssetMap(assetToReturn)
- }
- }
- }
-
- property("Generate transaction with BurnTokensRequest") {
- withFixture { implicit w =>
- val pubKey = getPublicKeys.head.pubkey
- val genesisBlock = makeGenesisBlock(pubKey, randomNewAsset)
- val initialBoxes = boxesAvailable(genesisBlock, pubKey)
-
- val boxesToUseEncoded = initialBoxes.map { box =>
- Base16.encode(ErgoBoxSerializer.toBytes(box))
- }
-
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
-
- //pay out all the wallet balance:
- val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq
- assetToSpend should not be empty
- val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance, assetToSpend, Map.empty)
-
- val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get
- tx1.outputs.size shouldBe 1
- tx1.outputs.head.value shouldBe confirmedBalance
- toAssetMap(tx1.outputs.head.additionalTokens.toArray) shouldBe toAssetMap(assetToSpend)
-
- //change == 1:
- val assetToSpend2 = assetToSpend.map { case (tokenId, tokenValue) => (tokenId, tokenValue - 1) }
- val assetToReturn = assetToSpend.map { case (tokenId, _) => (tokenId, 1L) }
- val req2 = Seq(BurnTokensRequest(assetToSpend2))
-
- val tx2 = await(wallet.generateTransaction(req2)).get
- tx2.outputs.size shouldBe 1
- tx2.outputs.head.value shouldBe confirmedBalance
- toAssetMap(tx2.outputs.head.additionalTokens.toArray) shouldBe toAssetMap(assetToReturn)
- }
- }
- }
-
- property("Generate transaction with PaymentRequest (no tokens) and BurnTokensRequest") {
- withFixture { implicit w =>
- val pubKey = getPublicKeys.head.pubkey
- val genesisBlock = makeGenesisBlock(pubKey, randomNewAsset)
- val initialBoxes = boxesAvailable(genesisBlock, pubKey)
-
- val boxesToUseEncoded = initialBoxes.map { box =>
- Base16.encode(ErgoBoxSerializer.toBytes(box))
- }
-
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
- log.error(s"Confirmed balance $confirmedBalance")
- //pay out all the wallet balance:
- val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq
- assetToSpend should not be empty
- val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance, assetToSpend, Map.empty)
-
- val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get
- tx1.outputs.size shouldBe 1
- tx1.outputs.head.value shouldBe confirmedBalance
- toAssetMap(tx1.outputs.head.additionalTokens.toArray) shouldBe toAssetMap(assetToSpend)
-
- //change == 1:
- val assetToSpend2 = assetToSpend.map { case (tokenId, tokenValue) => (tokenId, tokenValue - 1) }
- val assetToReturn = assetToSpend.map { case (tokenId, _) => (tokenId, 1L) }
- val req2 = Seq(BurnTokensRequest(assetToSpend2), PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance - MinBoxValue, Seq.empty, Map.empty))
-
- val tx2 = await(wallet.generateTransaction(req2)).get
- tx2.outputs.size shouldBe 2
- tx2.outputs.head.value shouldBe confirmedBalance - MinBoxValue
- toAssetMap(tx2.outputs.head.additionalTokens.toArray) shouldBe toAssetMap(Seq.empty)
- tx2.outputs(1).value shouldBe MinBoxValue
- toAssetMap(tx2.outputs(1).additionalTokens.toArray) shouldBe toAssetMap(assetToReturn)
- }
- }
- }
-
- property("whitelist set, preserve tokens from auto-burn") {
- val inputs = {
- val x = IndexedSeq(new Input(genesisEmissionBox.id, emptyProverResult))
- Seq(encodedTokenId(x.head.boxId.toTokenId))
- }
-
- implicit val ww: WalletFixture = new WalletFixture(settings
- .copy(walletSettings = settings
- .walletSettings.copy(tokensWhitelist = Some(inputs))), parameters, getCurrentView(_).vault)
-
- val pubKey = getPublicKeys.head.pubkey
- val genesisBlock = makeNextBlock(getUtxoState, Seq(makeGenesisTxWithAsset(pubKey, issueAsset = true)))
- val initialBoxes = boxesAvailable(genesisBlock, pubKey)
- val assetR = assetsByTokenId(initialBoxes).toSeq
- Some(assetR.map(x => encodedTokenId(x._1))) shouldBe ww.settings.walletSettings.tokensWhitelist
-
- val boxesToUseEncoded = initialBoxes.map { box =>
- Base16.encode(ErgoBoxSerializer.toBytes(box))
- }
-
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
- log.error(s"Confirmed balance $confirmedBalance")
- //pay out all the wallet balance:
- val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq
- Some(assetToSpend.map(x => encodedTokenId(x._1))) shouldBe ww.settings.walletSettings.tokensWhitelist
- assetToSpend should not be empty
-
- val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance / 2, Seq.empty, Map.empty)
-
- val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get
- tx1.outputs.size shouldBe 2
- tx1.outputs.head.value shouldBe (confirmedBalance / 2)
- tx1.outputs.head.additionalTokens.toArray shouldBe Seq.empty
- toAssetMap(tx1.outputs(1).additionalTokens.toArray) shouldBe toAssetMap(assetToSpend)
- }
- }
-
- property("whitelist empty, auto-burn tokens on arbitrary tx") {
- implicit val ww: WalletFixture = new WalletFixture(settings
- .copy(walletSettings = settings
- .walletSettings.copy(tokensWhitelist = Some(Seq.empty))), parameters, getCurrentView(_).vault)
-
- val pubKey = getPublicKeys.head.pubkey
- val genesisBlock = makeNextBlock(getUtxoState, Seq(makeGenesisTxWithAsset(pubKey, issueAsset = true)))
- val initialBoxes = boxesAvailable(genesisBlock, pubKey)
-
- val boxesToUseEncoded = initialBoxes.map { box =>
- Base16.encode(ErgoBoxSerializer.toBytes(box))
- }
-
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
- log.error(s"Confirmed balance $confirmedBalance")
- //pay out all the wallet balance:
- val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq
- assetToSpend should not be empty
-
- val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance / 2, Seq.empty, Map.empty)
-
- val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get
- tx1.outputs.size shouldBe 2
- tx1.outputs.head.value shouldBe (confirmedBalance / 2)
- tx1.outputs.head.additionalTokens.toArray shouldBe Seq.empty
- toAssetMap(tx1.outputs(1).additionalTokens.toArray) shouldBe toAssetMap(Seq.empty)
- }
- }
-
- property("whitelist not set, ignore auto-burn") {
- implicit val ww: WalletFixture = new WalletFixture(settings
- .copy(walletSettings = settings
- .walletSettings.copy(tokensWhitelist = None)), parameters, getCurrentView(_).vault)
-
- val pubKey = getPublicKeys.head.pubkey
- val genesisBlock = makeNextBlock(getUtxoState, Seq(makeGenesisTxWithAsset(pubKey, issueAsset = true)))
- val initialBoxes = boxesAvailable(genesisBlock, pubKey)
-
- val boxesToUseEncoded = initialBoxes.map { box =>
- Base16.encode(ErgoBoxSerializer.toBytes(box))
- }
-
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
- log.error(s"Confirmed balance $confirmedBalance")
- //pay out all the wallet balance:
- val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq
- assetToSpend should not be empty
-
- val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance / 2, Seq.empty, Map.empty)
-
- val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get
- tx1.outputs.size shouldBe 2
- tx1.outputs.head.value shouldBe (confirmedBalance / 2)
- tx1.outputs.head.additionalTokens.toArray shouldBe Seq.empty
- toAssetMap(tx1.outputs(1).additionalTokens.toArray) shouldBe toAssetMap(assetToSpend)
- }
- }
-
- property("Generate transaction with multiple inputs") {
- withFixture { implicit w =>
- val addresses = getPublicKeys
- val pubkey = addresses.head.pubkey
- addresses.length should be > 0
- val genesisBlock = makeGenesisBlock(pubkey, randomNewAsset)
- val genesisTx = genesisBlock.transactions.head
- val initialBoxes = boxesAvailable(genesisTx, pubkey)
- applyBlock(genesisBlock) shouldBe 'success //scan by wallet happens during apply
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- val (tx, block, assetsToSpend) =
- eventually {
- val snap = getConfirmedBalances
- val assetsToSpend = assetsByTokenId(initialBoxes).toSeq
- assetsToSpend should not be empty
-
- val sumToSpend = snap.walletBalance / (addresses.length + 1)
- val req =
- PaymentRequest(addresses.head, sumToSpend, assetsToSpend, Map.empty) +:
- addresses.tail.map(a => PaymentRequest(a, sumToSpend, Seq.empty, Map.empty))
- log.info(s"Confirmed balance $snap")
- log.info(s"Payment request $req")
- val tx = await(wallet.generateTransaction(req)).get
- log.info(s"Generated transaction $tx")
- val context = new ErgoStateContext(
- Seq(genesisBlock.header),
- Some(genesisBlock.extension),
- startDigest,
- parameters,
- validationSettingsNoIl,
- VotingData.empty)
- val boxesToSpend = tx.inputs.map(i => genesisTx.outputs.find(o => java.util.Arrays.equals(o.id, i.boxId)).get)
- tx.statefulValidity(boxesToSpend, emptyDataBoxes, context) shouldBe 'success
-
- val block = makeNextBlock(getUtxoState, Seq(tx))
- applyBlock(block) shouldBe 'success //scan by wallet happens during apply
- (tx, block, assetsToSpend)
- }
- eventually {
- val newSnap = getConfirmedBalances
- val newSumToSpend = newSnap.walletBalance / addresses.length
- val req2 = PaymentRequest(addresses.head, newSumToSpend, assetsToSpend, Map.empty) +:
- addresses.tail.map(a => PaymentRequest(a, newSumToSpend, Seq.empty, Map.empty))
- log.info(s"New balance $newSnap")
- log.info(s"Payment requests 2 $req2")
- val tx2 = await(wallet.generateTransaction(req2)).get
- log.info(s"Generated transaction $tx2")
- val context2 = new ErgoStateContext(Seq(block.header), Some(block.extension), startDigest, parameters, validationSettingsNoIl, VotingData.empty)
- val knownBoxes = tx.outputs ++ genesisTx.outputs
- val boxesToSpend2 = tx2.inputs.map(i => knownBoxes.find(o => java.util.Arrays.equals(o.id, i.boxId)).get)
- tx2.statefulValidity(boxesToSpend2, emptyDataBoxes, context2) shouldBe 'success
- }
- }
- }
-
- property("off-chain scan") {
- withFixture { implicit w =>
- val pubKey = getPublicKeys.head.script
-
- val bs0 = getBalancesWithUnconfirmed
- bs0.walletBalance shouldBe 0
- bs0.walletAssetBalances shouldBe empty
-
- val balance1 = settings.walletSettings.dustLimit.getOrElse(1000000L) + 1
- val box1 = IndexedSeq(new ErgoBoxCandidate(balance1, pubKey, startHeight, randomNewAsset.toColl))
- wallet.scanOffchain(ErgoTransaction(fakeInputs, box1))
-
- implicit val patienceConfig: PatienceConfig = PatienceConfig(1.second, 100.millis)
- eventually {
- val bs1 = getBalancesWithUnconfirmed
- bs1.walletBalance shouldBe balance1
- bs1.walletAssetBalances shouldBe assetAmount(box1)
- }
-
- val balance2 = settings.walletSettings.dustLimit.getOrElse(1000000L) + 1
- val box2 = IndexedSeq(new ErgoBoxCandidate(balance2, pubKey, startHeight, randomNewAsset.toColl))
- wallet.scanOffchain(ErgoTransaction(fakeInputs, IndexedSeq(), box2))
-
- eventually {
- val bs2 = getBalancesWithUnconfirmed
- bs2.walletBalance shouldBe (balance1 + balance2)
- bs2.walletAssetBalances shouldBe assetAmount(box1 ++ box2)
- }
- }
- }
-
- property("off-chain box spending") {
- withFixture { implicit w =>
- val address = getPublicKeys.head
- val tx = makeGenesisTx(address.pubkey, randomNewAsset)
- wallet.scanOffchain(tx)
- val boxesToSpend = boxesAvailable(tx, address.pubkey)
- val balanceToSpend = balanceAmount(boxesToSpend)
- log.info(s"Balance to spent: $balanceToSpend")
- implicit val patienceConfig: PatienceConfig = PatienceConfig(offchainScanTime(tx).millis, 100.millis)
- val (spendingTx, balanceToReturn, assetsAfterSpending) =
- eventually {
- val totalBalance = getBalancesWithUnconfirmed.walletBalance
- totalBalance shouldEqual balanceToSpend
- log.info(s"Total balance with unconfirmed: $totalBalance")
- val balanceToReturn = randomLong(balanceToSpend)
- val spendingTx = makeSpendingTx(boxesToSpend, address, balanceToReturn, assetsWithRandom(boxesToSpend))
- val assetsAfterSpending = assetAmount(boxesAvailable(spendingTx, address.pubkey))
- assetsAfterSpending should not be empty
- (spendingTx, balanceToReturn, assetsAfterSpending)
- }
- wallet.scanOffchain(spendingTx)
- eventually {
- val totalAfterSpending = getBalancesWithUnconfirmed
-
- log.info(s"Balance to return back: $balanceToReturn")
- totalAfterSpending.walletBalance shouldEqual balanceToReturn
- totalAfterSpending.walletAssetBalances shouldEqual assetsAfterSpending
- }
- }
- }
-
- property("off-chain double registration") {
- withFixture { implicit w =>
- val address = getPublicKeys.head
- val tx = makeGenesisTx(address.pubkey, randomNewAsset)
- wallet.scanOffchain(tx)
- val boxesToSpend = boxesAvailable(tx, address.pubkey)
- val balanceToSpend = balanceAmount(boxesToSpend)
- implicit val patienceConfig: PatienceConfig = PatienceConfig((offchainScanTime(tx) * 3).millis, 100.millis)
- val (spendingTx, totalBalance, balanceToReturn, assets) =
- eventually {
- val totalBalance = getBalancesWithUnconfirmed.walletBalance
-
- val balanceToReturn = randomLong(balanceToSpend)
- val spendingTx = makeSpendingTx(boxesToSpend, address, balanceToReturn, assetsWithRandom(boxesToSpend))
- // val doubleSpendingTx = makeSpendingTx(boxesToSpend, address, randomLong(balanceToSpend))
- val assets = assetAmount(boxesAvailable(spendingTx, address.pubkey))
- assets should not be empty
- (spendingTx, totalBalance, balanceToReturn, assets)
- }
- wallet.scanOffchain(Seq(spendingTx, spendingTx))
- wallet.scanOffchain(spendingTx)
-
- log.info(s"Total with unconfirmed balance: $totalBalance")
- log.info(s"Balance to spent: $balanceToSpend")
- log.info(s"Balance to return back: $balanceToReturn")
- eventually {
- val totalAfterSpending = getBalancesWithUnconfirmed
- totalBalance shouldEqual balanceToSpend
- totalAfterSpending.walletBalance shouldEqual balanceToReturn
- totalAfterSpending.walletAssetBalances shouldEqual assets
- }
- }
- }
-
- property("off-chain spending of the on-chain box") {
- withFixture { implicit w =>
- val address = getPublicKeys.head
- val genesisBlock = makeGenesisBlock(address.pubkey, randomNewAsset)
- val boxesToSpend = boxesAvailable(genesisBlock, address.pubkey)
- val sumBalance = balanceAmount(boxesToSpend)
- log.info(s"Sum balance: $sumBalance")
- val balanceToReturn = randomLong(sumBalance)
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- val (spendingTx, assets) =
- eventually {
- val totalBalance = getBalancesWithUnconfirmed.walletBalance
- val confirmedBalance = getConfirmedBalances.walletBalance
-
- val spendingTx = makeSpendingTx(boxesToSpend, address, balanceToReturn, assetsWithRandom(boxesToSpend))
- val assets = assetAmount(boxesAvailable(spendingTx, address.pubkey))
- assets should not be empty
- confirmedBalance shouldBe sumBalance
- totalBalance shouldBe sumBalance
- log.info(s"Balance before spending: $confirmedBalance")
- log.info(s"Total with unconfirmed balance before spending: $totalBalance")
- (spendingTx, assets)
- }
- wallet.scanOffchain(spendingTx)
- eventually {
- val confirmedAfterSpending = getConfirmedBalances.walletBalance
- val totalAfterSpending = getBalancesWithUnconfirmed
-
- log.info(s"Balance after spending: $confirmedAfterSpending")
- log.info(s"Total with unconfirmed after spending: $totalAfterSpending")
-
- confirmedAfterSpending shouldBe sumBalance
- totalAfterSpending.walletBalance shouldBe balanceToReturn
- totalAfterSpending.walletAssetBalances shouldBe assets
- }
- }
- }
-
- property("assets application") {
- withFixture { implicit w =>
- val address = getPublicKeys.head
- val asset1Sum = randomLong()
- val genesisBlock = makeGenesisBlock(address.pubkey, Seq(newAssetIdStub -> asset1Sum))
- val boxesToSpend = boxesAvailable(genesisBlock, address.pubkey)
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- val (asset1Token, asset1ToReturn, asset2Sum, spendingBlock) =
- eventually {
- val initialBalance = getConfirmedBalances
- val initialTotal = getBalancesWithUnconfirmed
- val initialAssets = initialBalance.walletAssetBalances
- log.info(s"Initial assets: ${boxesToSpend.flatMap(_.additionalTokens.toArray)}")
- log.info(s"Confirmed: $initialBalance")
- log.info(s"With unconfirmed: $initialTotal")
- initialAssets should not be empty
- val (asset1Token, asset1InitialValue) = initialAssets.head
- asset1InitialValue shouldBe asset1Sum
- initialTotal.walletAssetBalances shouldBe initialAssets
-
- val asset2Sum = randomLong()
- val asset1ToReturn = randomLong(asset1Sum)
- val assets2Seq = Seq(decodedTokenId(asset1Token) -> asset1ToReturn, newAssetIdStub -> asset2Sum)
- val balanceToReturn = 1000 * parameters.minValuePerByte
- val spendingTx = makeSpendingTx(boxesToSpend, address, balanceToReturn, assets2Seq)
- val spendingBlock = makeNextBlock(getUtxoState, Seq(spendingTx))
- applyBlock(spendingBlock) shouldBe 'success
- (asset1Token, asset1ToReturn, asset2Sum, spendingBlock)
- }
- wallet.scanPersistent(spendingBlock)
- eventually {
- val balanceAfterSpending = getConfirmedBalances
- val totalAfterSpending = getBalancesWithUnconfirmed
- log.info(s"After spending: $balanceAfterSpending")
- log.info(s"With unconfirmed after spending: $balanceAfterSpending")
- val assets = balanceAfterSpending.walletAssetBalances
- totalAfterSpending.walletAssetBalances.toMap shouldBe assets.toMap
- assets.find(_._1 == asset1Token).get._2 shouldBe asset1ToReturn
- val asset2 = assets.filter(_._1 != asset1Token)
- asset2 should not be empty
- asset2.head._2 shouldBe asset2Sum
- }
- }
- }
-
- property("on-chain box spending (without return)") {
- withFixture { implicit w =>
- val address = getPublicKeys.head
- val genesisBlock = makeGenesisBlock(address.pubkey, randomNewAsset)
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- val (spendingBlock, boxesToSpend, confirmedBalance, balanceToSpend) =
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
- val boxesToSpend = boxesAvailable(genesisBlock, address.pubkey)
- val balanceToSpend = balanceAmount(boxesToSpend)
- log.info(s"Confirmed balance $confirmedBalance")
- log.info(s"Sum balance: $balanceToSpend")
- confirmedBalance should be > 0L
- confirmedBalance shouldBe balanceToSpend
-
- val spendingTx = makeSpendingTx(boxesToSpend, address, 0, assetsWithRandom(boxesToSpend))
-
- val spendingBlock = makeNextBlock(getUtxoState, Seq(spendingTx))
- applyBlock(spendingBlock) shouldBe 'success
- (spendingBlock, boxesToSpend, confirmedBalance, balanceToSpend)
- }
- wallet.scanPersistent(spendingBlock)
- eventually {
- val balanceAfterSpending = getConfirmedBalances
- log.info(s"Boxes to spend: $boxesToSpend")
- log.info(s"Total with unconfirmed balance: $confirmedBalance")
- log.info(s"Balance to spent: $balanceToSpend")
- log.info(s"Balance after spend: ${balanceAfterSpending.walletBalance}")
- balanceAfterSpending.walletBalance shouldEqual 0
- getBalancesWithUnconfirmed shouldEqual balanceAfterSpending
- }
- }
- }
-
- property("on-chain box spending (with return)") {
- withFixture { implicit w =>
- val address = getPublicKeys.head
- val genesisBlock = makeGenesisBlock(address.pubkey, randomNewAsset)
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 300.millis)
- val (confirmedBalance, balanceToSpend, balanceToReturn, assets, spendingBlock) =
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
- val boxesToSpend = boxesAvailable(genesisBlock, address.pubkey)
- val balanceToSpend = balanceAmount(boxesToSpend)
- log.info(s"Boxes to spend: $boxesToSpend")
- log.info(s"Confirmed balance $confirmedBalance")
- log.info(s"Sum balance: $balanceToSpend")
- confirmedBalance should be > 0L
- confirmedBalance shouldBe balanceToSpend
-
- val balanceToReturn = randomLong(balanceToSpend)
- val spendingTx = makeSpendingTx(boxesToSpend, address, balanceToReturn, assetsWithRandom(boxesToSpend))
- val assets = assetAmount(boxesAvailable(spendingTx, address.pubkey))
- assets should not be empty
- val spendingBlock = makeNextBlock(getUtxoState, Seq(spendingTx))
- applyBlock(spendingBlock) shouldBe 'success
- (confirmedBalance, balanceToSpend, balanceToReturn, assets, spendingBlock)
- }
- wallet.scanPersistent(spendingBlock)
- eventually {
- val balanceAfterSpending = getConfirmedBalances
- log.info(s"Total with unconfirmed balance: $confirmedBalance")
- log.info(s"Balance to spent: $balanceToSpend")
- log.info(s"Balance to return back: $balanceToReturn")
- balanceAfterSpending.walletBalance shouldEqual (confirmedBalance - balanceToSpend + balanceToReturn)
- balanceAfterSpending.walletAssetBalances.toMap shouldBe assets.toMap
-
- getBalancesWithUnconfirmed.height shouldEqual balanceAfterSpending.height
- getBalancesWithUnconfirmed.walletBalance shouldEqual balanceAfterSpending.walletBalance
- getBalancesWithUnconfirmed.walletAssetBalances.toMap shouldEqual balanceAfterSpending.walletAssetBalances.toMap
- }
- }
- }
-
- property("off-chain transaction becomes on-chain") {
- withFixture { implicit w =>
- val pubKey = getPublicKeys.head.pubkey
- val tx = makeGenesisTx(pubKey, randomNewAsset)
- wallet.scanOffchain(tx)
- implicit val patienceConfig: PatienceConfig = PatienceConfig(offchainScanTime(tx).millis, 100.millis)
- val (initialBalance, sumBalance, sumAssets) =
- eventually {
- val boxesToSpend = boxesAvailable(tx, pubKey)
- val sumBalance = balanceAmount(boxesToSpend)
- val sumAssets = assetAmount(boxesToSpend)
- sumAssets should not be empty
-
- val initialBalance = getBalancesWithUnconfirmed.walletBalance
- initialBalance shouldBe sumBalance
-
- val block = makeNextBlock(getUtxoState, Seq(tx))
- applyBlock(block) shouldBe 'success
- (initialBalance, sumBalance, sumAssets)
- }
-
- eventually {
- val confirmedBalance = getConfirmedBalances
- log.info(s"Confirmed balance $confirmedBalance")
- log.info(s"Sum balance: $sumBalance")
- initialBalance shouldBe sumBalance
- confirmedBalance.walletBalance should be > 0L
- confirmedBalance.walletBalance shouldBe initialBalance
- confirmedBalance.walletAssetBalances shouldBe sumAssets
- getBalancesWithUnconfirmed shouldBe confirmedBalance
- }
-
- }
- }
-
- property("off-chain spending rollback") {
- withFixture { implicit w =>
- val address = getPublicKeys.head
- val genesisBlock = makeGenesisBlock(address.pubkey)
- val initialBoxes = boxesAvailable(genesisBlock, address.pubkey)
- val initialBalance = balanceAmount(initialBoxes)
- applyBlock(genesisBlock) shouldBe 'success
- val initialState = getCurrentState
-
- // We need this second block to have something to rollback. Just spent some balance to anyone
- val balanceToSpend = randomLong(initialBalance)
- val onchainSpendingTx = makeTx(initialBoxes, emptyProverResult, balanceToSpend, address.pubkey)
- val boxesToSpend = boxesAvailable(onchainSpendingTx, address.pubkey)
- val block = makeNextBlock(getUtxoState, Seq(onchainSpendingTx))
- applyBlock(block) shouldBe 'success
- wallet.scanPersistent(block)
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.seconds, 100.millis)
- val confirmedBalance =
- eventually {
- val totalBalance = getBalancesWithUnconfirmed.walletBalance
- val confirmedBalance = getConfirmedBalances.walletBalance
-
- confirmedBalance shouldBe balanceToSpend
- totalBalance shouldBe confirmedBalance
- log.info(s"Initial balance: $initialBalance")
- log.info(s"Balance before off-chain spending: $confirmedBalance")
- log.info(s"Total with unconfirmed balance before spending: $totalBalance")
- confirmedBalance
- }
-
- val balanceToReturn = randomLong(balanceAmount(boxesToSpend))
- val spendingTx = makeSpendingTx(boxesToSpend, address, balanceToReturn)
- wallet.scanOffchain(spendingTx)
-
- eventually {
- val confirmedAfterSpending = getConfirmedBalances.walletBalance
- val totalAfterSpending = getBalancesWithUnconfirmed.walletBalance
-
- confirmedAfterSpending shouldBe confirmedBalance
- totalAfterSpending shouldBe balanceToReturn
-
- log.info(s"After spending before rollback: $confirmedAfterSpending")
- log.info(s"Total with unconfirmed balance after spending before rollback: $totalAfterSpending")
- }
-
- wallet.rollback(initialState.version)
- eventually {
- val balanceAfterRollback = getConfirmedBalances.walletBalance
- val totalAfterRollback = getBalancesWithUnconfirmed.walletBalance
-
- log.info(s"Balance after rollback: $balanceAfterRollback")
- log.info(s"Total with unconfirmed balance after rollback: $totalAfterRollback")
-
- balanceAfterRollback shouldBe initialBalance
- totalAfterRollback shouldBe balanceToReturn
- }
- }
- }
-
- property("on-chain rollback") {
- withFixture { implicit w =>
- val pubKey = getPublicKeys.head.pubkey
- val genesisBlock = makeGenesisBlock(pubKey)
- val boxesToSpend = boxesAvailable(genesisBlock, pubKey)
- applyBlock(genesisBlock) shouldBe 'success
- val initialState = getCurrentState
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.seconds, 100.millis)
- val (initialBalance, creationTx, initialAssets, balanceToSpend) =
- eventually {
- val initialBalance = getConfirmedBalances.walletBalance
- val balanceToSpend = randomLong(balanceAmount(boxesToSpend))
- val creationTx = makeTx(boxesToSpend, emptyProverResult, balanceToSpend, pubKey, randomNewAsset)
- val initialAssets = assetAmount(boxesAvailable(creationTx, pubKey))
- initialAssets should not be empty
- log.info(s"Initial balance: $initialBalance")
- log.info(s"Initial assets: $initialAssets")
- (initialBalance, creationTx, initialAssets, balanceToSpend)
- }
-
- val block = makeNextBlock(getUtxoState, Seq(creationTx))
- wallet.scanPersistent(block)
- eventually {
- val historyHeight = getHistory.headersHeight
-
- val confirmedBeforeRollback: WalletDigest = getConfirmedBalances
- val totalBeforeRollback = getBalancesWithUnconfirmed
- log.info(s"History height: $historyHeight")
- log.info(s"Confirmed balance: $confirmedBeforeRollback")
- log.info(s"Total with unconfirmed balance: $totalBeforeRollback")
-
- confirmedBeforeRollback.walletBalance shouldBe balanceToSpend
- confirmedBeforeRollback.walletAssetBalances shouldBe initialAssets
- totalBeforeRollback shouldBe confirmedBeforeRollback
- }
- wallet.rollback(initialState.version)
- eventually {
- val confirmedAfterRollback = getConfirmedBalances
- val totalAfterRollback = getBalancesWithUnconfirmed
-
- log.info(s"Balance after rollback: $confirmedAfterRollback")
- log.info(s"Total with unconfirmed balance after rollback: $totalAfterRollback")
-
- confirmedAfterRollback.walletBalance shouldBe initialBalance
- confirmedAfterRollback.walletAssetBalances shouldBe empty
- totalAfterRollback.walletBalance shouldBe balanceToSpend
- totalAfterRollback.walletAssetBalances shouldBe initialAssets
- }
- }
- }
-
- property("on-chain spending rollback") {
- withFixture { implicit w =>
- val address = getPublicKeys.head
- val genesisBlock = makeGenesisBlock(address.pubkey, randomNewAsset)
- val boxesToSpend = boxesAvailable(genesisBlock, address.pubkey)
- val sumBalance = balanceAmount(boxesToSpend)
- val sumAssets = assetAmount(boxesToSpend)
- sumAssets should not be empty
-
- applyBlock(genesisBlock) shouldBe 'success
- val initialState = getCurrentState
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.second, 100.millis)
- val (block, initialSnapshot) =
- eventually {
- val initialSnapshot = getConfirmedBalances
- log.info(s"Initial balance: $initialSnapshot")
- val spendingTx = makeSpendingTx(boxesToSpend, address)
- val block = makeNextBlock(getUtxoState, Seq(spendingTx))
- initialSnapshot.walletBalance shouldBe sumBalance
- initialSnapshot.walletAssetBalances shouldBe sumAssets
- (block, initialSnapshot)
- }
- wallet.scanPersistent(block)
-
- val confirmedBeforeRollback =
- eventually {
- val historyHeight = getHistory.headersHeight
-
- val confirmedBeforeRollback = getConfirmedBalances
- val totalBeforeRollback = getBalancesWithUnconfirmed
-
- log.info(s"Balance to spend: $sumBalance")
- log.info(s"History height: $historyHeight")
- log.info(s"Confirmed balance: $confirmedBeforeRollback")
- log.info(s"Total with unconfirmed balance: $totalBeforeRollback")
-
- confirmedBeforeRollback.walletBalance shouldBe 0L
- confirmedBeforeRollback.walletAssetBalances shouldBe empty
- totalBeforeRollback shouldBe confirmedBeforeRollback
- confirmedBeforeRollback
- }
-
- wallet.rollback(initialState.version)
- eventually {
- val confirmedAfterRollback = getConfirmedBalances
- val totalAfterRollback = getBalancesWithUnconfirmed
- log.info(s"Balance after rollback: $confirmedAfterRollback")
- log.info(s"Total with unconfirmed balance after rollback: $totalAfterRollback")
-
- confirmedAfterRollback shouldBe initialSnapshot
- totalAfterRollback.walletBalance shouldBe confirmedBeforeRollback.walletBalance
- totalAfterRollback.walletAssetBalances shouldBe confirmedBeforeRollback.walletAssetBalances
- }
- }
- }
-
- property("on-chain spending with return rollback") {
- withFixture { implicit w =>
- val address = getPublicKeys.head
- val genesisBlock = makeGenesisBlock(address.pubkey, randomNewAsset)
- val boxesToSpend = boxesAvailable(genesisBlock, address.pubkey)
- val sumBalance = balanceAmount(boxesToSpend)
-
- applyBlock(genesisBlock) shouldBe 'success
- val initialState = getCurrentState
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.seconds, 100.millis)
- val (block, initialSnapshot, asset1Map, balanceToReturn) =
- eventually {
- val initialSnapshot = getConfirmedBalances
-
- val balanceToReturn = randomLong(sumBalance)
- val sumAsset1 = assetsByTokenId(boxesToSpend).toSeq
- sumAsset1 should not be empty
-
- val asset1Map = toAssetMap(sumAsset1)
- val assetToReturn = sumAsset1.map { case (tokenId, tokenValue) => (tokenId, randomLong(tokenValue)) }
- val assetsForSpending = randomNewAsset ++ assetToReturn
- val spendingTx = makeSpendingTx(boxesToSpend, address, balanceToReturn, assetsForSpending)
- val block = makeNextBlock(getUtxoState, Seq(spendingTx))
- log.info(s"Initial balance: $initialSnapshot")
- log.info(s"Balance to spend: $sumBalance")
- log.info(s"Balance to return $balanceToReturn")
- initialSnapshot.walletBalance shouldBe sumBalance
- initialSnapshot.walletAssetBalances.toMap shouldBe asset1Map
- (block, initialSnapshot, asset1Map, balanceToReturn)
- }
- wallet.scanPersistent(block)
-
- val totalBeforeRollback =
- eventually {
- val historyHeight = getHistory.headersHeight
- val confirmedBeforeRollback = getConfirmedBalances
- val totalBeforeRollback = getBalancesWithUnconfirmed
- log.info(s"History height: $historyHeight")
- log.info(s"Confirmed balance: $confirmedBeforeRollback")
- log.info(s"Total with unconfirmed balance: $totalBeforeRollback")
- confirmedBeforeRollback.walletBalance should be > 0L
- confirmedBeforeRollback.walletBalance shouldBe balanceToReturn
- confirmedBeforeRollback.walletAssetBalances should have size 2
- totalBeforeRollback.walletBalance shouldBe balanceToReturn
- totalBeforeRollback.walletAssetBalances.toMap shouldBe confirmedBeforeRollback.walletAssetBalances.toMap
- totalBeforeRollback
- }
- wallet.rollback(initialState.version)
-
- eventually {
- val confirmedAfterRollback = getConfirmedBalances
- val totalAfterRollback = getBalancesWithUnconfirmed
- log.info(s"Balance after rollback: $confirmedAfterRollback")
- log.info(s"Total with unconfirmed balance after rollback: $totalAfterRollback")
- confirmedAfterRollback shouldBe initialSnapshot
- confirmedAfterRollback.walletAssetBalances.toMap shouldBe asset1Map
- totalAfterRollback.walletBalance shouldBe balanceToReturn
- totalAfterRollback.walletAssetBalances shouldBe totalBeforeRollback.walletAssetBalances
- }
- }
- }
-
- property("on-chain spent box to off-chain box rollback") {
- withFixture { implicit w =>
- val address = getPublicKeys.head
- val genesisBlock = makeGenesisBlock(address.pubkey)
- val initialBoxes = boxesAvailable(genesisBlock, address.pubkey)
- applyBlock(genesisBlock) shouldBe 'success
- val initialState = getCurrentState
- val initialBalance = balanceAmount(initialBoxes)
-
- val balancePicked = randomLong(initialBalance)
- val creationTx = makeTx(initialBoxes, emptyProverResult, balancePicked, address.pubkey, randomNewAsset)
- val boxesToSpend = boxesAvailable(creationTx, address.pubkey)
- val balanceToSpend = balanceAmount(boxesToSpend)
-
- log.info(s"Initial balance: $initialBalance")
- log.info(s"Balance to spend: $balanceToSpend")
- balanceToSpend shouldBe balancePicked
-
- val balanceToReturn = randomLong(balanceToSpend)
- val sumAsset1 = assetsByTokenId(boxesToSpend).toSeq
- sumAsset1 should not be empty
-
- val assetToReturn = sumAsset1.map { case (tokenId, tokenValue) => (tokenId, randomLong(tokenValue)) }
- val assetsForSpending = randomNewAsset ++ assetToReturn
- val spendingTx = makeSpendingTx(boxesToSpend, address, balanceToReturn, assetsForSpending)
- val block = makeNextBlock(getUtxoState, Seq(creationTx, spendingTx))
- wallet.scanPersistent(block)
-
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.seconds, 100.millis)
- val totalBeforeRollback =
- eventually {
- val historyHeight = getHistory.headersHeight
-
- val confirmedBeforeRollback = getConfirmedBalances
- val totalBeforeRollback = getBalancesWithUnconfirmed
- log.info(s"History height: $historyHeight")
- log.info(s"Confirmed balance: $confirmedBeforeRollback")
- log.info(s"Total with unconfirmed balance: $totalBeforeRollback")
-
- confirmedBeforeRollback.walletBalance shouldBe balanceToReturn
- confirmedBeforeRollback.walletAssetBalances should have size 2
-
- totalBeforeRollback.walletBalance shouldBe confirmedBeforeRollback.walletBalance
- totalBeforeRollback.walletAssetBalances.toMap shouldBe confirmedBeforeRollback.walletAssetBalances.toMap
- totalBeforeRollback
- }
- wallet.rollback(initialState.version)
-
- eventually {
- val confirmedAfterRollback = getConfirmedBalances
- val totalAfterRollback = getBalancesWithUnconfirmed
-
- log.info(s"Balance after rollback: $confirmedAfterRollback")
- log.info(s"Total with unconfirmed balance after rollback: $totalAfterRollback")
-
- confirmedAfterRollback.walletBalance shouldBe initialBalance
- totalAfterRollback.walletBalance shouldBe balanceToReturn
- totalAfterRollback.walletAssetBalances shouldBe totalBeforeRollback.walletAssetBalances
- }
- }
- }
-
- property("single-input transaction generation") {
- withFixture { implicit w =>
- val pubKey = getPublicKeys.head.pubkey
- val genesisBlock = makeGenesisBlock(pubKey, randomNewAsset)
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.seconds, 100.millis)
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
-
- //pay out all the wallet balance:
- val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq
- assetToSpend should not be empty
- val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance, assetToSpend, Map.empty)
-
- val tx1 = await(wallet.generateTransaction(Seq(req1))).get
- tx1.outputs.size shouldBe 1
- tx1.outputs.head.value shouldBe confirmedBalance
- toAssetMap(tx1.outputs.head.additionalTokens.toArray) shouldBe toAssetMap(assetToSpend)
-
- //change == 1:
- val assetToSpend2 = assetToSpend.map { case (tokenId, tokenValue) => (tokenId, tokenValue - 1) }
- val assetToReturn = assetToSpend.map { case (tokenId, _) => (tokenId, 1L) }
- val req2 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance - MinBoxValue, assetToSpend2, Map.empty)
-
- val tx2 = await(wallet.generateTransaction(Seq(req2))).get
- tx2.outputs.size shouldBe 2
- tx2.outputs.head.value shouldBe confirmedBalance - MinBoxValue
- toAssetMap(tx2.outputs.head.additionalTokens.toArray) shouldBe toAssetMap(assetToSpend2)
- tx2.outputs(1).value shouldBe MinBoxValue
- toAssetMap(tx2.outputs(1).additionalTokens.toArray) shouldBe toAssetMap(assetToReturn)
- }
- }
- }
-
- property("generate unsigned transaction + sign (single input)") {
- withFixture { implicit w =>
- val pubKey = getPublicKeys.head.pubkey
- val genesisBlock = makeGenesisBlock(pubKey, randomNewAsset)
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.seconds, 100.millis)
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
-
- //pay out all the wallet balance:
- val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq
- assetToSpend should not be empty
- val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance, assetToSpend, Map.empty)
-
- val utx = await(wallet.generateUnsignedTransaction(Seq(req1))).get
- utx.outputs.size shouldBe 1
- utx.outputs.head.value shouldBe confirmedBalance
- toAssetMap(utx.outputs.head.additionalTokens.toArray) shouldBe toAssetMap(assetToSpend)
-
- val tx = await(wallet.signTransaction(utx, Seq.empty, TransactionHintsBag.empty, None, None)).get
- tx.id shouldBe utx.id // signing preserves transaction id
- }
- }
- }
-
- property("co-signing (external secrets) - 2-out-of-2") {
- withFixture { implicit w =>
-
- val secret1 = DLogProverInput.random()
- val es1 = ExternalSecret(PrimitiveSecretKey(secret1))
-
- val secret2 = DLogProverInput.random()
- val es2 = ExternalSecret(PrimitiveSecretKey(secret2))
-
- val pubKey = getPublicKeys.head.pubkey
- val genesisBlock = makeGenesisBlock(pubKey, randomNewAsset)
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.seconds, 100.millis)
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
-
- //pay out all the wallet balance:
- val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq
- assetToSpend should not be empty
- val req1 = PaymentRequest(Pay2SAddress(CAND(Seq(secret1.publicImage, secret2.publicImage))), confirmedBalance, assetToSpend, Map.empty)
-
- val tx = await(wallet.generateTransaction(Seq(req1))).get
-
- val in = tx.outputs.head
-
- val utx = new UnsignedErgoTransaction(IndexedSeq(new UnsignedInput(in.id)), IndexedSeq.empty, IndexedSeq(in.toCandidate))
-
- val hints1 = await(wallet.generateCommitmentsFor(utx, Some(Seq(es1)), Some(Seq(in)), None)).response.get
-
- val txSigned = await(wallet.signTransaction(utx, Seq(es2), hints1, Some(Seq(in)), None)).get
-
- txSigned.statelessValidity().isSuccess shouldBe true
- }
- }
- }
-
- property("co-signing (external secrets) - 2-out-of-3") {
- withFixture { implicit w =>
- val secret1 = DLogProverInput.random()
- val es1 = ExternalSecret(PrimitiveSecretKey(secret1))
-
- val secret2 = DLogProverInput.random()
- val es2 = ExternalSecret(PrimitiveSecretKey(secret2))
-
- val secret3 = DLogProverInput.random()
-
- val pubKey = getPublicKeys.head.pubkey
- val genesisBlock = makeGenesisBlock(pubKey, randomNewAsset)
- applyBlock(genesisBlock) shouldBe 'success
- implicit val patienceConfig: PatienceConfig = PatienceConfig(5.seconds, 100.millis)
- eventually {
- val confirmedBalance = getConfirmedBalances.walletBalance
-
- //pay out all the wallet balance:
- val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq
- assetToSpend should not be empty
- val addr = Pay2SAddress(CTHRESHOLD(2, Seq(secret1.publicImage, secret2.publicImage, secret3.publicImage)))
- val req1 = PaymentRequest(addr, confirmedBalance, assetToSpend, Map.empty)
-
- val tx = await(wallet.generateTransaction(Seq(req1))).get
-
- val in = tx.outputs.head
-
- // secret1 and secret2 are signing
- val utx = new UnsignedErgoTransaction(IndexedSeq(new UnsignedInput(in.id)), IndexedSeq.empty, IndexedSeq(in.toCandidate))
-
- val cmts1 = await(wallet.generateCommitmentsFor(utx, Some(Seq(es1)), Some(Seq(in)), None)).response.get
-
- val pubCmts1 = TransactionHintsBag(cmts1.publicHints)
-
- val ptx = await(wallet.signTransaction(utx, Seq(es2), pubCmts1, Some(Seq(in)), None)).get
-
- val eh = wallet.extractHints(ptx, Seq(secret1.publicImage, secret2.publicImage), Seq(secret3.publicImage), Some(Seq(in)), None)
- val hintsExtracted = await(eh).transactionHintsBag
-
- val hints = hintsExtracted.addHintsForInput(0, cmts1.allHintsForInput(0))
-
- val txSigned = await(wallet.signTransaction(utx, Seq(es1), hints, Some(Seq(in)), None)).get
- txSigned.statelessValidity().isSuccess shouldBe true
- }
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/WalletProfileSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/WalletProfileSpec.scala
deleted file mode 100644
index caf1103277..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/WalletProfileSpec.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.ergoplatform.nodeView.wallet
-
-import org.ergoplatform.utils.ErgoPropertyTest
-
-import scala.util.Try
-
-class WalletProfileSpec extends ErgoPropertyTest {
- property("fromLabel getting profiles properly") {
- WalletProfile.fromLabel("user").outputsFilterSize shouldBe WalletProfile.User.outputsFilterSize
- WalletProfile.fromLabel("user").scriptsFilterSize shouldBe WalletProfile.User.scriptsFilterSize
-
- WalletProfile.fromLabel("exchange").scriptsFilterSize should not be WalletProfile.User.scriptsFilterSize
- WalletProfile.fromLabel("exchange").outputsFilterSize shouldBe WalletProfile.Exchange.outputsFilterSize
- WalletProfile.fromLabel("exchange").scriptsFilterSize shouldBe WalletProfile.Exchange.scriptsFilterSize
-
- Try(WalletProfile.fromLabel("appserver")).isFailure shouldBe true
- WalletProfile.fromLabel("appServer").outputsFilterSize shouldBe WalletProfile.AppServer.outputsFilterSize
- WalletProfile.fromLabel("appServer").scriptsFilterSize shouldBe WalletProfile.AppServer.scriptsFilterSize
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/WalletScanLogicSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/WalletScanLogicSpec.scala
deleted file mode 100644
index fb6d72e266..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/WalletScanLogicSpec.scala
+++ /dev/null
@@ -1,282 +0,0 @@
-package org.ergoplatform.nodeView.wallet
-
-import org.ergoplatform.utils.{ErgoPropertyTest, WalletTestOps}
-import WalletScanLogic.{extractWalletOutputs, scanBlockTransactions}
-import org.ergoplatform.db.DBSpec
-import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, Input}
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.nodeView.wallet.persistence.{OffChainRegistry, WalletRegistry}
-import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, ScanRequest, ScanWalletInteraction}
-import org.ergoplatform.wallet.Constants
-import org.ergoplatform.wallet.Constants.ScanId
-import org.scalacheck.Gen
-import sigmastate.Values.{ByteArrayConstant, ErgoTree, FalseLeaf, TrueLeaf}
-
-import scala.util.Random
-
-class WalletScanLogicSpec extends ErgoPropertyTest with DBSpec with WalletTestOps {
-
- private case class TrackedTransaction(tx: ErgoTransaction,
- payments: List[ErgoTree],
- paymentValues: List[Int],
- appPayments: List[ErgoTree],
- appPaymentValues: List[Int],
- miningRewards: List[ErgoTree],
- miningRewardValues: List[Int]) {
- def scriptsCount: Int = payments.size + appPayments.size + miningRewards.size
-
- def valuesSum: Long = (paymentValues ++ appPaymentValues ++ miningRewardValues).sum
- }
-
- private val prover = defaultProver
- private val monetarySettings = initSettings.chainSettings.monetary.copy(minerRewardDelay = 720)
- private val s = initSettings.copy(chainSettings = initSettings.chainSettings.copy(monetary = monetarySettings))
-
- private val trueProp = org.ergoplatform.settings.Constants.TrueLeaf
- private val scanningPredicate = EqualsScanningPredicate(ErgoBox.ScriptRegId, ByteArrayConstant(trueProp.bytes))
- private val appReq = ScanRequest("True detector", scanningPredicate, Some(ScanWalletInteraction.Off), None)
- private val scanId: ScanId = ScanId @@ 50.toShort
-
- private val pubkeys = prover.hdPubKeys
- private val miningScripts = WalletCache.miningScripts(pubkeys, s)
-
- private def paymentsGen: Gen[List[ErgoTree]] = Gen.listOf(Gen.oneOf(pubkeys.map(_.key.toSigmaProp: ErgoTree)))
-
- private def miningRewardsGen: Gen[List[ErgoTree]] = Gen.listOf(Gen.oneOf(miningScripts))
-
- private def nonTrackablePaymentsGen: Gen[List[ErgoTree]] = Gen.nonEmptyListOf(Gen.const(FalseLeaf.toSigmaProp))
-
- private def appPaymentsGen: Gen[List[ErgoTree]] = Gen.listOf(Gen.const(trueProp))
-
- private def walletVarsGen: Gen[WalletVars] = {
- for {
- // To check that scanning works with locked wallet, we randomly choose whether the prover is set or not
- proverSet <- Gen.oneOf(true, false)
- } yield {
- if (proverSet) {
- WalletVars(Some(prover), Seq(appReq.toScan(scanId).get), None)(s)
- } else {
- val cache = WalletCache(pubkeys, s)
- WalletVars(None, Seq(appReq.toScan(scanId).get), Some(cache))(s)
- }
- }
- }
-
- private def trackedTransactionGen: Gen[TrackedTransaction] = {
- for {
- payments <- paymentsGen
- appPayments <- appPaymentsGen
- miningRewards <- miningRewardsGen
- nonTrackablePayments <- nonTrackablePaymentsGen
- } yield {
- def valueGen(): Int = Random.nextInt(1000) + 100
-
- val appPaymentValues = appPayments.map(_ => valueGen())
- val paymentValues = payments.map(_ => valueGen())
- val miningRewardValues = miningRewards.map(_ => valueGen())
- val nonTrackableValues = nonTrackablePayments.map(_ => valueGen())
- val outs = (payments ++ appPayments ++ miningRewards ++ nonTrackablePayments)
- .zip(paymentValues ++ appPaymentValues ++ miningRewardValues ++ nonTrackableValues)
- .map { case (script, vl) => new ErgoBoxCandidate(vl, script, creationHeight = 1) }
- .toIndexedSeq
-
- val tx = new ErgoTransaction(fakeInputs, IndexedSeq.empty, outs)
-
- TrackedTransaction(tx, payments, paymentValues, appPayments, appPaymentValues, miningRewards, miningRewardValues)
- }
- }
-
- property("extractWalletOutputs properly extracts") {
- val height = Random.nextInt(200) - 100
- val inclusionHeightOpt = if (height <= 0) None else Some(height)
-
- forAll(trackedTransactionGen, walletVarsGen) { case (trackedTransaction, walletVars) =>
- val foundBoxes = extractWalletOutputs(trackedTransaction.tx, inclusionHeightOpt, walletVars, None)
- foundBoxes.length shouldBe trackedTransaction.scriptsCount
- foundBoxes.map(_.inclusionHeightOpt).forall(_ == inclusionHeightOpt) shouldBe true
- foundBoxes.map(_.value).sum shouldBe trackedTransaction.valuesSum
- foundBoxes.forall(tb => if (trackedTransaction.payments.contains(tb.box.ergoTree)) {
- tb.scans == Set(Constants.PaymentsScanId)
- } else if (trackedTransaction.miningRewards.contains(tb.box.ergoTree)) {
- tb.scans == Set(Constants.MiningScanId)
- } else {
- tb.scans == Set(scanId)
- }) shouldBe true
- }
- }
-
- property("extractWalletOutputs filters out boxes with dust") {
- val height = Random.nextInt(200) - 100
- val inclusionHeightOpt = if (height <= 0) None else Some(height)
- forAll(trackedTransactionGen, walletVarsGen) { case (trackedTransaction, walletVars) =>
- val highDustLimit = Some(Long.MaxValue)
- val foundBoxes1 = extractWalletOutputs(trackedTransaction.tx, inclusionHeightOpt, walletVars, highDustLimit)
- foundBoxes1 shouldBe empty
- val lowDustLimit = Some(1L)
- val foundBoxes2 = extractWalletOutputs(trackedTransaction.tx, inclusionHeightOpt, walletVars, lowDustLimit)
- foundBoxes2.forall(_.value > 1) shouldBe true
- }
- }
-
- property("scanBlockTransactions") {
- withVersionedStore(10) { store =>
- val walletVars = walletVarsGen.sample.get
- val emptyReg = new WalletRegistry(store)(settings.walletSettings)
- val emptyOff = OffChainRegistry.empty
- val blockId = modIdGen.sample.get
-
- val height0 = 5
- //simplest case - we're scanning an empty block
- val (r0, o0, f0) =
- scanBlockTransactions(emptyReg, emptyOff, walletVars, height0, blockId,
- Seq.empty, None, None, WalletProfile.User).get
- val r0digest = r0.fetchDigest()
- r0digest.walletBalance shouldBe 0
- r0digest.walletAssetBalances.size shouldBe 0
- r0digest.height shouldBe height0
-
- val o0digest = o0.digest
- o0digest.walletBalance shouldBe 0
- o0digest.walletAssetBalances.size shouldBe 0
- o0digest.height shouldBe height0
-
- var registry = r0
- var off = o0
-
- forAll(trackedTransactionGen) { trackedTransaction =>
- //applying one transaction creating boxes
- val creatingTx = trackedTransaction.tx
- val txs = Seq(creatingTx)
- val height1 = 5
-
- val regDigestBefore = registry.fetchDigest().walletBalance
- val offDigestBefore = off.digest.walletBalance
-
- val (r1, o1, f1) =
- scanBlockTransactions(registry, off, walletVars, height1, blockId,
- txs, Some(f0), None, WalletProfile.User).get
- val r1digest = r1.fetchDigest()
- r1digest.walletBalance shouldBe (regDigestBefore + trackedTransaction.paymentValues.sum)
- r1digest.walletAssetBalances.size shouldBe 0
- r1digest.height shouldBe height1
-
- val o1digest = o1.digest
- o1digest.walletBalance shouldBe (offDigestBefore + trackedTransaction.paymentValues.sum)
- o1digest.walletAssetBalances.size shouldBe 0
- o1digest.height shouldBe height1
-
- registry = r1
- off = o1
-
- //applying a transaction spending outputs of previous transaction and creating new one with the same outputs
- val tx = trackedTransaction.tx
- val inputs = tx.outputs.map(_.id).map(id => Input(id, emptyProverResult))
- val spendingTx = ErgoTransaction(inputs, IndexedSeq.empty, tx.outputCandidates)
-
- val (r2, o2, f2) =
- scanBlockTransactions(registry, off, walletVars, height1 + 1, blockId,
- Seq(spendingTx), Some(f1), None, WalletProfile.User).get
-
- val r2digest = r2.fetchDigest()
- r2digest.walletBalance shouldBe (regDigestBefore + trackedTransaction.paymentValues.sum)
- r2digest.walletAssetBalances.size shouldBe 0
- r2digest.height shouldBe height1 + 1
-
- val o2digest = o2.digest
- o2digest.walletBalance shouldBe (offDigestBefore + trackedTransaction.paymentValues.sum)
- o2digest.walletAssetBalances.size shouldBe 0
- o2digest.height shouldBe height1 + 1
-
- registry = r2
- off = o2
-
- //applying a transaction spending outputs of the previous transaction
- val inputs2 = spendingTx.outputs.map(_.id).map(id => Input(id, emptyProverResult))
- val outputs2 = IndexedSeq(new ErgoBoxCandidate(spendingTx.outputs.map(_.value).sum, FalseLeaf.toSigmaProp, height1))
- val spendingTx2 = new ErgoTransaction(inputs2, IndexedSeq.empty, outputs2)
-
- val (r3, o3, f3) =
- scanBlockTransactions(registry, off, walletVars, height1 + 2, blockId,
- Seq(spendingTx2), Some(f2), None, WalletProfile.User).get
-
- val r3digest = r3.fetchDigest()
- r3digest.walletBalance shouldBe regDigestBefore
- r3digest.walletAssetBalances.size shouldBe 0
- r3digest.height shouldBe height1 + 2
-
- val o3digest = o3.digest
- o3digest.walletBalance shouldBe offDigestBefore
- o3digest.walletAssetBalances.size shouldBe 0
- o3digest.height shouldBe height1 + 2
-
- registry = r3
- off = o3
-
- //applying all the three previous transactions
- val threeTxs = Seq(creatingTx, spendingTx, spendingTx2)
-
- val (r4, o4, _) =
- scanBlockTransactions(registry, off, walletVars, height1 + 3, blockId,
- threeTxs, Some(f3), None, WalletProfile.User).get
-
- val r4digest = r4.fetchDigest()
- r4digest.walletBalance shouldBe regDigestBefore
- r4digest.walletAssetBalances.size shouldBe 0
- r4digest.height shouldBe height1 + 3
- r4.walletUnspentBoxes() shouldBe Seq.empty
-
- val o4digest = o4.digest
- o4digest.walletBalance shouldBe offDigestBefore
- o4digest.walletAssetBalances.size shouldBe 0
- o4digest.height shouldBe height1 + 3
-
- registry = r4
- off = o4
- }
- }
- }
-
- property("external scan prioritized over payments one if walletInteraction = off, otherwise shared") {
- val intFlagGen = Gen.oneOf(ScanWalletInteraction.Off, ScanWalletInteraction.Shared, ScanWalletInteraction.Forced)
- forAll(intFlagGen) { intFlag =>
- val pk = pubkeys.head.key.toSigmaProp: ErgoTree
- val outs = IndexedSeq(new ErgoBoxCandidate(1000, pk, creationHeight = 1))
- val tx = new ErgoTransaction(fakeInputs, IndexedSeq.empty, outs)
-
- val cache = WalletCache(pubkeys, s)
- val paymentPredicate = EqualsScanningPredicate(ErgoBox.ScriptRegId, ByteArrayConstant(pk.bytes))
- val paymentScanReq = ScanRequest("Payment scan", paymentPredicate, Some(intFlag), Some(true))
- val walletVars = WalletVars(None, Seq(paymentScanReq.toScan(scanId).get), Some(cache))(s)
-
- val boxes = extractWalletOutputs(tx, Some(1), walletVars, None)
-
- if (intFlag == ScanWalletInteraction.Shared || intFlag == ScanWalletInteraction.Forced) {
- boxes.size shouldBe 1
- boxes.head.scans.size shouldBe 2
- boxes.head.scans shouldBe Set(scanId, Constants.PaymentsScanId)
- } else {
- boxes.size shouldBe 1
- boxes.head.scans.size shouldBe 1
- boxes.head.scans.head shouldBe scanId
- }
- }
- }
-
- property("scan with forced flag is sharing boxes with the p2k-wallet") {
- val trueProp = TrueLeaf.toSigmaProp.treeWithSegregation: ErgoTree
- val outs = IndexedSeq(new ErgoBoxCandidate(1000, trueProp, creationHeight = 1))
- val tx = new ErgoTransaction(fakeInputs, IndexedSeq.empty, outs)
-
- val cache = WalletCache(pubkeys, s)
- val paymentPredicate = EqualsScanningPredicate(ErgoBox.ScriptRegId, ByteArrayConstant(trueProp.bytes))
- val paymentScanReq = ScanRequest("Payment scan", paymentPredicate, Some(ScanWalletInteraction.Forced), Some(false))
- val walletVars = WalletVars(None, Seq(paymentScanReq.toScan(scanId).get), Some(cache))(s)
-
- val boxes = extractWalletOutputs(tx, Some(1), walletVars, None)
-
- boxes.size shouldBe 1
- boxes.head.scans.size shouldBe 2
- boxes.head.scans shouldBe Set(scanId, Constants.PaymentsScanId)
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/WalletVarsSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/WalletVarsSpec.scala
deleted file mode 100644
index 6df68147b6..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/WalletVarsSpec.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.ergoplatform.nodeView.wallet
-
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.ergoplatform.wallet.interpreter.ErgoProvingInterpreter
-
-class WalletVarsSpec extends ErgoPropertyTest {
-
- property(".withProver init") {
- val prover = ErgoProvingInterpreter(defaultRootSecret, parameters)
- val walletVars = WalletVars(None, Seq.empty, None)
- val wp = walletVars.withProver(prover)
-
- wp.trackedPubKeys.length shouldBe 1
- wp.trackedBytes.length shouldBe 1
-
- defaultRootSecret.publicKey shouldBe wp.trackedPubKeys.head
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/OffChainRegistrySpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/OffChainRegistrySpec.scala
deleted file mode 100644
index 886fbf38ce..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/OffChainRegistrySpec.scala
+++ /dev/null
@@ -1,92 +0,0 @@
-package org.ergoplatform.nodeView.wallet.persistence
-
-import org.ergoplatform.ErgoBox
-import org.ergoplatform.nodeView.wallet.IdUtils.{EncodedBoxId, encodedBoxId}
-import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, Scan, ScanWalletInteraction}
-import org.ergoplatform.utils.WalletTestOps
-import org.ergoplatform.utils.generators.WalletGenerators
-import org.ergoplatform.wallet.Constants
-import org.scalacheck.Gen
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-import sigmastate.Values.ByteArrayConstant
-
-import scala.collection.immutable.TreeSet
-import scala.util.Random
-
-
-class OffChainRegistrySpec
- extends AnyFlatSpec
- with Matchers
- with ScalaCheckPropertyChecks
- with WalletGenerators
- with WalletTestOps {
-
- implicit override val generatorDrivenConfig: PropertyCheckConfiguration = PropertyCheckConfiguration(minSuccessful = 5, sizeRange = 10)
-
- //registry.updateOnTransaction is called when offchain transaction comes
- it should "calculate indexes correctly on offchain transaction" in {
- forAll(Gen.listOf(trackedBoxGen)) { boxes =>
- //apply transaction outputs to empty offchain registry
- var registry = OffChainRegistry.empty.updateOnTransaction(boxes, Seq.empty, Seq.empty)
- val balance = balanceAmount(boxes.map(_.box))
- val assetsBalance = assetAmount(boxes.map(_.box))
- registry.digest.walletBalance shouldEqual balance
- registry.digest.walletAssetBalances.toMap shouldEqual assetsBalance.toMap
-
- //spend all the outputs
- registry = registry.updateOnTransaction(Seq.empty, boxes.map(EncodedBoxId @@@ _.boxId), Seq.empty)
- registry.digest.walletBalance shouldEqual 0
- registry.digest.walletAssetBalances shouldEqual Seq.empty
-
-
- //check remove-offchain flag
- boxes.filter(_.scans.size > 1).flatMap(_.scans).find(_ != Constants.PaymentsScanId).map { scanId =>
- val trueProp = org.ergoplatform.settings.Constants.TrueLeaf
- val p = EqualsScanningPredicate(ErgoBox.R1, ByteArrayConstant(trueProp.bytes))
- val scan = Scan(scanId, "_", p, ScanWalletInteraction.Off, removeOffchain = false)
- val filtered = boxes.filter(tb => tb.scans.contains(scanId))
-
- val fbalance = balanceAmount(filtered.map(_.box))
- val fassetsBalance = assetAmount(filtered.map(_.box))
-
- registry = registry.updateOnTransaction(filtered, Seq.empty, Seq.empty)
- registry.digest.walletBalance shouldEqual fbalance
- registry.digest.walletAssetBalances.toMap shouldEqual fassetsBalance.toMap
-
- registry = registry.updateOnTransaction(Seq.empty, filtered.map(EncodedBoxId @@@ _.boxId), Seq(scan))
- registry.digest.walletBalance shouldEqual fbalance
- registry.digest.walletAssetBalances.toMap shouldEqual fassetsBalance.toMap
-
- val scan2 = Scan(scanId, "_", p, ScanWalletInteraction.Off, removeOffchain = true)
- registry = registry.updateOnTransaction(Seq.empty, filtered.map(EncodedBoxId @@@ _.boxId), Seq(scan2))
- registry.digest.walletBalance shouldEqual 0
- registry.digest.walletAssetBalances shouldEqual Seq.empty
- }
- }
- }
-
- //registry.updateOnTransaction is called when a block comes
- it should "calculate indexes correctly on a block" in {
- forAll(Gen.listOf(trackedBoxGen)) { boxes =>
- val height = Random.nextInt(500) + 1
-
- //apply block to empty registry
- val registry = OffChainRegistry.empty.updateOnBlock(height, boxes, boxes.map(tb => encodedBoxId(tb.box.id)).to[TreeSet])
- val balance = balanceAmount(boxes.map(_.box))
- val assetsBalance = assetAmount(boxes.map(_.box))
- registry.height shouldEqual height
- registry.digest.walletBalance shouldEqual balance
- registry.digest.walletAssetBalances.toMap shouldEqual assetsBalance.toMap
-
- //a block coming is not making any offchain box on-chain
- val registry2 = OffChainRegistry.empty.updateOnBlock(height, boxes, TreeSet.empty)
- registry2.height shouldEqual height
- registry2.digest.walletBalance shouldEqual balance
- registry2.digest.walletAssetBalances.toMap shouldEqual assetsBalance.toMap
- }
- }
-
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletRegistryBenchmark.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletRegistryBenchmark.scala
deleted file mode 100644
index 1dad6a9df8..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletRegistryBenchmark.scala
+++ /dev/null
@@ -1,86 +0,0 @@
-package org.ergoplatform.nodeView.wallet.persistence
-
-import org.ergoplatform.ErgoBox.{AdditionalRegisters, TokenId}
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.nodeView.wallet.WalletScanLogic.ScanResults
-import org.ergoplatform.nodeView.wallet.{WalletTransaction, WalletVars}
-import org.ergoplatform.sdk.wallet.secrets.{DerivationPath, ExtendedSecretKey}
-import org.ergoplatform.utils.ErgoTestConstants
-import org.ergoplatform.wallet.Constants
-import org.ergoplatform.wallet.boxes.TrackedBox
-import org.ergoplatform.wallet.interpreter.ErgoProvingInterpreter
-import org.ergoplatform.{ErgoAddressEncoder, ErgoBox, Input}
-import scorex.util.ModifierId
-import scorex.util.encode.Base16
-import sigmastate.Values.ErgoTree
-import sigmastate.interpreter.{ContextExtension, ProverResult}
-
-import scala.collection.compat.immutable.ArraySeq
-
-object WalletRegistryBenchmark extends App with ErgoTestConstants {
-
- def createBox(value: Long,
- ergoTree: ErgoTree,
- creationHeight: Int,
- additionalTokens: Seq[(TokenId, Long)] = Nil,
- additionalRegisters: AdditionalRegisters = Map.empty,
- transactionId: ModifierId = ErgoBox.allZerosModifierId,
- boxIndex: Short = 0): ErgoBox = {
- import sigmastate.eval._
- new ErgoBox(value, ergoTree,
- CostingSigmaDslBuilder.Colls.fromArray(additionalTokens.toArray[(TokenId, Long)]),
- additionalRegisters,
- transactionId, boxIndex, creationHeight)
- }
-
- implicit val enc = new ErgoAddressEncoder(ErgoAddressEncoder.MainnetNetworkPrefix)
-
- val registry = WalletRegistry(settings).get
- val storage = WalletStorage.readOrCreate(settings)
-
- val rootSecret = ExtendedSecretKey.deriveMasterKey(Array.fill(32)(0: Byte), usePre1627KeyDerivation = false)
-
- val derivedSecrets = (1 to 15000).map { i =>
- val k = rootSecret.derive(DerivationPath.fromEncoded(s"m/44'/429'/0'/0/$i").get)
- storage.addPublicKey(k.publicKey).get
- k
- }
-
- val prover = ErgoProvingInterpreter(rootSecret +: derivedSecrets, parameters)
- val walletVars = WalletVars.apply(storage, settings).withProver(prover)
-
- val boxes = walletVars.proverOpt.get.hdPubKeys.map { pk =>
- createBox(1000000000, pk.key, 1)
- }.map { box =>
- TrackedBox(box, 2, Set(Constants.PaymentsScanId))
- }
-
- val scanResults0 = ScanResults(boxes, ArraySeq.empty, ArraySeq.empty)
- registry.updateOnBlock(scanResults0, ModifierId @@ Base16.encode(Array.fill(32)(0: Byte)), 1).get
- println("keys: " + walletVars.proverOpt.get.secretKeys.size)
-
- val bts0 = System.currentTimeMillis()
- val boxesRead = registry.unspentBoxes(Constants.PaymentsScanId)
- val bts = System.currentTimeMillis()
- println("boxes read: " + boxesRead.size)
- println("boxes read time: " + (bts - bts0) + " ms")
-
- val stateContext = storage.readStateContext(parameters)
-
- val txs = boxes.map { tb =>
- val bx = tb.box
- val input = new Input(bx.id, ProverResult(Array.fill(64)(0: Byte), ContextExtension.empty))
- val tx = ErgoTransaction(IndexedSeq(input), IndexedSeq(bx.toCandidate))
- WalletTransaction(tx, 2, Seq(Constants.PaymentsScanId))
- }
-
- val scanResults1 = ScanResults(ArraySeq.empty, ArraySeq.empty, txs)
- registry.updateOnBlock(scanResults1, ModifierId @@ Base16.encode(Array.fill(32)(1: Byte)), 2).get
-
- val tts0 = System.currentTimeMillis()
- val txsRead = registry.allWalletTxs()
- val tts = System.currentTimeMillis()
- println("txs read: " + txsRead.size)
- println("txs read time: " + (tts - tts0) + " ms")
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletRegistrySpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletRegistrySpec.scala
deleted file mode 100644
index 6b5dfb4977..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletRegistrySpec.scala
+++ /dev/null
@@ -1,366 +0,0 @@
-package org.ergoplatform.nodeView.wallet.persistence
-
-import com.google.common.primitives.{Ints, Shorts}
-import org.ergoplatform.wallet.Constants.{PaymentsScanId, ScanId}
-import org.ergoplatform.db.DBSpec
-import org.ergoplatform.nodeView.wallet.WalletScanLogic.{ScanResults, SpentInputData}
-import org.ergoplatform.utils.generators.WalletGenerators
-import org.ergoplatform.wallet.boxes.TrackedBox
-import org.scalacheck.Gen
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-import scorex.core.VersionTag
-import scorex.util.encode.Base16
-
-import scala.collection.compat.immutable.ArraySeq
-import scala.util.Success
-
-class WalletRegistrySpec
- extends AnyFlatSpec
- with Matchers
- with DBSpec
- with ScalaCheckPropertyChecks
- with WalletGenerators {
-
- implicit override val generatorDrivenConfig = PropertyCheckConfiguration(minSuccessful = 4, sizeRange = 10)
-
- private val emptyBag = KeyValuePairsBag.empty
- private val walletBoxStatus = Set(PaymentsScanId)
-
- private val ws = settings.walletSettings
-
- it should "read unspent wallet boxes" in {
- forAll(trackedBoxGen) { box =>
- withVersionedStore(10) { store =>
- val unspentBox = box.copy(spendingHeightOpt = None, spendingTxIdOpt = None, scans = walletBoxStatus)
- WalletRegistry.putBox(emptyBag, unspentBox).transact(store).get
-
- val registry = new WalletRegistry(store)(settings.walletSettings)
- registry.walletUnspentBoxes() shouldBe Seq(unspentBox)
-
- //put app box
- val appId = ScanId @@ (PaymentsScanId + 1).toShort
- val unspentAppBox = box.copy(spendingHeightOpt = None, spendingTxIdOpt = None, scans = Set(appId))
- WalletRegistry.putBox(emptyBag, unspentAppBox).transact(store).get
- registry.walletUnspentBoxes() shouldBe Seq(unspentBox)
- registry.allUnspentBoxes() shouldBe Seq(unspentBox, unspentAppBox)
- }
- }
- }
-
- it should "read spent wallet boxes" in {
- forAll(trackedBoxGen, modifierIdGen) { case (box, txId) =>
- withVersionedStore(10) { store =>
- val spentBox = box.copy(spendingHeightOpt = Some(10000), spendingTxIdOpt = Some(txId), scans = walletBoxStatus)
- WalletRegistry.putBox(emptyBag, spentBox).transact(store).get
- val registry = new WalletRegistry(store)(settings.walletSettings)
- registry.walletSpentBoxes() shouldBe Seq(spentBox)
- }
- }
- }
-
- it should "read confirmed wallet boxes" in {
- forAll(trackedBoxGen, modifierIdGen) { case (box, txId) =>
- withVersionedStore(10) { store =>
- val unspentBox = box.copy(spendingHeightOpt = None, spendingTxIdOpt = None, scans = walletBoxStatus)
- val spentBox = box.copy(spendingHeightOpt = Some(10000), spendingTxIdOpt = Some(txId), scans = walletBoxStatus)
- WalletRegistry.putBoxes(emptyBag, Seq(unspentBox, spentBox)).transact(store).get
- val registry = new WalletRegistry(store)(settings.walletSettings)
- registry.walletSpentBoxes() shouldBe Seq(spentBox)
- registry.walletUnspentBoxes() shouldBe Seq(unspentBox)
- registry.walletConfirmedBoxes() shouldBe Seq(unspentBox, spentBox)
- }
- }
- }
-
- it should "read wallet transactions" in {
- forAll(walletTransactionGen) { wtx =>
- withVersionedStore(10) { store =>
- WalletRegistry.putTx(emptyBag, wtx).transact(store).get
- val registry = new WalletRegistry(store)(settings.walletSettings)
-
- registry.allWalletTxs() shouldBe Seq(wtx)
- }
- }
- }
-
- it should "update historical boxes when `keepSpentBoxes = true`" in {
- val ws = settings.walletSettings.copy(keepSpentBoxes = true)
- val spendingHeight = 0
- forAll(Gen.nonEmptyListOf(trackedBoxGen), modifierIdGen) { (boxes, txId) =>
- withVersionedStore(10) { store =>
- val unspentBoxes = boxes.map(
- _.copy(spendingHeightOpt = None, spendingTxIdOpt = None, scans = walletBoxStatus))
- val transitedBoxes = unspentBoxes.map(
- _.copy(spendingHeightOpt = Some(spendingHeight), spendingTxIdOpt = Some(txId)))
-
- WalletRegistry.putBoxes(emptyBag, unspentBoxes).transact(store).get
- val registry = new WalletRegistry(store)(ws)
- registry.processSpentBoxes(emptyBag, unspentBoxes.map(txId -> _), spendingHeight).transact(store).get
- registry.walletSpentBoxes().toList should contain theSameElementsAs transitedBoxes
- }
- }
- }
-
- it should "updateOnBlock() in correct way - only outputs" in {
- forAll(Gen.nonEmptyListOf(trackedBoxGen)) { boxes =>
- withVersionedStore(10) { store =>
- val registry = new WalletRegistry(store)(settings.walletSettings)
- val blockId = modifierIdGen.sample.get
- val unspentBoxes = boxes.map(bx => bx.copy(spendingHeightOpt = None, spendingTxIdOpt = None, scans = walletBoxStatus))
- registry.updateOnBlock(ScanResults(unspentBoxes, ArraySeq.empty, ArraySeq.empty), blockId, 100).get
- registry.walletUnspentBoxes().toList should contain theSameElementsAs unspentBoxes
- }
- }
- }
-
- private def outputsSpentTest(keepSpent: Boolean): Unit = forAll(Gen.nonEmptyListOf(trackedBoxGen)) { boxes =>
- withVersionedStore(10) { store =>
- val fakeTxId = modifierIdGen.sample.get
- val registry = new WalletRegistry(store)(settings.walletSettings.copy(keepSpentBoxes = keepSpent))
- val blockId = modifierIdGen.sample.get
- val outs = boxes.map { bx =>
- bx.copy(spendingHeightOpt = None, spendingTxIdOpt = None, scans = walletBoxStatus)
- }
- val inputs = outs.map(tb => SpentInputData(fakeTxId, tb))
- registry.updateOnBlock(ScanResults(outs, inputs, ArraySeq.empty), blockId, 100).get
- registry.walletUnspentBoxes() shouldBe Seq.empty
- }
- }
-
- it should "updateOnBlock() in correct way - outputs spent" in {
- outputsSpentTest(keepSpent = false)
- outputsSpentTest(keepSpent = true)
- }
-
- it should "putBox/getBox/removeBox" in {
- forAll(trackedBoxGen) { tb =>
- withVersionedStore(10) { store =>
- val reg = new WalletRegistry(store)(ws)
-
- WalletRegistry.putBox(emptyBag, tb).transact(store).get
- reg.getBox(tb.box.id) shouldBe Some(tb)
- reg.cache -= tb.boxId
- WalletRegistry.removeBoxes(emptyBag, Seq(tb)).transact(store).get
- reg.getBox(tb.box.id) shouldBe None
- }
- }
- }
-
- it should "putBox/removeBox - 2 versions" in {
- forAll(trackedBoxGen) { tb =>
- withVersionedStore(10) { store =>
- val reg = new WalletRegistry(store)(ws)
-
- val tb1 = tb.copy(spendingHeightOpt = None, spendingTxIdOpt = None)
- val bag1 = WalletRegistry.putBox(emptyBag, tb1)
-
- val tb2 = tb.copy(spendingHeightOpt = Some(5000), spendingTxIdOpt = Some(modifierIdGen.sample.get))
- val bag2 = WalletRegistry.removeBox(bag1, tb1)
- WalletRegistry.putBox(bag2, tb2).transact(store).get
- reg.getBox(tb.box.id) shouldBe Some(tb2)
- reg.walletUnspentBoxes() shouldBe Seq.empty
- }
- }
- }
-
- it should "putBoxes/getBoxes/removeBoxes" in {
- forAll(Gen.listOf(trackedBoxGen)) { tbs =>
- withVersionedStore(10) { store =>
- val reg = new WalletRegistry(store)(ws)
-
- WalletRegistry.putBoxes(emptyBag, tbs).transact(store).get
- reg.getBoxes(tbs.map(_.box.id)) should contain theSameElementsAs tbs.map(Some.apply)
- val updateFn = (tb: TrackedBox) => tb.copy(spendingHeightOpt = Some(0),
- scans = Set(PaymentsScanId, ScanId @@ 2.toShort))
- val updatedBoxes = tbs.map(updateFn)
- reg.getBoxes(tbs.map(_.box.id)) should contain theSameElementsAs updatedBoxes.map(Some.apply)
- reg.cache --= tbs.map(_.boxId)
- WalletRegistry.removeBoxes(emptyBag, tbs).transact(store).get
- reg.getBoxes(tbs.map(_.box.id)).flatten shouldBe Seq()
- }
- }
- }
-
- it should "putTx/getTx/getAllTxs/removeTxs" in {
- forAll(walletTransactionGen) { wtx =>
- withVersionedStore(10) { store =>
- val reg = new WalletRegistry(store)(ws)
-
- WalletRegistry.putTx(emptyBag, wtx).transact(store).get
- reg.getTx(wtx.id) shouldEqual Some(wtx)
- reg.allWalletTxs() shouldEqual Seq(wtx)
- WalletRegistry.removeTxs(emptyBag, Seq(wtx)).transact(store).get
- reg.allWalletTxs() should not contain wtx
- }
- }
- }
-
- it should "putTxs/getAllTxs" in {
- forAll(Gen.listOf(walletTransactionGen)) { wtxs =>
- withVersionedStore(10) { store =>
- val reg = new WalletRegistry(store)(ws)
-
- WalletRegistry.putTxs(emptyBag, wtxs).transact(store).get
- reg.allWalletTxs() should contain theSameElementsAs wtxs
- }
- }
- }
-
- it should "putIndex/digest/updateIndex" in {
- forAll(registrySummaryGen) { index =>
- withVersionedStore(10) { store =>
- val reg = new WalletRegistry(store)(ws)
-
- WalletRegistry.putDigest(emptyBag, index).transact(store).get
- reg.fetchDigest() shouldBe index
- val updatedIndex = index.copy(height = 0, walletBalance = 0)
- reg.updateDigest(emptyBag)(_ => Success(updatedIndex)).get.transact(store).get
- reg.fetchDigest() shouldBe updatedIndex
- }
- }
- }
-
- it should "update scans correctly" in {
- val appId1: ScanId = ScanId @@ 21.toShort
- val appId2: ScanId = ScanId @@ 22.toShort
-
- forAll(trackedBoxGen) { tb0 =>
- withVersionedStore(10) { store =>
- val tb1 = tb0.copy(scans = Set(appId1, appId2), spendingHeightOpt = None, spendingTxIdOpt = None)
-
- val reg = new WalletRegistry(store)(ws)
- WalletRegistry.putBox(emptyBag, tb1).transact(store).get
- reg.getBox(tb1.box.id).get.scans shouldBe Set(appId1, appId2)
- reg.unspentBoxes(appId1).length shouldBe 1
- reg.unspentBoxes(appId2).length shouldBe 1
- reg.updateScans(Set(appId1), tb1.box)
- reg.getBox(tb1.box.id).get.scans shouldBe Set(appId1)
- reg.unspentBoxes(appId1).length shouldBe 1
- reg.unspentBoxes(appId2).length shouldBe 0
- // limit should by applied
- reg.unspentBoxes(appId1, limit = 1).length shouldBe 1
- reg.unspentBoxes(appId1, limit = 0).length shouldBe 0
- }
- }
- }
-
- it should "get unspent boxes by height from/to inclusive" in {
- val appId1: ScanId = ScanId @@ 21.toShort
- val appId2: ScanId = ScanId @@ 22.toShort
- forAll(trackedBoxGen) { tb0 =>
- withVersionedStore(10) { store =>
- val tb1 = tb0.copy(scans = Set(appId1), inclusionHeightOpt = Some(5), spendingHeightOpt = None)
- val reg = new WalletRegistry(store)(ws)
- WalletRegistry.putBox(emptyBag, tb1).transact(store).get
- reg.getBox(tb1.box.id).get.scans shouldBe Set(appId1)
- reg.boxesByInclusionHeight(appId1, 1, 4).length shouldBe 0
- reg.boxesByInclusionHeight(appId1, 6, 10).length shouldBe 0
- reg.boxesByInclusionHeight(appId1, 4, 6).length shouldBe 1
- reg.boxesByInclusionHeight(appId1, 5, 6).length shouldBe 1
- reg.boxesByInclusionHeight(appId1, 5, 5).length shouldBe 1
- reg.boxesByInclusionHeight(appId1, 4, 5).length shouldBe 1
- // put another box under the same scan id should result in 2 matches
- val tb2 = trackedBoxGen.sample.get.copy(scans = Set(appId1), inclusionHeightOpt = Some(6), spendingHeightOpt = None)
- WalletRegistry.putBox(emptyBag, tb2).transact(store).get
- reg.boxesByInclusionHeight(appId1, 4, 7).length shouldBe 2
- reg.boxesByInclusionHeight(appId1, 4, 5).length shouldBe 1
- // search should differentiate between scan ids
- val tb3 = trackedBoxGen.sample.get.copy(scans = Set(appId2), inclusionHeightOpt = Some(6), spendingHeightOpt = None)
- WalletRegistry.putBox(emptyBag, tb3).transact(store).get
- reg.boxesByInclusionHeight(appId1, 4, 7).length shouldBe 2
- reg.boxesByInclusionHeight(appId2, 4, 7).length shouldBe 1
- // putting 2 different boxes under same height should result in 2 matches
- val tb4 = trackedBoxGen.sample.get.copy(scans = Set(appId2), inclusionHeightOpt = Some(6), spendingHeightOpt = None)
- WalletRegistry.putBox(emptyBag, tb4).transact(store).get
- reg.boxesByInclusionHeight(appId2, 4, 7).length shouldBe 2
- // putting 2 identical boxes should be idempotent operation
- WalletRegistry.putBox(emptyBag, tb4).transact(store).get
- reg.boxesByInclusionHeight(appId2, 4, 7).length shouldBe 2
- // spent boxes should be included
- val tb5 = trackedBoxGen.sample.get.copy(scans = Set(appId2), inclusionHeightOpt = Some(5), spendingHeightOpt = Some(6))
- WalletRegistry.putBox(emptyBag, tb5).transact(store).get
- reg.boxesByInclusionHeight(appId2, 4, 7).length shouldBe 3
- // one spent box and 2 unspent boxes should be present
- reg.spentBoxesByInclusionHeight(appId2, 4, 7).length shouldBe 1
- reg.unspentBoxesByInclusionHeight(appId2, 4, 7).length shouldBe 2
- }
- }
- }
-
- it should "remove application from a box correctly" in {
- val appId: ScanId = ScanId @@ 20.toShort
-
- forAll(trackedBoxGen) { tb0 =>
- val tb = tb0.copy(scans = Set(appId))
- withVersionedStore(10) { store =>
- val reg = new WalletRegistry(store)(ws)
- WalletRegistry.putBox(emptyBag, tb).transact(store).get
- reg.getBox(tb.box.id).isDefined shouldBe true
- reg.removeScan(tb.box.id, appId).isSuccess shouldBe true
- reg.getBox(tb.box.id).isDefined shouldBe false
- }
- }
-
- }
-
- it should "remove box-scan correspondence and then rollback - one app" in {
- val scanId: ScanId = ScanId @@ 20.toShort
-
- forAll(trackedBoxGen) { tb0 =>
- val tb = tb0.copy(scans = Set(scanId))
- withVersionedStore(10) { store =>
- val reg = new WalletRegistry(store)(ws)
- val version = scorex.utils.Random.randomBytes()
-
- WalletRegistry.putBox(emptyBag, tb).transact(store, version).get
- reg.getBox(tb.box.id).isDefined shouldBe true
- reg.removeScan(tb.box.id, scanId).isSuccess shouldBe true
- reg.getBox(tb.box.id).isDefined shouldBe false
- reg.rollback(VersionTag @@ Base16.encode(version)).isSuccess shouldBe true
- reg.getBox(tb.box.id).isDefined shouldBe false
- }
- }
- }
-
- it should "remove box-scan correspondence and then rollback - multiple apps" in {
- val scanId: ScanId = ScanId @@ 20.toShort
-
- forAll(trackedBoxGen) { tb0 =>
- val tb = tb0.copy(scans = Set(PaymentsScanId, scanId))
- withVersionedStore(10) { store =>
- val reg = new WalletRegistry(store)(ws)
- val version = scorex.utils.Random.randomBytes()
-
- WalletRegistry.putBox(emptyBag, tb).transact(store, version).get
- reg.getBox(tb.box.id).get.scans.size shouldBe 2
- reg.removeScan(tb.box.id, scanId).isSuccess shouldBe true
- reg.getBox(tb.box.id).get.scans.size shouldBe 1
- reg.rollback(VersionTag @@ Base16.encode(version)).isSuccess shouldBe true
- reg.getBox(tb.box.id).get.scans.size shouldBe 1
- reg.getBox(tb.box.id).get.scans shouldBe Set(PaymentsScanId)
- }
- }
- }
-
- it should "compose keys correctly" in {
- val box = trackedBoxGen.sample.get
-
- forAll { (prefix: Byte, scanId: Short, height: Int, suffix: Byte) =>
- val key1 = (prefix +: Shorts.toByteArray(scanId)) ++ Array.fill(32)(suffix)
- WalletRegistry.composeKey(prefix, ScanId @@ scanId, suffix) shouldBe key1
-
- val key2 = (prefix +: Shorts.toByteArray(scanId)) ++ Ints.toByteArray(height) ++ Array.fill(32)(suffix)
- WalletRegistry.composeKey(prefix, ScanId @@ scanId, height, suffix) shouldBe key2
-
- val id = box.box.id
- val key3 = (prefix +: Shorts.toByteArray(scanId)) ++ id
- WalletRegistry.composeKeyWithId(prefix, ScanId @@ scanId, id) shouldBe key3
-
- val key4 = (prefix +: Shorts.toByteArray(scanId)) ++ Ints.toByteArray(height) ++ id
- WalletRegistry.composeKeyWithHeightAndId(prefix, ScanId @@ scanId, height, id) shouldBe key4
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletStorageSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletStorageSpec.scala
deleted file mode 100644
index c0a1826bab..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletStorageSpec.scala
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.ergoplatform.nodeView.wallet.persistence
-
-import com.google.common.primitives.Ints
-import org.ergoplatform.db.DBSpec
-import org.ergoplatform.nodeView.wallet.persistence.WalletStorage.SecretPathsKey
-import org.ergoplatform.nodeView.wallet.scanning.{ScanRequest, ScanWalletInteraction}
-import org.ergoplatform.sdk.wallet.secrets.{DerivationPath, DerivationPathSerializer}
-import org.ergoplatform.utils.generators.WalletGenerators
-import org.scalacheck.Gen
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-import scorex.db.LDBKVStore
-
-class WalletStorageSpec
- extends AnyFlatSpec
- with Matchers
- with WalletGenerators
- with ScalaCheckPropertyChecks
- with DBSpec {
-
- it should "add and read derivation paths" in {
- def addPath(store: LDBKVStore, storedPaths: Seq[DerivationPath], derivationPath: DerivationPath): Unit = {
- val updatedPaths = (storedPaths :+ derivationPath).toSet
- val toInsert = Ints.toByteArray(updatedPaths.size) ++ updatedPaths
- .foldLeft(Array.empty[Byte]) { case (acc, path) =>
- val bytes = DerivationPathSerializer.toBytes(path)
- acc ++ Ints.toByteArray(bytes.length) ++ bytes
- }
- store.insert(SecretPathsKey, toInsert).get
- }
-
- forAll(Gen.nonEmptyListOf(derivationPathGen)) { paths =>
- withStore { store =>
- val storage = new WalletStorage(store, settings)
- paths.foreach(path => addPath(store, storage.readPaths(), path))
- storage.readPaths() should contain theSameElementsAs paths.toSet
- }
- }
- }
-
- it should "add and read public keys" in {
- forAll(extendedPubKeyListGen) { pubKeys =>
- withStore { store =>
- val storage = new WalletStorage(store, settings)
- pubKeys.foreach(storage.addPublicKey(_).get)
- val keysRead = storage.readAllKeys()
- keysRead.length shouldBe pubKeys.length
- keysRead should contain theSameElementsAs pubKeys.toSet
- }
- }
- }
-
- it should "add, remove and read scans" in {
- forAll(Gen.nonEmptyListOf(externalScanReqGen)) { externalScanReqs =>
- withStore { store =>
- val storage = new WalletStorage(store, settings)
- externalScanReqs.foreach(req => storage.addScan(req))
- val storageApps = storage.allScans
- val storageRequests = storageApps.map { app =>
- ScanRequest(app.scanName, app.trackingRule, Some(ScanWalletInteraction.Off), Some(true))
- }
- storageRequests.foreach(r => externalScanReqs.contains(r) shouldBe true)
- storageApps.map(_.scanId).foreach(storage.removeScan(_).get)
- storage.allScans.length shouldBe 0
- }
- }
- }
-
- it should "always increase ids" in {
- forAll(externalScanReqGen) { externalScanReq =>
- withStore { store =>
- val storage = new WalletStorage(store, settings)
- val scan = storage.addScan(externalScanReq).get
-
- storage.lastUsedScanId shouldBe scan.scanId
-
- storage.removeScan(scan.scanId).get
- storage.lastUsedScanId shouldBe scan.scanId
-
- val scan2 = storage.addScan(externalScanReq).get
- storage.lastUsedScanId shouldBe scan2.scanId
- storage.lastUsedScanId shouldBe (scan.scanId +1)
- }
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanSpecification.scala
deleted file mode 100644
index 120a0e8691..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanSpecification.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.ergoplatform.nodeView.wallet.scanning
-
-import io.circe.Json
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.ergoplatform.utils.generators.WalletGenerators
-
-class ScanSpecification extends ErgoPropertyTest with WalletGenerators {
- import ScanJsonCodecs._
-
- property("external scan req json serialization roundtrip") {
- forAll(externalScanReqGen) { req =>
- val j: Json = scanReqEncoder.apply(req)
- scanReqDecoder.decodeJson(j).toTry.get == req
- }
- }
-
- property("external scan json serialization roundtrip") {
- forAll(externalAppGen) { req =>
- val j: Json = scanEncoder.apply(req)
- scanDecoder.decodeJson(j).toTry.get == req
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateJsonCodecsSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateJsonCodecsSpecification.scala
deleted file mode 100644
index 4d015ac027..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateJsonCodecsSpecification.scala
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.ergoplatform.nodeView.wallet.scanning
-
-import io.circe.parser._
-import org.ergoplatform.ErgoBox
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.ergoplatform.utils.generators.WalletGenerators
-import scorex.util.encode.Base16
-import sigmastate.Values.ByteArrayConstant
-import sigmastate.eval.Extensions.ArrayByteOps
-
-import scala.language.implicitConversions
-
-class ScanningPredicateJsonCodecsSpecification extends ErgoPropertyTest with WalletGenerators {
-
- import ScanningPredicateJsonCodecs.{scanningPredicateDecoder, scanningPredicateEncoder}
-
- private implicit def bacFromBytes(bs: Array[Byte]) = ByteArrayConstant(bs)
-
- private val complexOr = OrScanningPredicate(
- ContainsScanningPredicate(ErgoBox.R1, ByteArrayConstant(Array.fill(32)(1: Byte))),
- EqualsScanningPredicate(ErgoBox.R4, ByteArrayConstant(Array.fill(32)(0: Byte))),
- ContainsAssetPredicate(Array.fill(32)(0: Byte).toTokenId)
- )
-
- private val complexAnd = AndScanningPredicate(
- ContainsScanningPredicate(ErgoBox.R1, ByteArrayConstant(Array.fill(32)(1: Byte))),
- EqualsScanningPredicate(ErgoBox.R4, ByteArrayConstant(Array.fill(32)(1: Byte))),
- ContainsAssetPredicate(Array.fill(32)(1: Byte).toTokenId)
- )
-
- property("json roundtrip for generated predicate") {
- forAll(scanningPredicateGen){p =>
- val j = scanningPredicateEncoder(p)
- scanningPredicateDecoder.decodeJson(j).toTry.get == p
- }
- }
-
- property("complex or roundtrip") {
- val p = complexOr
- val j = scanningPredicateEncoder(p)
- scanningPredicateDecoder.decodeJson(j).toTry.get == p
- }
-
- property("complex and roundtrip") {
- val p = complexAnd
- val j = scanningPredicateEncoder(p)
- scanningPredicateDecoder.decodeJson(j).toTry.get == p
- }
-
- property("example from EIP-1"){
- val j = parse(
- """{"predicate": "and", "args":[{"predicate": "contains",
- |"value": "0e2102dada811a888cd0dc7a0a41739a3ad9b0f427741fe6ca19700cf1a51200c96bf7"},
- |{"predicate": "containsAsset",
- |"assetId": "02dada811a888cd0dc7a0a41739a3ad9b0f427741fe6ca19700cf1a51200c96bf7"}]}""".stripMargin).toOption.get
-
- val bs = Base16.decode("02dada811a888cd0dc7a0a41739a3ad9b0f427741fe6ca19700cf1a51200c96bf7").get
- scanningPredicateDecoder.decodeJson(j).toTry.get == AndScanningPredicate(
- ContainsScanningPredicate(ErgoBox.R1, bs),
- ContainsAssetPredicate(bs.toTokenId)
- )
- }
-
- property("example from EIP-1 w. explicit register"){
- val j = parse(
- """{"predicate": "and", "args":[{"predicate": "contains", "register": "R4",
- |"value": "0e2102dada811a888cd0dc7a0a41739a3ad9b0f427741fe6ca19700cf1a51200c96bf7"},
- |{"predicate": "containsAsset",
- |"assetId": "02dada811a888cd0dc7a0a41739a3ad9b0f427741fe6ca19700cf1a51200c96bf7"}]}""".stripMargin).toOption.get
-
- val bs = Base16.decode("02dada811a888cd0dc7a0a41739a3ad9b0f427741fe6ca19700cf1a51200c96bf7").get
- scanningPredicateDecoder.decodeJson(j).toTry.get == AndScanningPredicate(
- ContainsScanningPredicate(ErgoBox.R4, bs),
- ContainsAssetPredicate(bs.toTokenId)
- )
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSerializerSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSerializerSpecification.scala
deleted file mode 100644
index ccd25df6ed..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSerializerSpecification.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.ergoplatform.nodeView.wallet.scanning
-
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.ergoplatform.utils.generators.WalletGenerators
-
-class ScanningPredicateSerializerSpecification extends ErgoPropertyTest with WalletGenerators {
-
- property("complex or roundtrip") {
- forAll(scanningPredicateGen) { p =>
- val bs = ScanningPredicateSerializer.toBytes(p)
- ScanningPredicateSerializer.parseBytes(bs) == p
- }
- }
-
- property("complex and roundtrip") {
- forAll(scanningPredicateGen) { p =>
- val bs = ScanningPredicateSerializer.toBytes(p)
- ScanningPredicateSerializer.parseBytes(bs) == p
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSpecification.scala
deleted file mode 100644
index dcfc049dbe..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSpecification.scala
+++ /dev/null
@@ -1,229 +0,0 @@
-package org.ergoplatform.nodeView.wallet.scanning
-
-import io.circe.parser._
-import org.ergoplatform.ErgoBox.R1
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.ergoplatform.utils.generators.ErgoTransactionGenerators
-import org.ergoplatform.wallet.serialization.JsonCodecsWrapper
-import org.ergoplatform.{ErgoTreePredef, P2PKAddress}
-import sigmastate.Values.ByteArrayConstant
-import sigmastate.eval.Extensions.ArrayByteOps
-import sigmastate.helpers.TestingHelpers._
-
-import scala.language.implicitConversions
-import scala.util.Random
-
-class ScanningPredicateSpecification extends ErgoPropertyTest with ErgoTransactionGenerators {
-
- val testDelay = 720 // to construct mining rewards scripts
-
- private implicit def bacFromBytes(bs: Array[Byte]) = ByteArrayConstant(bs)
-
- /** Helper function to create a new array with changed random byte. */
- private def mutateRandomByte(source: Array[Byte]): Array[Byte] = {
- val sourceModified = source.clone()
- val idx = Random.nextInt(sourceModified.length)
- sourceModified.update(idx, ((sourceModified(idx) + 1) % Byte.MaxValue).toByte)
- sourceModified
- }
-
- property("equals - p2pk") {
- forAll(ergoAddressGen) { p2pkAddress =>
- //look for exact p2pk script bytes
- val box = testBox(value = 1, p2pkAddress.script, creationHeight = 0)
- val scriptBytes = p2pkAddress.script.bytes
- EqualsScanningPredicate(R1, scriptBytes).filter(box) shouldBe true
-
- //then change random byte
- val scriptBytesModified = mutateRandomByte(scriptBytes)
- EqualsScanningPredicate(R1, scriptBytesModified).filter(box) shouldBe false
-
- //skip first byte in the filter
- EqualsScanningPredicate(R1, scriptBytes.tail).filter(box) shouldBe false
- }
- }
-
- property("equals - miner prop") {
- forAll(proveDlogGen) { pk =>
- val minerProp = ErgoTreePredef.rewardOutputScript(testDelay, pk)
- val mpBytes = minerProp.bytes
-
- //look for exact miner script bytes
- val box = testBox(value = 1, minerProp, creationHeight = 0)
- EqualsScanningPredicate(R1, mpBytes).filter(box) shouldBe true
-
- //then change random byte
- val scriptBytesModified = mutateRandomByte(mpBytes)
- EqualsScanningPredicate(R1, scriptBytesModified).filter(box) shouldBe false
- }
- }
-
- property("contains - p2pk") {
- forAll(ergoAddressGen) { p2pkAddress =>
- //look for exact p2pk script bytes
- val box = testBox(value = 1, p2pkAddress.script, creationHeight = 0)
- val pkBytes = p2pkAddress.asInstanceOf[P2PKAddress].pubkeyBytes
- ContainsScanningPredicate(R1, pkBytes).filter(box) shouldBe true
-
- //then change random byte in filter
- val pkBytesModified = mutateRandomByte(pkBytes)
- EqualsScanningPredicate(R1, pkBytesModified).filter(box) shouldBe false
-
- //skip first byte in the proper filter
- ContainsScanningPredicate(R1, pkBytes.tail).filter(box) shouldBe true
- }
- }
-
- property("contains - miner prop") {
- forAll(ergoAddressGen) { p2pkAddress =>
- //look for exact p2pk script bytes
- val minerProp = ErgoTreePredef.rewardOutputScript(testDelay, p2pkAddress.asInstanceOf[P2PKAddress].pubkey)
- val box = testBox(value = 1, minerProp, creationHeight = 0)
- val pkBytes = p2pkAddress.asInstanceOf[P2PKAddress].pubkeyBytes
-
- ContainsScanningPredicate(R1, pkBytes).filter(box) shouldBe true
-
- //then change random byte in filter
- val pkBytesModified = mutateRandomByte(pkBytes)
- EqualsScanningPredicate(R1, pkBytesModified).filter(box) shouldBe false
-
- //skip first byte in the proper filter
- ContainsScanningPredicate(R1, pkBytes.tail).filter(box) shouldBe true
- }
- }
-
- property("containsAsset") {
- forAll(proveDlogGen) { pk =>
- forAll(assetGen) { case (tokenId, amt) =>
- val box = testBox(value = 1, pk, creationHeight = 0, additionalTokens = Seq(tokenId -> amt))
- ContainsAssetPredicate(tokenId).filter(box) shouldBe true
-
- val emptyBox = testBox(value = 1, pk, creationHeight = 0)
- ContainsAssetPredicate(tokenId).filter(emptyBox) shouldBe false
-
- ContainsAssetPredicate(mutateRandomByte(tokenId.toArray).toTokenId).filter(box) shouldBe false
- }
- }
- }
-
- property("and") {
- forAll(ergoAddressGen) { p2pk =>
- forAll(assetGen) { case (tokenId, amt) =>
- val box = testBox(value = 1, p2pk.script, creationHeight = 0, additionalTokens = Seq(tokenId -> amt))
-
- //box contains both asset and p2pk script
- AndScanningPredicate(ContainsAssetPredicate(tokenId), ContainsScanningPredicate(R1, p2pk.contentBytes))
- .filter(box) shouldBe true
-
- AndScanningPredicate(
- EqualsScanningPredicate(R1, p2pk.script.bytes),
- ContainsScanningPredicate(R1, p2pk.contentBytes)
- ).filter(box) shouldBe true
-
- AndScanningPredicate(
- ContainsAssetPredicate(mutateRandomByte(tokenId.toArray).toTokenId),
- ContainsScanningPredicate(R1, p2pk.contentBytes)
- ).filter(box) shouldBe false
-
- AndScanningPredicate(
- ContainsAssetPredicate(tokenId),
- ContainsScanningPredicate(R1, mutateRandomByte(p2pk.contentBytes))
- ).filter(box) shouldBe false
- }
- }
- }
-
- property("or") {
- forAll(ergoAddressGen) { p2pk =>
- forAll(assetGen) { case (tokenId, amt) =>
- val box = testBox(value = 1, p2pk.script, creationHeight = 0, additionalTokens = Seq(tokenId -> amt))
-
- //box contains both asset and p2pk script
- OrScanningPredicate(ContainsAssetPredicate(tokenId), ContainsScanningPredicate(R1, p2pk.contentBytes))
- .filter(box) shouldBe true
-
- OrScanningPredicate(
- EqualsScanningPredicate(R1, p2pk.script.bytes),
- ContainsScanningPredicate(R1, p2pk.contentBytes)
- ).filter(box) shouldBe true
-
- OrScanningPredicate(
- ContainsAssetPredicate(mutateRandomByte(tokenId.toArray).toTokenId),
- ContainsScanningPredicate(R1, p2pk.contentBytes)
- ).filter(box) shouldBe true
-
- OrScanningPredicate(
- ContainsAssetPredicate(tokenId),
- ContainsScanningPredicate(R1, mutateRandomByte(p2pk.contentBytes))
- ).filter(box) shouldBe true
-
- OrScanningPredicate(
- ContainsAssetPredicate(mutateRandomByte(tokenId.toArray).toTokenId),
- ContainsScanningPredicate(R1, mutateRandomByte(p2pk.contentBytes))
- ).filter(box) shouldBe false
- }
- }
- }
-
- property("and - complex case #1 - with deserialization"){
- val scanString =
- """
- |{
- | "scanId": 80,
- | "scanName": "Local Oracle Datapoint Scan",
- | "trackingRule": {
- | "predicate": "and",
- | "args": [
- | {
- | "predicate": "containsAsset",
- | "assetId": "12caaacb51c89646fac9a3786eb98d0113bd57d68223ccc11754a4f67281daed"
- | },
- | {
- | "predicate": "equals",
- | "register": "R1",
- | "value": "0edf03100604000400050004000e20b662db51cf2dc39f110a021c2a31c74f0a1a18ffffbf73e8a051a7b8c0f09ebc0eca02100e040004000e2012caaacb51c89646fac9a3786eb98d0113bd57d68223ccc11754a4f67281daed0500040004140580dac4090402048092f401040201010402058092f4010400d804d601b2a5730000d602b5db6501fed9010263ed93e4c67202050ec5a7938cb2db63087202730100017302d603b17202d6049db072027303d9010441639a8c720401e4c68c72040206057e720305ea02d1edededededededed93c27201e4c6a7060e917203730493db63087201db6308a793e4c672010405720493e4c6720105049ae4c6a70504730592c17201730693e4c672010405720492c1720199c1a77e9c9a720373077308058cb0720286027309730ad901053c400163d802d6078c720501d6088c72070186029a7208730beded8c72070293c2b2a5720800d0cde4c68c720502040792c1b2a5720800730c02b2ad7202d9010563cde4c672050407730d00d803d601b2a5730000d602e4c6a70407d603b2db6501fe730100ea02d1ededededed93e4c672010407720293e4c67201050ec5720391e4c672010605730293c27201c2a793db63087201db6308a7ed938cb2db6308720373030001730493c272037305cd7202"
- | },
- | {
- | "predicate": "equals",
- | "register": "R4",
- | "value": "07029f2230dbe53f6b84d8a884a3407c3dffe43daf8037445441be7cdcd261feeaa4"
- | }
- | ]
- | },
- | "walletInteraction": "off",
- | "removeOffchain": true
- | }
- """.stripMargin
-
- val scanJson = parse(scanString).toOption.get
- val scan = ScanJsonCodecs.scanDecoder.decodeJson(scanJson).toOption.get
-
- val boxString =
- """
- |{
- | "boxId": "9441cf85bb564c72426b5eca49bce5f6cb27778c598ad02f34ca4358027b3a44",
- | "value": 2000000,
- | "ergoTree": "100604000400050004000e20b662db51cf2dc39f110a021c2a31c74f0a1a18ffffbf73e8a051a7b8c0f09ebc0eca02100e040004000e2012caaacb51c89646fac9a3786eb98d0113bd57d68223ccc11754a4f67281daed0500040004140580dac4090402048092f401040201010402058092f4010400d804d601b2a5730000d602b5db6501fed9010263ed93e4c67202050ec5a7938cb2db63087202730100017302d603b17202d6049db072027303d9010441639a8c720401e4c68c72040206057e720305ea02d1edededededededed93c27201e4c6a7060e917203730493db63087201db6308a793e4c672010405720493e4c6720105049ae4c6a70504730592c17201730693e4c672010405720492c1720199c1a77e9c9a720373077308058cb0720286027309730ad901053c400163d802d6078c720501d6088c72070186029a7208730beded8c72070293c2b2a5720800d0cde4c68c720502040792c1b2a5720800730c02b2ad7202d9010563cde4c672050407730d00d803d601b2a5730000d602e4c6a70407d603b2db6501fe730100ea02d1ededededed93e4c672010407720293e4c67201050ec5720391e4c672010605730293c27201c2a793db63087201db6308a7ed938cb2db6308720373030001730493c272037305cd7202",
- | "assets": [
- | {
- | "tokenId": "12caaacb51c89646fac9a3786eb98d0113bd57d68223ccc11754a4f67281daed",
- | "amount": 1
- | }
- | ],
- | "creationHeight": 280831,
- | "additionalRegisters": {
- | "R4": "07029f2230dbe53f6b84d8a884a3407c3dffe43daf8037445441be7cdcd261feeaa4",
- | "R5": "0e0101"
- | },
- | "transactionId": "dfad960e6fb085f10e9b700f5631251b11209e7ed09a56c94d8bd91452226344",
- | "index": 1
- | }
- """.stripMargin
-
- val boxJson = parse(boxString).toOption.get
- val box = JsonCodecsWrapper.ergoBoxDecoder.decodeJson(boxJson).toOption.get
-
- scan.trackingRule.filter(box) shouldBe true
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/reemission/ReemissionRulesSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/reemission/ReemissionRulesSpec.scala
deleted file mode 100644
index 46a670cab6..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/reemission/ReemissionRulesSpec.scala
+++ /dev/null
@@ -1,208 +0,0 @@
-package org.ergoplatform.reemission
-
-import org.ergoplatform._
-import org.ergoplatform.settings.{MonetarySettings, ReemissionSettings}
-import org.ergoplatform.utils.{ErgoPropertyTest, ErgoTestConstants}
-import scorex.crypto.hash.Blake2b256
-import scorex.util.ModifierId
-import sigma.Colls
-import sigmastate.AvlTreeData
-import sigmastate.TrivialProp.TrueProp
-import sigmastate.eval.Digest32Coll
-import sigmastate.helpers.TestingHelpers.testBox
-import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter}
-import sigmastate.interpreter.Interpreter.emptyEnv
-
-import scala.util.{Failure, Success, Try}
-
-// done similarly to ErgoScriptPredefSpec in sigma repo
-class ReemissionRulesSpec extends ErgoPropertyTest with ErgoTestConstants {
-
- private val ms = MonetarySettings()
- private val checkReemissionRules: Boolean = true
- private val emissionNftId: ModifierId = ModifierId @@ "06f29034fb69b23d519f84c4811a19694b8cdc2ce076147aaa050276f0b840f4"
- private val reemissionTokenId: ModifierId = ModifierId @@ "01345f0ed87b74008d1c46aefd3e7ad6ee5909a2324f2899031cdfee3cc1e022"
- private val reemissionNftId: ModifierId = ModifierId @@ "06f2c3adfe52304543f7b623cc3fccddc0174a7db52452fef8e589adacdfdfee"
- private val activationHeight: Int = 0
- private val reemissionStartHeight: Int = 100
- private val injectionBoxBytesEncoded: ModifierId = ModifierId @@ "a0f9e1b5fb011003040005808098f4e9b5ca6a0402d1ed91c1b2a4730000730193c5a7c5b2a4730200f6ac0b0201345f0ed87b74008d1c46aefd3e7ad6ee5909a2324f2899031cdfee3cc1e02280808cfaf49aa53506f29034fb69b23d519f84c4811a19694b8cdc2ce076147aaa050276f0b840f40100325c3679e7e0e2f683e4a382aa74c2c1cb989bb6ad6a1d4b1c5a021d7b410d0f00"
- private val rs = ReemissionSettings(checkReemissionRules, emissionNftId, reemissionTokenId,
- reemissionNftId, activationHeight, reemissionStartHeight, injectionBoxBytesEncoded)
-
- private val rr = new ReemissionRules(rs)
-
- private val reemissionBoxAssets = Colls.fromItems((Digest32Coll @@ rs.reemissionNftIdBytes) -> 1L)
-
- private val fakeMessage = Blake2b256("Hello World")
-
- private def prover = new ContextEnrichingTestProvingInterpreter
- private def verifier = new ErgoLikeTestInterpreter
- private val prop = rr.reemissionBoxProp(ms)
-
- def checkRewardsTx(nextHeight: Int,
- pkBytes: Array[Byte],
- inputBoxes: IndexedSeq[ErgoBox],
- spendingTransaction: ErgoLikeTransaction,
- expectedValidity: Boolean) = {
- val ctx = ErgoLikeContextTesting(
- currentHeight = nextHeight,
- lastBlockUtxoRoot = AvlTreeData.dummy,
- minerPubkey = pkBytes,
- boxesToSpend = inputBoxes,
- spendingTransaction,
- self = inputBoxes.head,
- 1: Byte) //activated script version
- Try(prover.prove(emptyEnv, prop, ctx, fakeMessage).get) match {
- case Success(pr) =>
- verifier.verify(emptyEnv, prop, ctx, pr, fakeMessage).get._1 shouldBe expectedValidity
- case Failure(e) if expectedValidity =>
- throw new Exception("Unexpected exception thrown: ", e)
- case _ =>
- }
- }
-
- ignore("reemission rules test vectors") {
-
- }
-
- property("reemissionBoxProp - spending path") {
- val minerPk = prover.dlogSecrets.head.publicImage
- val pkBytes = minerPk.pkBytes
- val minerProp = ErgoTreePredef.rewardOutputScript(ms.minerRewardDelay, minerPk)
-
- val currentHeight = rs.reemissionStartHeight
- val nextHeight = currentHeight + 1
-
- val initialErgValue = 1000000000000L
- val reemissionBox = testBox(initialErgValue, prop, currentHeight, reemissionBoxAssets.toArray, Map())
-
- val reemissionReward = rr.reemissionRewardPerBlock
-
- val inputBoxes = IndexedSeq(reemissionBox)
- val inputs = inputBoxes.map(b => Input(b.id, emptyProverResult))
-
- val newReemissionBox = new ErgoBoxCandidate(reemissionBox.value - reemissionReward, prop, nextHeight, reemissionBoxAssets)
- val minerBox = new ErgoBoxCandidate(reemissionReward, minerProp, nextHeight)
-
- val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(newReemissionBox, minerBox))
-
- // normal execution
- checkRewardsTx(nextHeight, pkBytes, inputBoxes, spendingTransaction, true)
-
- // miner tries to take too much from reemission contract
- val newReemissionBox2 = new ErgoBoxCandidate(reemissionBox.value - reemissionReward - 1, prop, nextHeight, reemissionBoxAssets)
- val minerBox2 = new ErgoBoxCandidate(reemissionReward + 1, minerProp, nextHeight)
- val spendingTransaction2 = ErgoLikeTransaction(inputs, IndexedSeq(newReemissionBox2, minerBox2))
- checkRewardsTx(nextHeight, pkBytes, inputBoxes, spendingTransaction2, false)
-
- //... and it is not okay to take less even
- val newReemissionBox3 = new ErgoBoxCandidate(reemissionBox.value - reemissionReward + 1, prop, nextHeight, reemissionBoxAssets)
- val minerBox3 = new ErgoBoxCandidate(reemissionReward - 1, minerProp, nextHeight)
- val spendingTransaction3 = ErgoLikeTransaction(inputs, IndexedSeq(newReemissionBox3, minerBox3))
- checkRewardsTx(nextHeight, pkBytes, inputBoxes, spendingTransaction3, false)
-
- // re-emission NFT must be preserved
- val newReemissionBox4 = new ErgoBoxCandidate(reemissionBox.value - reemissionReward, prop, nextHeight, Colls.emptyColl)
- val spendingTransaction4 = ErgoLikeTransaction(inputs, IndexedSeq(newReemissionBox4, minerBox))
- checkRewardsTx(nextHeight, pkBytes, inputBoxes, spendingTransaction4, false)
-
- // not possible to charge before re-emission start
- val nextHeight5 = currentHeight - 10
- val emissionBox5 = testBox(initialErgValue, prop, nextHeight5 - 1, reemissionBoxAssets.toArray, Map())
- val inputBoxes5 = IndexedSeq(emissionBox5)
- val inputs5 = inputBoxes5.map(b => Input(b.id, emptyProverResult))
- val newReemissionBox5 = new ErgoBoxCandidate(emissionBox5.value - reemissionReward, prop, nextHeight5, reemissionBoxAssets)
- val minerBox5 = new ErgoBoxCandidate(reemissionReward, minerProp, nextHeight5)
- val spendingTransaction5 = ErgoLikeTransaction(inputs5, IndexedSeq(newReemissionBox5, minerBox5))
- checkRewardsTx(nextHeight5, pkBytes, inputBoxes5, spendingTransaction5, false)
-
- // can be spent to miner pubkey only
- val prover6 = new ContextEnrichingTestProvingInterpreter
- val minerPk6 = prover6.dlogSecrets.head.publicImage
- val pkBytes6 = minerPk6.pkBytes
- checkRewardsTx(nextHeight, pkBytes6, inputBoxes, spendingTransaction, false)
-
- // we modify reward delay here, not PK
- val minerProp7 = ErgoTreePredef.rewardOutputScript(ms.minerRewardDelay - 1, minerPk)
- val minerBox7 = new ErgoBoxCandidate(reemissionReward, minerProp7, nextHeight)
- val spendingTransaction7 = ErgoLikeTransaction(inputs, IndexedSeq(newReemissionBox, minerBox7))
- checkRewardsTx(nextHeight, pkBytes, inputBoxes, spendingTransaction7, false)
- }
-
- // also testing payToReemission contract
- property("reemissionBoxProp - merging path") {
- val minerPk = prover.dlogSecrets.head.publicImage
- val pkBytes = minerPk.pkBytes
-
- val rewardsProp = prop
- val pay2RewardsProp = rr.payToReemission
-
- val mergedValue = 100000000L
-
- val currentHeight = rs.reemissionStartHeight - 1
-
- val pay2RBox = testBox(mergedValue, pay2RewardsProp, currentHeight, reemissionBoxAssets.toArray, Map())
- val reemissionBox = testBox(mergedValue * 100, rewardsProp, currentHeight, reemissionBoxAssets.toArray, Map())
-
- val inputBoxes = IndexedSeq(reemissionBox, pay2RBox)
- val inputs = inputBoxes.map(b => Input(b.id, emptyProverResult))
-
- val feeValue = 10000000L
-
- // merging with 1 box - successful case
- val newReemissionBox = new ErgoBoxCandidate(reemissionBox.value + mergedValue - feeValue, prop, currentHeight, reemissionBoxAssets)
- val feeBox = new ErgoBoxCandidate(feeValue, TrueProp, currentHeight)
- val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(newReemissionBox, feeBox))
-
- checkRewardsTx(currentHeight, pkBytes, inputBoxes, spendingTransaction, true)
-
- // merging with 2 boxex - successful case
- val inputBoxes2 = IndexedSeq(reemissionBox, pay2RBox, pay2RBox)
- val inputs2 = inputBoxes2.map(b => Input(b.id, emptyProverResult))
- val newReemissionBox2 = new ErgoBoxCandidate(reemissionBox.value + 2 * mergedValue - feeValue, prop, currentHeight, reemissionBoxAssets)
- val spendingTransaction2 = ErgoLikeTransaction(inputs2, IndexedSeq(newReemissionBox2, feeBox))
-
- checkRewardsTx(currentHeight, pkBytes, inputBoxes, spendingTransaction2, true)
-
- // paying too high fee
- val newReemissionBox3 = new ErgoBoxCandidate(reemissionBox.value + mergedValue - feeValue - 1, prop, currentHeight, reemissionBoxAssets)
- val feeBox3 = new ErgoBoxCandidate(feeValue + 1, TrueProp, currentHeight)
- val spendingTransaction3 = ErgoLikeTransaction(inputs2, IndexedSeq(newReemissionBox3, feeBox3))
-
- checkRewardsTx(currentHeight, pkBytes, inputBoxes, spendingTransaction3, false)
-
- // reemission NFT must be preserved
- val newReemissionBox4 = new ErgoBoxCandidate(reemissionBox.value + mergedValue - feeValue, prop, currentHeight)
- val spendingTransaction4 = ErgoLikeTransaction(inputs, IndexedSeq(newReemissionBox4, feeBox))
-
- checkRewardsTx(currentHeight, pkBytes, inputBoxes, spendingTransaction4, false)
-
- // reemission box value must be increased
- val feeValue5 = mergedValue
- val newReemissionBox5 = new ErgoBoxCandidate(reemissionBox.value + mergedValue - feeValue5, prop, currentHeight, reemissionBoxAssets)
- val feeBox5 = new ErgoBoxCandidate(feeValue5, TrueProp, currentHeight)
- val spendingTransaction5 = ErgoLikeTransaction(inputs, IndexedSeq(newReemissionBox5, feeBox5))
- checkRewardsTx(currentHeight, pkBytes, inputBoxes, spendingTransaction5, false)
-
- // pay-2-reemission box can be spent only with a box with reemission NFT as input #0
- val reemissionBoxAssets6 = Colls.fromItems(
- (Digest32Coll @@ rs.reemissionNftIdBytes.reverse) -> 1L
- )
- val newReemissionBox6 = new ErgoBoxCandidate(
- reemissionBox.value + mergedValue - feeValue,
- prop, currentHeight, reemissionBoxAssets6)
- val spendingTransaction6 = ErgoLikeTransaction(inputs, IndexedSeq(newReemissionBox6, feeBox))
-
- val ctx = ErgoLikeContextTesting(
- currentHeight = currentHeight,
- lastBlockUtxoRoot = AvlTreeData.dummy,
- minerPubkey = pkBytes,
- boxesToSpend = inputBoxes,
- spendingTransaction6,
- self = inputBoxes(1),
- 0)
-
- prover.prove(emptyEnv, pay2RewardsProp, ctx, fakeMessage).isFailure shouldBe true
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/sanity/ErgoSanity.scala b/ergo-core/src/test/scala/org/ergoplatform/sanity/ErgoSanity.scala
deleted file mode 100644
index f40b10c22a..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/sanity/ErgoSanity.scala
+++ /dev/null
@@ -1,129 +0,0 @@
-package org.ergoplatform.sanity
-
-import akka.actor.ActorRef
-import org.ergoplatform.ErgoBox
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.history.BlockTransactions
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.modifiers.{BlockSection, ErgoFullBlock}
-import org.ergoplatform.network.{ErgoNodeViewSynchronizer, ErgoSyncTracker}
-import org.ergoplatform.nodeView.NodeViewSynchronizerTests
-import org.ergoplatform.nodeView.history.{ErgoHistory, ErgoSyncInfo, ErgoSyncInfoMessageSpec}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.ergoplatform.nodeView.state.{DigestState, ErgoState, UtxoState}
-import org.ergoplatform.sanity.ErgoSanity._
-import org.ergoplatform.settings.ErgoSettings
-import org.ergoplatform.settings.Constants.HashLength
-import org.ergoplatform.utils.{ErgoTestHelpers, HistoryTestHelpers}
-import org.scalacheck.Gen
-import scorex.core.network.DeliveryTracker
-import scorex.core.{PersistentNodeViewModifier, bytesToId}
-import scorex.crypto.authds.ADDigest
-import scorex.crypto.hash.{Blake2b256, Digest32}
-import scorex.testkit.generators.{ModifierProducerTemplateItem, SynInvalid, Valid}
-import scorex.testkit.properties._
-import scorex.testkit.properties.mempool.{MempoolRemovalTest, MempoolTransactionsTest}
-import scorex.testkit.properties.state.StateApplicationTest
-import scorex.utils.Random
-
-import scala.concurrent.ExecutionContext
-import scala.concurrent.duration._
-
-trait ErgoSanity[ST <: ErgoState[ST]] extends NodeViewSynchronizerTests[ST]
- with StateApplicationTest[ST]
- with MempoolTransactionsTest
- with MempoolRemovalTest
- with HistoryTests
- with ErgoTestHelpers
- with HistoryTestHelpers {
-
-
- override val memPool: MPool = ErgoMemPool.empty(settings)
-
- //Generators
- override lazy val transactionGenerator: Gen[ErgoTransaction] = invalidErgoTransactionGen
- override lazy val unconfirmedTxGenerator: Gen[UnconfirmedTransaction] =
- invalidErgoTransactionGen.map(tx => UnconfirmedTransaction(tx, None))
- override lazy val memPoolGenerator: Gen[MPool] = emptyMemPoolGen
-
- override def syntacticallyValidModifier(history: HT): Header = {
- val bestTimestamp = history.bestHeaderOpt.map(_.timestamp + 1).getOrElse(System.currentTimeMillis())
-
- powScheme.prove(
- history.bestHeaderOpt,
- Header.InitialVersion,
- settings.chainSettings.initialNBits,
- ADDigest @@ Array.fill(HashLength + 1)(0.toByte),
- Digest32 @@ Array.fill(HashLength)(0.toByte),
- Digest32 @@ Array.fill(HashLength)(0.toByte),
- Math.max(System.currentTimeMillis(), bestTimestamp),
- Digest32 @@ Array.fill(HashLength)(0.toByte),
- Array.fill(3)(0: Byte),
- defaultMinerSecretNumber
- ).get
- }
-
- override def syntacticallyInvalidModifier(history: HT): PM =
- syntacticallyValidModifier(history).copy(parentId = bytesToId(Random.randomBytes(32)))
-
- private val hf = Blake2b256
-
- def makeSyntacticallyInvalid(mod: PM): PM = mod match {
- case fb: ErgoFullBlock =>
- val parentId = fb.header.parentId
- val header = fb.header.copy(parentId = bytesToId(hf(parentId)))
- fb.copy(header = header)
- case h: Header => h.copy(parentId = bytesToId(hf(h.parentId)))
- case v => v
- }
-
- def customModifiers(history: HT,
- state: ST,
- template: Seq[ModifierProducerTemplateItem]): Seq[PM] =
- template.zip(totallyValidModifiers(history, state, template.length))
- .map { case (templateItem, mod) =>
- templateItem match {
- case Valid => mod
- case SynInvalid => makeSyntacticallyInvalid(mod)
- }
- }
-
- class SyncronizerMock(networkControllerRef: ActorRef,
- viewHolderRef: ActorRef,
- syncInfoSpec: ErgoSyncInfoMessageSpec.type,
- settings: ErgoSettings,
- syncTracker: ErgoSyncTracker,
- deliveryTracker: DeliveryTracker)
- (implicit ec: ExecutionContext) extends ErgoNodeViewSynchronizer(
- networkControllerRef,
- viewHolderRef,
- syncInfoSpec,
- settings,
- syncTracker,
- deliveryTracker)(ec) {
-
- protected def broadcastInvForNewModifier(mod: PersistentNodeViewModifier): Unit = {
- mod match {
- case fb: ErgoFullBlock if fb.header.isNew(1.hour) =>
- fb.toSeq.foreach(s => broadcastModifierInv(s))
- case h: Header if h.isNew(1.hour) =>
- broadcastModifierInv(h)
- case _ =>
- }
- }
- }
-
-}
-
-object ErgoSanity {
- type TX = ErgoTransaction
- type B = ErgoBox
- type PM = BlockSection
- type CTM = BlockTransactions
- type SI = ErgoSyncInfo
- type HT = ErgoHistory
- type UTXO_ST = UtxoState
- type DIGEST_ST = DigestState
- type MPool = ErgoMemPool
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/sanity/ErgoSanityDigest.scala b/ergo-core/src/test/scala/org/ergoplatform/sanity/ErgoSanityDigest.scala
deleted file mode 100644
index d9b07a50e7..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/sanity/ErgoSanityDigest.scala
+++ /dev/null
@@ -1,107 +0,0 @@
-package org.ergoplatform.sanity
-
-import akka.actor.{ActorRef, ActorSystem, Props}
-import akka.testkit.TestProbe
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.BlockTransactions
-import org.ergoplatform.modifiers.history.header.HeaderSerializer
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.{ChangedHistory, ChangedMempool}
-import org.ergoplatform.network.ErgoSyncTracker
-import org.ergoplatform.nodeView.history.ErgoSyncInfoMessageSpec
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.ergoplatform.nodeView.state.wrapped.{WrappedDigestState, WrappedUtxoState}
-import org.ergoplatform.nodeView.state.{DigestState, StateType}
-import org.ergoplatform.sanity.ErgoSanity._
-import org.ergoplatform.settings.ErgoSettings
-import org.scalacheck.Gen
-import scorex.core.idToBytes
-import scorex.core.network.{ConnectedPeer, DeliveryTracker}
-import scorex.core.network.peer.PeerInfo
-import scorex.core.serialization.ErgoSerializer
-
-import scala.concurrent.ExecutionContextExecutor
-
-class ErgoSanityDigest extends ErgoSanity[DIGEST_ST] {
-
- override val historyGen: Gen[HT] =
- generateHistory(verifyTransactions = true, StateType.Digest, PoPoWBootstrap = false, -1)
-
- override val stateGen: Gen[WrappedDigestState] = {
- boxesHolderGen.map(WrappedUtxoState(_, createTempDir, None, parameters, settings)).map { wus =>
- val digestState = DigestState.create(Some(wus.version), Some(wus.rootDigest), createTempDir, settings)
- new WrappedDigestState(digestState, wus, settings)
- }
- }
-
- override def semanticallyValidModifier(state: DIGEST_ST): PM =
- validFullBlock(None, state.asInstanceOf[WrappedDigestState].wrappedUtxoState)
-
- override def semanticallyInvalidModifier(state: DIGEST_ST): PM = invalidErgoFullBlockGen.sample.get
-
- override def totallyValidModifier(history: HT, state: DIGEST_ST): PM = {
- val parentOpt = history.bestFullBlockOpt
- validFullBlock(parentOpt, state.asInstanceOf[WrappedDigestState].wrappedUtxoState).header
- }
-
- override def totallyValidModifiers(history: HT, state: DIGEST_ST, count: Int): Seq[PM] = {
- require(count >= 1)
- val blockOpt = history.bestFullBlockOpt
- (0 until count).foldLeft((blockOpt, Seq.empty[PM])) { case (acc, _) =>
- val pm = validFullBlock(blockOpt, state.asInstanceOf[WrappedDigestState].wrappedUtxoState)
- (Some(pm), acc._2 :+ pm)
- }._2.map(_.asInstanceOf[ErgoFullBlock].header)
- }
-
- override def nodeViewSynchronizer(implicit system: ActorSystem):
- (ActorRef, SI, PM, TX, ConnectedPeer, TestProbe, TestProbe, TestProbe, TestProbe, ErgoSerializer[PM]) = {
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val h = historyGen.sample.get
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val s = stateGen.sample.get
- val settings = ErgoSettings.read()
- val pool = ErgoMemPool.empty(settings)
- val v = h.bestFullBlockIdOpt.orElse(h.bestHeaderIdOpt)
- v.foreach(id => s.store.update(idToBytes(id), Seq(), Seq()).get)
- implicit val ec: ExecutionContextExecutor = system.dispatcher
- val ncProbe = TestProbe("NetworkControllerProbe")
- val vhProbe = TestProbe("ViewHolderProbe")
- val pchProbe = TestProbe("PeerHandlerProbe")
- val eventListener = TestProbe("EventListener")
- val syncTracker = ErgoSyncTracker(settings.scorexSettings.network)
- val deliveryTracker: DeliveryTracker = DeliveryTracker.empty(settings)
- val ref = system.actorOf(Props(
- new SyncronizerMock(
- ncProbe.ref,
- vhProbe.ref,
- ErgoSyncInfoMessageSpec,
- settings,
- syncTracker,
- deliveryTracker
- )
- ))
- val m = totallyValidModifier(h, s)
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val tx = validErgoTransactionGenTemplate(minAssets = 0, maxAssets = 0).sample.get._2
-
-
- val peerInfo = PeerInfo(defaultPeerSpec, Long.MaxValue, None, 0L)
-
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val p: ConnectedPeer = ConnectedPeer(
- connectionIdGen.sample.get,
- pchProbe.ref,
- Some(peerInfo)
- )
- ref ! ChangedHistory(h)
- ref ! ChangedMempool(pool)
- val serializer: ErgoSerializer[PM] = HeaderSerializer.asInstanceOf[ErgoSerializer[PM]]
- (ref, h.syncInfoV1, m, tx, p, pchProbe, ncProbe, vhProbe, eventListener, serializer)
- }
-
- override def modifierWithTransactions(memoryPoolOpt: Option[MPool], customTransactionsOpt: Option[Seq[TX]]): CTM = {
- val boxHolder = boxesHolderGen.sample.get
- val txs = validTransactionsFromBoxHolder(boxHolder)._1
- val id = modifierIdGen.sample.get
- BlockTransactions(id, 1: Byte, txs)
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/sanity/ErgoSanityUTXO.scala b/ergo-core/src/test/scala/org/ergoplatform/sanity/ErgoSanityUTXO.scala
deleted file mode 100644
index ef6107e35b..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/sanity/ErgoSanityUTXO.scala
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.ergoplatform.sanity
-
-import akka.actor.{ActorRef, ActorSystem, Props}
-import akka.testkit.TestProbe
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.BlockTransactions
-import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.{ChangedHistory, ChangedMempool}
-import org.ergoplatform.network.ErgoSyncTracker
-import org.ergoplatform.nodeView.history.ErgoSyncInfoMessageSpec
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
-import org.ergoplatform.sanity.ErgoSanity._
-import org.ergoplatform.settings.ErgoSettings
-import org.ergoplatform.utils.ErgoTestHelpers
-import org.scalacheck.Gen
-import scorex.core.network.{ConnectedPeer, DeliveryTracker}
-import scorex.core.network.peer.PeerInfo
-import scorex.core.serialization.ErgoSerializer
-
-import scala.concurrent.ExecutionContextExecutor
-
-class ErgoSanityUTXO extends ErgoSanity[UTXO_ST] with ErgoTestHelpers {
-
- override val historyGen: Gen[HT] =
- generateHistory(verifyTransactions = true, StateType.Utxo, PoPoWBootstrap = false, blocksToKeep = -1)
-
- override val stateGen: Gen[WrappedUtxoState] =
- boxesHolderGen.map(WrappedUtxoState(_, createTempDir, None, parameters, settings))
-
- override def semanticallyValidModifier(state: UTXO_ST): PM = {
- statefulyValidFullBlock(state.asInstanceOf[WrappedUtxoState])
- }
-
- override def semanticallyInvalidModifier(state: UTXO_ST): PM = invalidErgoFullBlockGen.sample.get
-
- override def totallyValidModifier(history: HT, state: UTXO_ST): PM = {
- val parentOpt = history.bestFullBlockOpt
- validFullBlock(parentOpt, state.asInstanceOf[WrappedUtxoState]).header
- }
-
- override def totallyValidModifiers(history: HT, state: UTXO_ST, count: Int): Seq[PM] = {
- require(count >= 1)
- val headerOpt = history.bestFullBlockOpt
- (0 until count).foldLeft((headerOpt, Seq.empty[PM])) { case (acc, _) =>
- val pm = validFullBlock(headerOpt, state.asInstanceOf[WrappedUtxoState])
- (Some(pm), acc._2 :+ pm)
- }._2.map(_.asInstanceOf[ErgoFullBlock].header)
- }
-
- override def nodeViewSynchronizer(implicit system: ActorSystem):
- (ActorRef, SI, PM, TX, ConnectedPeer, TestProbe, TestProbe, TestProbe, TestProbe, ErgoSerializer[PM]) = {
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val h = historyGen.sample.get
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val s = stateGen.sample.get
- val settings = ErgoSettings.read()
- val pool = ErgoMemPool.empty(settings)
- implicit val ec: ExecutionContextExecutor = system.dispatcher
- val ncProbe = TestProbe("NetworkControllerProbe")
- val vhProbe = TestProbe("ViewHolderProbe")
- val pchProbe = TestProbe("PeerHandlerProbe")
- val eventListener = TestProbe("EventListener")
- val syncTracker = ErgoSyncTracker(settings.scorexSettings.network)
- val deliveryTracker: DeliveryTracker = DeliveryTracker.empty(settings)
- val ref = system.actorOf(Props(
- new SyncronizerMock(
- ncProbe.ref,
- vhProbe.ref,
- ErgoSyncInfoMessageSpec,
- settings,
- syncTracker,
- deliveryTracker)
- ))
- val m = totallyValidModifier(h, s)
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val tx = validErgoTransactionGenTemplate(minAssets = 0, maxAssets = 0).sample.get._2
-
-
- val peerInfo = PeerInfo(defaultPeerSpec, System.currentTimeMillis(), None, 0L)
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val p: ConnectedPeer = ConnectedPeer(
- connectionIdGen.sample.get,
- pchProbe.ref,
- Some(peerInfo)
- )
- ref ! ChangedHistory(h)
- ref ! ChangedMempool(pool)
- val serializer: ErgoSerializer[PM] = HeaderSerializer.asInstanceOf[ErgoSerializer[PM]]
- (ref, h.syncInfoV1, m, tx, p, pchProbe, ncProbe, vhProbe, eventListener, serializer)
- }
-
- override def modifierWithTransactions(memoryPoolOpt: Option[MPool], customTransactionsOpt: Option[Seq[TX]]): CTM = {
- val boxHolder = boxesHolderGen.sample.get
- val txs = validTransactionsFromBoxHolder(boxHolder)._1
- val id = modifierIdGen.sample.get
- BlockTransactions(id, Header.InitialVersion, txs)
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/serialization/ErgoBoxSerializerSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/serialization/ErgoBoxSerializerSpec.scala
deleted file mode 100644
index 7fdf9d2c17..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/serialization/ErgoBoxSerializerSpec.scala
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.ergoplatform.serialization
-
-import org.ergoplatform.ErgoBox
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.ergoplatform.wallet.boxes.ErgoBoxSerializer
-import scorex.util.serialization.VLQByteStringWriter
-import scala.util.Try
-
-class ErgoBoxSerializerSpec extends ErgoPropertyTest {
-
- property("ErgoBox serialization") {
- forAll(ergoBoxGen) { b: ErgoBox =>
- val bs = ErgoBoxSerializer.toBytes(b)
- val b2 = ErgoBoxSerializer.parseBytes(bs)
- b shouldBe b2
- }
- }
-
- property("creation height overflow") {
- // helper method which creates bypassing Scala API, via changing binary representation
- def overflowHeight(box: ErgoBox): Try[ErgoBox] = {
- val hBytes = (new VLQByteStringWriter).putUInt(box.creationHeight).toBytes
-
- val bs = ErgoBoxSerializer.toBytes(box)
- val pos = bs.indexOfSlice(hBytes, 0)
-
- val before = bs.slice(0, pos)
- val after = bs.slice(pos + hBytes.length, bs.length)
-
- val overflowHeight = 0xFFFFFFFFL
- val overBytes = (new VLQByteStringWriter).putUInt(overflowHeight).toBytes
-
- ErgoBoxSerializer.parseBytesTry(before ++ overBytes ++ after)
- }
-
- forAll(ergoBoxGen) { b: ErgoBox =>
- val h = Int.MaxValue
- val ob = new ErgoBox(b.value, b.ergoTree, b.additionalTokens, b.additionalRegisters, b.transactionId, b.index, h)
- // starting from 5.0.0 sigma interpreter, Int overflow is thrown
- overflowHeight(ob).isFailure shouldBe true
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/serialization/JsonSerializationSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/serialization/JsonSerializationSpec.scala
deleted file mode 100644
index 016696d708..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/serialization/JsonSerializationSpec.scala
+++ /dev/null
@@ -1,195 +0,0 @@
-package org.ergoplatform.serialization
-
-import io.circe.syntax._
-import io.circe.{ACursor, Decoder, Encoder, Json}
-import org.ergoplatform.ErgoBox
-import org.ergoplatform.ErgoBox.{AdditionalRegisters, NonMandatoryRegisterId}
-import org.ergoplatform.http.api.ApiCodecs
-import org.ergoplatform.http.api.ApiEncoderOption.HideDetails.implicitValue
-import org.ergoplatform.http.api.ApiEncoderOption.{Detalization, ShowDetails}
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.popow.NipopowProof
-import org.ergoplatform.modifiers.mempool.UnsignedErgoTransaction
-import org.ergoplatform.nodeView.wallet.requests._
-import org.ergoplatform.sdk.wallet.secrets.{DhtSecretKey, DlogSecretKey}
-import org.ergoplatform.settings.{Algos, ErgoSettings}
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.ergoplatform.utils.generators.WalletGenerators
-import org.ergoplatform.wallet.Constants.ScanId
-import org.ergoplatform.wallet.boxes.TrackedBox
-import org.scalatest.Inspectors
-import sigmastate.SType
-import sigmastate.Values.{ErgoTree, EvaluatedValue}
-
-import scala.util.Random
-
-
-class JsonSerializationSpec extends ErgoPropertyTest with WalletGenerators with ApiCodecs {
-
- property("ErgoFullBlock should be encoded into JSON and decoded back correctly") {
-
- val (st, bh) = createUtxoState(settings)
- val block: ErgoFullBlock = validFullBlock(parentOpt = None, st, bh)
-
- val blockJson: Json = block.asJson
- val blockDecoded: ErgoFullBlock = blockJson.as[ErgoFullBlock].toTry.get
-
- blockDecoded shouldEqual block
- }
-
- property("ErgoBox should be converted into json correctly") {
- forAll(ergoBoxGen) { box =>
- checkErgoBox(box.asJson.hcursor, box)
- }
- }
-
- property("TrackedBox should be serialized to json") {
- forAll(trackedBoxGen) { b =>
- checkTrackedBox(b.asJson.hcursor, b)
- import ShowDetails.implicitValue
- checkTrackedBox(b.asJson.hcursor, b)
- }
- }
-
- property("PaymentRequest should be serialized to json") {
- val ergoSettings = ErgoSettings.read()
- implicit val requestEncoder: Encoder[PaymentRequest] = new PaymentRequestEncoder(ergoSettings)
- implicit val requestDecoder: Decoder[PaymentRequest] = new PaymentRequestDecoder(ergoSettings)
- forAll(paymentRequestGen) { request =>
- val json = request.asJson
- val parsingResult = json.as[PaymentRequest]
- parsingResult.isRight shouldBe true
- val restored = parsingResult.value
- restored.address shouldEqual request.address
- restored.value shouldEqual request.value
- restored.registers shouldEqual request.registers
- Inspectors.forAll(restored.assets.zip(request.assets)) {
- case ((restoredToken, restoredValue), (requestToken, requestValue)) =>
- restoredToken shouldEqual requestToken
- restoredValue shouldEqual requestValue
- }
- }
- }
-
- property("BurnTokensRequest should be serialized to json") {
- implicit val requestEncoder: Encoder[BurnTokensRequest] = new BurnTokensRequestEncoder()
- implicit val requestDecoder: Decoder[BurnTokensRequest] = new BurnTokensRequestDecoder()
- forAll(burnTokensRequestGen) { request =>
- val json = request.asJson
- val parsingResult = json.as[BurnTokensRequest]
- parsingResult.isRight shouldBe true
- val restored = parsingResult.value
- Inspectors.forAll(restored.assetsToBurn.zip(request.assetsToBurn)) {
- case ((restoredToken, restoredValue), (requestToken, requestValue)) =>
- restoredToken shouldEqual requestToken
- restoredValue shouldEqual requestValue
- }
- }
- }
-
- property("AssetIssueRequest should be serialized to json") {
- val ergoSettings = ErgoSettings.read()
- implicit val requestEncoder: Encoder[AssetIssueRequest] = new AssetIssueRequestEncoder(ergoSettings)
- implicit val requestDecoder: Decoder[AssetIssueRequest] = new AssetIssueRequestDecoder(ergoSettings)
- forAll(assetIssueRequestGen) { request =>
- val json = request.asJson
- val parsingResult = json.as[AssetIssueRequest]
- parsingResult.isRight shouldBe true
- val restored = parsingResult.value
- restored.addressOpt shouldEqual request.addressOpt
- restored.amount shouldEqual request.amount
- restored.name shouldEqual request.name
- restored.description shouldEqual request.description
- restored.decimals shouldEqual request.decimals
- }
- }
-
- property("json-encoded dlog secret is always about 32 bytes") {
- forAll(dlogSecretWithPublicImageGen) { case (secret, _) =>
- val wrappedSecret = DlogSecretKey(secret)
- val json = wrappedSecret.asJson
- json.toString().length shouldBe 66 // 32-bytes hex-encoded data (64 ASCII chars) + quotes == 66 ASCII chars
- }
- }
-
- property("dlog secret roundtrip") {
- forAll(dlogSecretWithPublicImageGen) { case (secret, _) =>
- val wrappedSecret = DlogSecretKey(secret)
- val json = wrappedSecret.asJson
- val parsedSecret = json.as[DlogSecretKey].toOption.get
- parsedSecret shouldBe wrappedSecret
- }
- }
-
- property("dht secret roundtrip") {
- forAll(dhtSecretWithPublicImageGen) { case (secret, _) =>
- val wrappedSecret = DhtSecretKey(secret)
- val json = wrappedSecret.asJson
- val parsedSecret = json.as[DhtSecretKey].toOption.get
- parsedSecret shouldBe wrappedSecret
- }
- }
-
- property("transactionSigningRequest roundtrip") {
- forAll(transactionSigningRequestGen(Random.nextBoolean)) { request =>
- val json = request.asJson
- val parsedRequest = json.as[TransactionSigningRequest].toOption.get
- parsedRequest shouldBe request
- }
- }
-
- property("unsignedErgoTransaction roundtrip") {
- forAll(validUnsignedErgoTransactionGen) { case (_, tx) =>
- val json = tx.asJson
- val parsedTx = json.as[UnsignedErgoTransaction].toOption.get
- parsedTx shouldBe tx
- }
- }
-
- property("PopowProof roundtrip"){
- forAll(poPowProofGen){ pp =>
- val json = pp.asJson
- implicit val decoder: Decoder[NipopowProof] = NipopowProof.nipopowProofDecoder(nipopowAlgos)
- val parsedProof = json.as[NipopowProof].toOption.get
- parsedProof shouldEqual pp
- }
- }
-
- private def checkTrackedBox(c: ACursor, b: TrackedBox)(implicit opts: Detalization) = {
- c.downField("spent").as[Boolean] shouldBe Right(b.spendingStatus.spent)
- c.downField("onchain").as[Boolean] shouldBe Right(b.chainStatus.onChain)
- c.downField("scans").as[Set[ScanId]] shouldBe Right(b.scans)
- c.downField("creationOutIndex").as[Short] shouldBe Right(b.creationOutIndex)
- c.downField("inclusionHeight").as[Option[Int]] shouldBe Right(b.inclusionHeightOpt)
- c.downField("spendingHeight").as[Option[Int]] shouldBe Right(b.spendingHeightOpt)
- checkErgoBox(c.downField("box"), b.box)
- if (!opts.showDetails) {
- c.downField("creationTransactionId").as[String] shouldBe Right(b.creationTxId)
- c.downField("spendingTransactionId").as[Option[String]] shouldBe Right(b.spendingTxIdOpt)
- }
- }
-
- private def checkErgoBox(c: ACursor, b: ErgoBox): Unit = {
- c.downField("boxId").as[String] shouldBe Right(Algos.encode(b.id))
- c.downField("value").as[Long] shouldBe Right(b.value)
- c.downField("ergoTree").as[ErgoTree] shouldBe Right(b.ergoTree)
- checkAssets(c.downField("assets"), b.additionalTokens.toArray.toSeq)
- checkRegisters(c.downField("additionalRegisters"), b.additionalRegisters)
- c.downField("creationHeight").as[Int] shouldBe Right(b.creationHeight)
- }
-
- private def checkAssets(c: ACursor, assets: Seq[(ErgoBox.TokenId, Long)]) = {
- def stringify(assets: Seq[(ErgoBox.TokenId, Long)]) = {
- assets map { case (tokenId, amount) => (Algos.encode(tokenId), amount) }
- }
-
- val Right(decodedAssets) = c.as[Seq[(ErgoBox.TokenId, Long)]]
- stringify(decodedAssets) should contain theSameElementsAs stringify(assets)
- }
-
- private def checkRegisters(c: ACursor, registers: AdditionalRegisters) = {
- val Right(decodedRegs) = c.as[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]]
- decodedRegs should contain theSameElementsAs registers
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/serialization/SerializationTests.scala b/ergo-core/src/test/scala/org/ergoplatform/serialization/SerializationTests.scala
deleted file mode 100644
index 65ac78905d..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/serialization/SerializationTests.scala
+++ /dev/null
@@ -1,124 +0,0 @@
-package org.ergoplatform.serialization
-
-import org.ergoplatform.modifiers.ErgoNodeViewModifier
-import org.ergoplatform.modifiers.history._
-import org.ergoplatform.modifiers.history.extension.ExtensionSerializer
-import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer}
-import org.ergoplatform.modifiers.history.popow.NipopowProofSerializer
-import org.ergoplatform.modifiers.mempool.ErgoTransactionSerializer
-import org.ergoplatform.nodeView.history.ErgoSyncInfoSerializer
-import org.ergoplatform.nodeView.wallet.persistence.WalletDigestSerializer
-import org.ergoplatform.nodeView.state.ErgoStateContextSerializer
-import org.ergoplatform.settings.{Constants, ErgoValidationSettings, ErgoValidationSettingsSerializer, ErgoValidationSettingsUpdateSerializer}
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.ergoplatform.utils.generators.WalletGenerators
-import org.scalacheck.Gen
-import org.scalatest.Assertion
-import scorex.core.serialization.ErgoSerializer
-
-class SerializationTests extends ErgoPropertyTest with WalletGenerators with scorex.testkit.SerializationTests {
-
- def checkSerializationRoundtripAndSize[A <: ErgoNodeViewModifier](generator: Gen[A],
- serializer: ErgoSerializer[A]): Assertion = {
- forAll(generator) { b: A =>
- val recovered = serializer.parseBytes(serializer.toBytes(b))
- val bytes = serializer.toBytes(b)
- bytes shouldEqual serializer.toBytes(recovered)
- }
- }
-
- property("Serializers should be defined for all block sections") {
- val block = invalidErgoFullBlockGen.sample.get
- block.toSeq.foreach { s =>
- Constants.modifierSerializers.get(s.modifierTypeId) should not be None
- }
- }
-
- property("PoPowProof serialization") {
- checkSerializationRoundtrip(poPowProofGen, new NipopowProofSerializer(nipopowAlgos))
- }
-
- property("Header serialization") {
- val serializer = HeaderSerializer
- forAll(invalidHeaderGen) { b: Header =>
- val recovered = serializer.parseBytes(serializer.toBytes(b))
- recovered shouldBe b
- recovered.size shouldBe serializer.toBytes(b).length
- }
- }
-
- property("ErgoStateContext serialization") {
- val serializer = ErgoStateContextSerializer(settings)
- val b = ergoStateContextGen.sample.get
- val recovered = serializer.parseBytes(serializer.toBytes(b))
- serializer.toBytes(b) shouldEqual serializer.toBytes(recovered)
- b.lastHeaders.length shouldBe recovered.lastHeaders.length
- b.lastHeaders shouldBe recovered.lastHeaders
- }
-
- property("Extension serialization") {
- checkSerializationRoundtrip(extensionGen, ExtensionSerializer)
- }
-
- property("ErgoTransactionGen serialization") {
- checkSerializationRoundtripAndSize(invalidErgoTransactionGen, ErgoTransactionSerializer)
- }
-
- property("ErgoTransaction .bytes") {
- forAll(invalidErgoTransactionGen) { tx =>
- val bytes = tx.bytes
- val txRestored = ErgoTransactionSerializer.parseBytes(bytes)
- txRestored.bytes.sameElements(bytes) shouldBe true
- }
- }
-
- property("ErgoSyncInfo v1 serialization") {
- checkSerializationRoundtrip(ergoSyncInfoV1Gen, ErgoSyncInfoSerializer)
- }
-
- property("ErgoSyncInfo v2 serialization") {
- checkSerializationRoundtrip(ergoSyncInfoV2Gen, ErgoSyncInfoSerializer)
- }
-
- property("ErgoHeader serialization") {
- checkSerializationRoundtripAndSize(defaultHeaderGen, HeaderSerializer)
- }
-
- property("BlockTransactions serialization") {
- checkSerializationRoundtripAndSize(invalidBlockTransactionsGen, BlockTransactionsSerializer)
- }
-
- property("ADProofs serialization") {
- checkSerializationRoundtripAndSize(randomADProofsGen, ADProofsSerializer)
- }
-
- property("ModeFeature serialization") {
- forAll(modeFeatureGen) { mf =>
- mf.serializer.parseBytes(mf.serializer.toBytes(mf)) shouldEqual mf
- }
- }
-
- property("ErgoValidationSettings serialization") {
- val serializer = ErgoValidationSettingsSerializer
- forAll(ergoValidationSettingsGen) { vs =>
- // to bytes / from bytes
- serializer.parseBytes(serializer.toBytes(vs)) shouldEqual vs
- // to extension / from extension
- ErgoValidationSettings.parseExtension(vs.toExtensionCandidate).get shouldEqual vs
- }
- }
-
- property("ErgoValidationSettingsUpdate serialization") {
- val serializer = ErgoValidationSettingsUpdateSerializer
- forAll(ergoValidationSettingsUpdateGen) { vs =>
- serializer.parseBytes(serializer.toBytes(vs)) shouldEqual vs
- }
- }
-
- property("WalletDigest serialization") {
- forAll(registrySummaryGen) { index =>
- WalletDigestSerializer.parseBytes(WalletDigestSerializer.toBytes(index)) shouldEqual index
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/settings/ErgoSettingsSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/settings/ErgoSettingsSpecification.scala
deleted file mode 100644
index e222ec2d88..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/settings/ErgoSettingsSpecification.scala
+++ /dev/null
@@ -1,178 +0,0 @@
-package org.ergoplatform.settings
-
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.SortingOption
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.core.settings.RESTApiSettings
-
-import java.net.{InetSocketAddress, URL}
-import scala.concurrent.duration._
-
-class ErgoSettingsSpecification extends ErgoPropertyTest {
-
- private val txCostLimit = initSettings.nodeSettings.maxTransactionCost
- private val txSizeLimit = initSettings.nodeSettings.maxTransactionSize
-
- property("should keep data user home by default") {
- val settings = ErgoSettings.read()
- settings.directory shouldBe System.getProperty("user.dir") + "/.ergo_test/data"
- }
-
- property("should read default settings") {
- val settings = ErgoSettings.read()
- settings.nodeSettings shouldBe NodeConfigurationSettings(
- StateType.Utxo,
- verifyTransactions = true,
- 1000,
- utxoSettings = UtxoSettings(false, 0, 2),
- nipopowSettings = NipopowSettings(false, 1),
- mining = true,
- txCostLimit,
- txSizeLimit,
- useExternalMiner = false,
- internalMinersCount = 1,
- internalMinerPollingInterval = 1.second,
- miningPubKeyHex = None,
- offlineGeneration = false,
- keepVersions = 200,
- acceptableChainUpdateDelay = 30.minutes,
- mempoolCapacity = 100000,
- mempoolCleanupDuration = 10.seconds,
- mempoolSorting = SortingOption.FeePerByte,
- rebroadcastCount = 3,
- minimalFeeAmount = 0,
- headerChainDiff = 100,
- adProofsSuffixLength = 112*1024,
- extraIndex = false
- )
- settings.cacheSettings shouldBe CacheSettings(
- HistoryCacheSettings(
- 12, 1000, 100, 1000
- ),
- NetworkCacheSettings(
- invalidModifiersCacheSize = 10000,
- invalidModifiersCacheExpiration = 6.hours,
- ),
- MempoolCacheSettings(
- invalidModifiersCacheSize = 10000,
- invalidModifiersCacheExpiration = 6.hours,
- )
- )
- settings.scorexSettings.restApi shouldBe RESTApiSettings(
- bindAddress = new InetSocketAddress("0.0.0.0", 9052),
- apiKeyHash = None,
- corsAllowedOrigin = Some("*"),
- timeout = 5.seconds,
- publicUrl = Some(new URL("https://example.com:80"))
- )
- }
-
- property("should read user settings from json file") {
- val settings = ErgoSettings.read(Args(Some("src/test/resources/settings.json"), None))
- settings.nodeSettings shouldBe NodeConfigurationSettings(
- StateType.Utxo,
- verifyTransactions = true,
- 12,
- utxoSettings = UtxoSettings(false, 0, 2),
- nipopowSettings = NipopowSettings(false, 1),
- mining = true,
- txCostLimit,
- txSizeLimit,
- useExternalMiner = false,
- internalMinersCount = 1,
- internalMinerPollingInterval = 1.second,
- miningPubKeyHex = None,
- offlineGeneration = false,
- keepVersions = 200,
- acceptableChainUpdateDelay = 30.minutes,
- mempoolCapacity = 100000,
- mempoolCleanupDuration = 10.seconds,
- mempoolSorting = SortingOption.FeePerByte,
- rebroadcastCount = 3,
- minimalFeeAmount = 0,
- headerChainDiff = 100,
- adProofsSuffixLength = 112*1024,
- extraIndex = false
- )
- settings.cacheSettings shouldBe CacheSettings(
- HistoryCacheSettings(
- 12, 1000, 100, 1000
- ),
- NetworkCacheSettings(
- invalidModifiersCacheSize = 10000,
- invalidModifiersCacheExpiration = 6.hours,
- ),
- MempoolCacheSettings(
- invalidModifiersCacheSize = 10000,
- invalidModifiersCacheExpiration = 6.hours,
- )
- )
- }
-
- property("should read user settings from HOCON file") {
- val settings = ErgoSettings.read(Args(Some("src/test/resources/settings.conf"), None))
- settings.nodeSettings shouldBe NodeConfigurationSettings(
- StateType.Utxo,
- verifyTransactions = true,
- 13,
- utxoSettings = UtxoSettings(false, 0, 2),
- nipopowSettings = NipopowSettings(false, 1),
- mining = true,
- txCostLimit,
- txSizeLimit,
- useExternalMiner = false,
- internalMinersCount = 1,
- internalMinerPollingInterval = 1.second,
- miningPubKeyHex = None,
- offlineGeneration = false,
- keepVersions = 200,
- acceptableChainUpdateDelay = 30.minutes,
- mempoolCapacity = 100000,
- mempoolCleanupDuration = 10.seconds,
- mempoolSorting = SortingOption.FeePerByte,
- rebroadcastCount = 3,
- minimalFeeAmount = 0,
- headerChainDiff = 100,
- adProofsSuffixLength = 112*1024,
- extraIndex = false
- )
- settings.cacheSettings shouldBe CacheSettings(
- HistoryCacheSettings(
- 12, 1000, 100, 1000
- ),
- NetworkCacheSettings(
- invalidModifiersCacheSize = 10000,
- invalidModifiersCacheExpiration = 6.hours,
- ),
- MempoolCacheSettings(
- invalidModifiersCacheSize = 10000,
- invalidModifiersCacheExpiration = 6.hours,
- )
- )
- }
-
- property("scorex.restApi.publicUrl should be valid") {
- val invalidUrls =
- List(
- "http:invalid",
- "http://localhost",
- "http://127.0.0.1",
- "http://0.0.0.0",
- "http://example.com/foo/bar",
- "http://example.com?foo=bar"
- ).map(new URL(_))
-
- invalidUrls.forall(ErgoSettings.invalidRestApiUrl) shouldBe true
-
- val validUrls =
- List(
- "http://example.com",
- "http://example.com:80",
- "http://82.90.21.31",
- "http://82.90.21.31:80"
- ).map(new URL(_))
-
- validUrls.forall(url => !ErgoSettings.invalidRestApiUrl(url)) shouldBe true
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/settings/VotingSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/settings/VotingSpecification.scala
deleted file mode 100644
index 2923aa7b31..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/settings/VotingSpecification.scala
+++ /dev/null
@@ -1,351 +0,0 @@
-package org.ergoplatform.settings
-
-import org.ergoplatform.modifiers.history.extension.ExtensionCandidate
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.nodeView.state.{ErgoStateContext, VotingData}
-import org.ergoplatform.settings.ValidationRules.rulesSpec
-import org.ergoplatform.utils.ErgoPropertyTest
-import org.ergoplatform.validation.{DisabledRule, ReplacedRule, ValidationRules => VR}
-import scorex.crypto.authds.ADDigest
-
-import scala.util.Try
-
-class VotingSpecification extends ErgoPropertyTest {
-
- import Parameters._
-
- private val headerId = scorex.util.bytesToId(Array.fill(32)(0: Byte))
-
- private val votingEpochLength = 2
-
- private val hfActivationHeight = 100
-
- private val hfActivationDifficultyHex = "01"
-
- override implicit val votingSettings: VotingSettings =
- VotingSettings(
- votingEpochLength,
- softForkEpochs = 2,
- activationEpochs = 3,
- version2ActivationHeight = hfActivationHeight,
- version2ActivationDifficultyHex = hfActivationDifficultyHex
- )
-
- private val updSettings = settings.copy(chainSettings = settings.chainSettings.copy(voting = votingSettings))
-
- private val proposedUpdate = ErgoValidationSettingsUpdate(
- Seq(ValidationRules.exDuplicateKeys, ValidationRules.exValueLength),
- Seq(VR.CheckDeserializedScriptType.id -> DisabledRule, VR.CheckValidOpCode.id -> ReplacedRule((VR.FirstRuleId + 11).toShort)))
- private val proposedUpdate2 = ErgoValidationSettingsUpdate(Seq(ValidationRules.fbOperationFailed), Seq())
- val ctx: ErgoStateContext = {
- new ErgoStateContext(Seq.empty, None, genesisStateDigest, parameters, validationSettingsNoIl, VotingData.empty)(updSettings)
- .upcoming(org.ergoplatform.mining.group.generator, 0L, settings.chainSettings.initialNBits, Array.fill(3)(0.toByte), emptyVSUpdate, 0.toByte)
- }
- val initialVs: ErgoValidationSettings = ctx.validationSettings
- val extensionWithAllParams: ExtensionCandidate = {
- parameters.toExtensionCandidate ++ initialVs.toExtensionCandidate
- }
-
- val emptyParameters = Parameters(0, Map.empty, ErgoValidationSettingsUpdate.empty)
-
- property("correct rule ids") {
- rulesSpec foreach { r =>
- r._1 < org.ergoplatform.validation.ValidationRules.FirstRuleId shouldBe true
- }
- }
-
- property("ErgoValidationSettings toExtension/fromExtension roundtrip") {
- // initial settings should not be written into Extension at all
- val initial = ErgoValidationSettings.initial
- val extension = initial.toExtensionCandidate
- extension.fields.size shouldBe 0
- initial shouldBe ErgoValidationSettings.parseExtension(extension).get
-
- forAll(ergoValidationSettingsGen) { vs =>
- val extension = vs.toExtensionCandidate
- vs shouldBe ErgoValidationSettings.parseExtension(extension).get
- }
- }
-
- property("Parameters should be defined at the beginning of the epoch") {
- val chain = genChain(votingEpochLength * 4).map { b =>
- if (b.header.votingStarts(votingEpochLength)) {
- b.copy(extension = extensionWithAllParams.toExtension(b.header.id))
- } else {
- b
- }
- }
- val validChain = chain.init
- val lastBlock = chain.last
- val invalidExtBlock1 = { // extension does not contain all required params
- lastBlock.copy(extension = lastBlock.extension.copy(
- fields = Seq(Array(0: Byte, 1: Byte) -> Array.fill(4)(2: Byte)))
- )
- }
- val invalidExtBlock2 = { // extension contains redundant parameter
- lastBlock.copy(extension = lastBlock.extension.copy(
- fields = parameters.toExtensionCandidate.fields :+ Array(0: Byte, 99: Byte) -> Array.fill(4)(2: Byte))
- )
- }
- val invalidExtBlock3 = { // extension does not contain params at all
- lastBlock.copy(extension = lastBlock.extension.copy(fields = Seq()))
- }
- val validCtx = validChain.foldLeft(ctx)((acc, mod) => acc.appendFullBlock(mod).get)
- validCtx.appendFullBlock(invalidExtBlock1) shouldBe 'failure
- validCtx.appendFullBlock(invalidExtBlock2) shouldBe 'failure
- validCtx.appendFullBlock(invalidExtBlock3) shouldBe 'failure
- validCtx.appendFullBlock(lastBlock) shouldBe 'success
- }
-
- property("voting for non-existing parameter") {
- val p: Parameters = Parameters(2, Map(BlockVersion -> 0), proposedUpdate)
- val vr: VotingData = VotingData.empty
- val esc = new ErgoStateContext(Seq(), None, ADDigest @@ Array.fill(33)(0: Byte), p, validationSettingsNoIl, vr)(updSettings)
- val invalidVote = 100: Byte
- val votes = Array(invalidVote , NoParameter, NoParameter)
-
- // voting for non-existing param is okay if not start of an epoch
- val h = defaultHeaderGen.sample.get.copy(height = 1, votes = votes, version = 0: Byte)
- val esc2 = esc.appendHeader(h).get
-
- // proposing a vote for non-existing param is not allowed
- val h2 = defaultHeaderGen.sample.get.copy(height = 2, votes = votes, version = 0: Byte)
- esc2.appendHeader(h2).toEither.left.get.getMessage.contains("Incorrect vote") shouldBe true
- }
-
- //Simple checks for votes in header could be found also in NonVerifyADHistorySpecification("Header votes")
- property("simple voting - start - conditions") {
- val kInit = 1000000
-
- val p: Parameters = Parameters(2, Map(StorageFeeFactorIncrease -> kInit, BlockVersion -> 0), proposedUpdate)
- val vr: VotingData = VotingData.empty
- val esc = new ErgoStateContext(Seq(), None, ADDigest @@ Array.fill(33)(0: Byte), p, validationSettingsNoIl, vr)(updSettings)
- val votes = Array(StorageFeeFactorIncrease, NoParameter, NoParameter)
- val h = defaultHeaderGen.sample.get.copy(height = 2, votes = votes, version = 0: Byte)
- val esc2 = process(esc, p, h).get
-
- //no quorum gathered - no parameter change
- val he = defaultHeaderGen.sample.get.copy(votes = Array.fill(3)(NoParameter), version = 0: Byte)
- val esc30 = process(esc2, p, he).get
- val esc40 = process(esc30, p, he).get
- esc40.currentParameters.storageFeeFactor shouldBe kInit
-
- //quorum gathered - parameter change
- val esc31 = process(esc2, p, h.copy(height = 3)).get
- esc31.votingData.epochVotes.find(_._1 == StorageFeeFactorIncrease).get._2 shouldBe 2
-
- val p4 = Parameters(4, Map(StorageFeeFactorIncrease -> (kInit + Parameters.StorageFeeFactorStep), BlockVersion -> 0), proposedUpdate)
- val esc41 = process(esc31, p4, he.copy(height = 4)).get
- esc41.currentParameters.storageFeeFactor shouldBe (kInit + Parameters.StorageFeeFactorStep)
- }
-
- /**
- * A test which is ensuring that approved soft-fork activates properly.
- * For the test, we have:
- * - epoch length is about 2 blocks
- * - 2 epochs to vote
- * - 3 epochs to activate the fork
- *
- * So the fork would be activated only if 4 votes out of 4 are for it.
- */
- property("soft fork - w. activation") {
-
- val p: Parameters = Parameters(1, Map(BlockVersion -> 0), proposedUpdate)
- val vr: VotingData = VotingData.empty
- val esc0 = new ErgoStateContext(Seq(), None, ADDigest @@ Array.fill(33)(0: Byte), p, validationSettings, vr)(updSettings)
- checkValidationSettings(esc0.validationSettings, emptyVSUpdate)
- val forkVote = Array(SoftFork, NoParameter, NoParameter)
- val emptyVotes = Array(NoParameter, NoParameter, NoParameter)
-
- val h1 = defaultHeaderGen.sample.get.copy(height = 1)
- val esc1 = process(esc0, p, h1).get
-
- // Soft-fork vote is proposed @ height == 2
- val h2 = defaultHeaderGen.sample.get.copy(votes = forkVote, version = 0: Byte, height = 2)
- val expectedParameters2 = Parameters(2, Map(SoftForkStartingHeight -> 2, SoftForkVotesCollected -> 0, BlockVersion -> 0), proposedUpdate)
- val esc2 = process(esc1, expectedParameters2, h2).get
- esc2.currentParameters.softForkStartingHeight.get shouldBe 2
- esc2.currentParameters.proposedUpdate shouldBe proposedUpdate
- checkValidationSettings(esc2.validationSettings, emptyVSUpdate)
-
- // voting for the fork @ height == 3
- val h3 = h2.copy(height = 3)
-
- val expectedParameters3 = Parameters(2, Map(SoftForkStartingHeight -> 2, SoftForkVotesCollected -> 1, BlockVersion -> 0), proposedUpdate)
- val esc3 = process(esc2, expectedParameters3, h3).get
- esc3.currentParameters.softForkStartingHeight.get shouldBe 2
- esc3.currentParameters.proposedUpdate shouldBe proposedUpdate
- checkValidationSettings(esc3.validationSettings, emptyVSUpdate)
-
- // voting for the fork @ height == 4
- // new epoch is starting, thus the block should contain number of votes for the fork collected in the previous epoch
- val h4 = h3.copy(height = 4)
- val expectedParameters4 = Parameters(4, Map(SoftForkStartingHeight -> 2, SoftForkVotesCollected -> 2, BlockVersion -> 0), proposedUpdate)
- val esc4 = process(esc3, expectedParameters4, h4).get
-
- esc4.currentParameters.softForkStartingHeight.get shouldBe 2
- esc4.currentParameters.softForkVotesCollected.get shouldBe 2
- esc4.currentParameters.proposedUpdate shouldBe proposedUpdate
- checkValidationSettings(esc4.validationSettings, emptyVSUpdate)
-
- // voting for the fork @ height == 5
- val h5 = h4.copy(height = 5)
- val expectedParameters5 = Parameters(4, Map(SoftForkStartingHeight -> 2, SoftForkVotesCollected -> 3, BlockVersion -> 0), proposedUpdate)
- val esc5 = process(esc4, expectedParameters5, h5).get
- checkValidationSettings(esc5.validationSettings, emptyVSUpdate)
-
- // voting is finished, and we check collected votes @ height == 6
- val h6 = h5.copy(height = 6, votes = emptyVotes)
- val expectedParameters6 = Parameters(6, Map(SoftForkStartingHeight -> 2, SoftForkVotesCollected -> 4, BlockVersion -> 0), proposedUpdate)
- val esc6 = process(esc5, expectedParameters6, h6).get
- checkValidationSettings(esc5.validationSettings, emptyVSUpdate)
-
- // voting for soft-fork is prohibited @ height == 6
- val h6w = h5.copy(height = 6)
- process(esc5, expectedParameters6, h6w).isFailure shouldBe true
-
- val esc11 = (7 to 11).foldLeft(esc6) { case (esc, i) =>
- // voting for soft-fork is prohibited during activation period
- val hw = h6.copy(height = i, votes = forkVote)
- process(esc, expectedParameters6, hw).isFailure shouldBe true
-
- val h = h6.copy(height = i)
-
- process(esc, expectedParameters6, h).get
- }
-
- // activation period done @ height = 12, block version is increased, rules to disable are disabled
- val h12 = h6.copy(height = 12, version = 1: Byte)
- val expectedParameters12 = Parameters(12, Map(SoftForkStartingHeight -> 2, SoftForkVotesCollected -> 4, BlockVersion -> 1), proposedUpdate)
-
- val esc12 = process(esc11, expectedParameters12, h12).get
- checkValidationSettings(esc12.validationSettings, proposedUpdate)
-
- // vote for soft-fork @ activation height
- val h12w = h12.copy(votes = forkVote)
- process(esc11, expectedParameters12, h12w).isFailure shouldBe true
-
- val h13 = h12.copy(height = 13)
- val esc13 = process(esc12, expectedParameters12, h13).get
-
- // vote for soft-fork is prohibited before next epoch after activation height
- val h13w = h13.copy(votes = forkVote)
- process(esc12, expectedParameters12, h13w).isFailure shouldBe true
-
- // voting for soft-fork is possible on the first block of the next epoch after activation height
- val h14 = h13.copy(height = 14, votes = forkVote)
- val expectedParameters14 = Parameters(14, Map(SoftForkStartingHeight -> 14, SoftForkVotesCollected -> 0, BlockVersion -> 1), proposedUpdate2)
- val esc14 = process(esc13, expectedParameters14, h14).get
- checkValidationSettings(esc14.validationSettings, proposedUpdate)
-
- // next epoch after activation height - soft-fork related parameters are cleared
- val h14b = h13.copy(height = 14, votes = emptyVotes)
- val expectedParameters14a = Parameters(14, Map(BlockVersion -> 1), proposedUpdate2)
- process(esc13, expectedParameters14a, h14b).get
- checkValidationSettings(esc14.validationSettings, proposedUpdate)
- }
-
- /**
- * A vote for a soft-fork which is not gathering enough votes to be activated.
- * The voting settings are :
- * - epoch length is about 2 blocks
- * - 2 epochs to vote
- * - 3 epochs to activate the fork
- *
- */
- property("soft fork - unsuccessful voting") {
- val p: Parameters = Parameters(1, Map(BlockVersion -> 0), proposedUpdate)
- val vr: VotingData = VotingData.empty
- val forkVote = Array(SoftFork, NoParameter, NoParameter)
- val emptyVotes = Array(NoParameter, NoParameter, NoParameter)
-
- val esc0 = new ErgoStateContext(Seq(), None, ADDigest @@ Array.fill(33)(0: Byte), p, validationSettingsNoIl, vr)(updSettings)
- val h1 = defaultHeaderGen.sample.get.copy(votes = forkVote, version = 0: Byte, height = 1)
- val esc1 = process(esc0, p, h1).get
-
- // Soft-fork vote is proposed @ height == 2
- val h2 = defaultHeaderGen.sample.get.copy(votes = forkVote, version = 0: Byte, height = 2)
- val expectedParameters2 = Parameters(2, Map(SoftForkStartingHeight -> 2, SoftForkVotesCollected -> 0, BlockVersion -> 0), proposedUpdate)
- val esc2 = process(esc1, expectedParameters2, h2).get
- esc2.currentParameters.softForkStartingHeight.get shouldBe 2
-
- // voting for the fork @ height == 3
- val h3 = h2.copy(height = 3)
- val expectedParameters3 = Parameters(2, Map(SoftForkStartingHeight -> 2, SoftForkVotesCollected -> 1, BlockVersion -> 0), proposedUpdate)
- val esc3 = process(esc2, expectedParameters3, h3).get
- esc3.currentParameters.softForkStartingHeight.get shouldBe 2
-
- // voting for the fork @ height == 4
- val h4 = h3.copy(height = 4)
- val expectedParameters4 = Parameters(4, Map(SoftForkStartingHeight -> 2, SoftForkVotesCollected -> 2, BlockVersion -> 0), proposedUpdate)
- val esc4 = process(esc3, expectedParameters4, h4).get
- esc4.currentParameters.softForkStartingHeight.get shouldBe 2
- esc4.currentParameters.softForkVotesCollected.get shouldBe 2
-
- // no vote for the fork @ height == 5, so only soft-fork proposal has gathered 75% only
- val h5 = h4.copy(height = 5, votes = emptyVotes)
- val expectedParameters5 = Parameters(4, Map(SoftForkStartingHeight -> 2, SoftForkVotesCollected -> 3, BlockVersion -> 0), proposedUpdate)
- val esc5 = process(esc4, expectedParameters5, h5).get
-
- // first epoch after the voting done, data should still be in the block
- val h6 = h5.copy(height = 6)
- val expectedParameters6 = Parameters(6, Map(SoftForkStartingHeight -> 2, SoftForkVotesCollected -> 3, BlockVersion -> 0), proposedUpdate)
- val esc6 = process(esc5, expectedParameters6, h6).get
-
- // in the first epoch after the voting done, it is prohibited to propose a new voting for a fork
- val h6w = h5.copy(height = 6, votes = forkVote)
- process(esc5, expectedParameters6, h6w).isFailure shouldBe true
-
- val h7 = h6.copy(height = 7)
- val esc7 = process(esc6, expectedParameters6, h7).get
-
- //... also prohibited to vote for a fork during the first epoch after the voting done
- val h7w = h6.copy(height = 7, votes = forkVote)
- process(esc6, expectedParameters6, h7w).isFailure shouldBe true
-
- // a new fork voting is proposed on the first block of the second epoch after voting (which has not gathered enough)
- val h8 = h7.copy(height = 8, votes = forkVote)
- val expectedParameters8 = Parameters(8, Map(SoftForkStartingHeight -> 8, SoftForkVotesCollected -> 0, BlockVersion -> 0), proposedUpdate)
- process(esc7, expectedParameters8, h8).get
-
- // on the second epoch after voting (not old enough) parameters are to be cleared,
- // and block version to be the same
- val h8e = h7.copy(height = 8, votes = emptyVotes)
- val expectedParameters8e = Parameters(8, Map(BlockVersion -> 0), proposedUpdate)
- process(esc7, expectedParameters8e, h8e).get
- }
-
- property("hardfork - v2 - activation") {
- val vr: VotingData = VotingData.empty
- val esc0 = new ErgoStateContext(Seq(), None, ADDigest @@ Array.fill(33)(0: Byte), parameters, ErgoValidationSettings.initial, vr)(updSettings)
- val h1 = defaultHeaderGen.sample.get.copy(votes = Array.empty, version = 1: Byte, height = hfActivationHeight - 1)
- val expectedParameters1 = Parameters(hfActivationHeight - 1, DefaultParameters, ErgoValidationSettingsUpdate.empty)
- val esc1 = process(esc0, expectedParameters1, h1).get
- val h2 = defaultHeaderGen.sample.get.copy(votes = Array.empty, version = 2: Byte, height = hfActivationHeight)
- val expectedParameters2 = Parameters(hfActivationHeight, DefaultParameters.updated(BlockVersion, 2: Byte), ErgoValidationSettingsUpdate.empty)
- val esc2 = process(esc1, expectedParameters2, h2).get
- esc2.currentParameters.blockVersion shouldBe 2
- }
-
- private def checkValidationSettings(vs: ErgoValidationSettings, updated: ErgoValidationSettingsUpdate): Unit = {
- vs.rules.foreach { r =>
- vs.isActive(r._1) shouldBe !updated.rulesToDisable.contains(r._1)
- }
- updated.statusUpdates.foreach { su =>
- vs.sigmaSettings.getStatus(su._1).get shouldBe su._2
- }
- }
-
- private def process(esc: ErgoStateContext,
- expectedParameters: Parameters,
- header: Header): Try[ErgoStateContext] = {
- val upcoming = esc.upcoming(header.minerPk, header.timestamp, header.nBits, header.votes, expectedParameters.proposedUpdate, header.version)
- val calculatedParams = upcoming.currentParameters
- expectedParameters.parametersTable.foreach { case (paramId, paramValue) =>
- calculatedParams.parametersTable(paramId) shouldBe paramValue
- }
- val extension = (upcoming.currentParameters.toExtensionCandidate ++ upcoming.validationSettings.toExtensionCandidate).toExtension(headerId)
- esc.process(header, Some(extension))
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/tools/ChainGenerator.scala b/ergo-core/src/test/scala/org/ergoplatform/tools/ChainGenerator.scala
deleted file mode 100644
index 7fb07b62f9..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/tools/ChainGenerator.scala
+++ /dev/null
@@ -1,221 +0,0 @@
-package org.ergoplatform.tools
-
-import org.ergoplatform._
-import org.ergoplatform.mining.difficulty.DifficultySerializer
-import org.ergoplatform.mining.{AutolykosPowScheme, CandidateBlock, CandidateGenerator}
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.extension.{Extension, ExtensionCandidate}
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.history.popow.NipopowAlgos
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction}
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.history.ErgoHistory.Height
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.SortingOption
-import org.ergoplatform.nodeView.state._
-import org.ergoplatform.settings._
-import org.ergoplatform.utils.{ErgoTestHelpers, HistoryTestHelpers}
-import org.ergoplatform.wallet.boxes.{BoxSelector, ReplaceCompactCollectBoxSelector}
-import scorex.util.ModifierId
-import sigmastate.crypto.DLogProtocol.ProveDlog
-
-import java.io.File
-import scala.annotation.tailrec
-import scala.concurrent.duration._
-import scala.util.Try
-
-/**
- * Application object for chain generation.
- * Takes 2 parameters: start timestamp and path to history folder.
- * Generate blocks starting from start timestamp and until current time with expected block interval
- * between them, to ensure that difficulty does not change.
- */
-object ChainGenerator extends App with ErgoTestHelpers {
-
- val realNetworkSetting = {
- val initSettings = ErgoSettings.read(Args(None, Some(NetworkType.TestNet)))
- initSettings.copy(chainSettings = initSettings.chainSettings.copy(genesisId = None))
- }
-
- val EmissionTxCost: Long = 20000
- val MinTxAmount: Long = 2000000
- val RewardDelay: Int = realNetworkSetting.chainSettings.monetary.minerRewardDelay
- val MaxTxsPerBlock: Int = 10
-
- val prover = defaultProver
- val minerPk = prover.hdKeys.head.publicImage
- val selfAddressScript = P2PKAddress(minerPk).script
- val minerProp = ErgoTreePredef.rewardOutputScript(RewardDelay, minerPk)
-
- val pow = new AutolykosPowScheme(powScheme.k, powScheme.n)
- val blockInterval = 2.minute
-
- val boxSelector: BoxSelector = new ReplaceCompactCollectBoxSelector(30, 2, None)
-
- val startTime = args.headOption.map(_.toLong).getOrElse(System.currentTimeMillis() - (blockInterval * 10).toMillis)
- val dir = if (args.length < 2) new File("/tmp/ergo/data") else new File(args(1))
- val txsSize: Int = if (args.length < 3) 100 * 1024 else args(2).toInt
-
- val minimalSuffix = 2
- val txCostLimit = initSettings.nodeSettings.maxTransactionCost
- val txSizeLimit = initSettings.nodeSettings.maxTransactionSize
- val nodeSettings: NodeConfigurationSettings = NodeConfigurationSettings(StateType.Utxo, verifyTransactions = true,
- -1, UtxoSettings(false, 0, 2), NipopowSettings(false, 1), mining = false, txCostLimit, txSizeLimit, useExternalMiner = false,
- internalMinersCount = 1, internalMinerPollingInterval = 1.second, miningPubKeyHex = None, offlineGeneration = false,
- 200, 5.minutes, 100000, 1.minute, mempoolSorting = SortingOption.FeePerByte, rebroadcastCount = 20,
- 1000000, 100, adProofsSuffixLength = 112*1024, extraIndex = false)
- val ms = settings.chainSettings.monetary.copy(
- minerRewardDelay = RewardDelay
- )
- val cs = realNetworkSetting.chainSettings
-
- val fullHistorySettings: ErgoSettings = ErgoSettings(dir.getAbsolutePath, NetworkType.TestNet, cs,
- nodeSettings, settings.scorexSettings, settings.walletSettings, settings.cacheSettings)
- val stateDir = ErgoState.stateDir(fullHistorySettings)
- stateDir.mkdirs()
-
- val votingEpochLength = votingSettings.votingLength
- val protocolVersion = fullHistorySettings.chainSettings.protocolVersion
-
- val history = ErgoHistory.readOrGenerate(fullHistorySettings)(context = null)
- HistoryTestHelpers.allowToApplyOldBlocks(history)
- val (state, _) = ErgoState.generateGenesisUtxoState(stateDir, fullHistorySettings)
- log.info(s"Going to generate a chain at ${dir.getAbsoluteFile} starting from ${history.bestFullBlockOpt}")
-
- val chain = loop(state, None, None, Seq())
- log.info(s"Chain of length ${chain.length} generated")
- history.bestHeaderOpt shouldBe history.bestFullBlockOpt.map(_.header)
- history.bestFullBlockOpt.get.id shouldBe chain.last
- log.info("History was generated successfully")
- System.exit(0)
-
- private def loop(state: UtxoState,
- initBox: Option[ErgoBox],
- last: Option[Header],
- acc: Seq[ModifierId]): Seq[ModifierId] = {
- val time: Long = last.map(_.timestamp + blockInterval.toMillis).getOrElse(startTime)
- if (time < System.currentTimeMillis()) {
- val (txs, lastOut) = genTransactions(last.map(_.height).getOrElse(ErgoHistory.GenesisHeight),
- initBox, state.stateContext)
-
- val candidate = genCandidate(prover.hdPubKeys.head.key, last, time, txs, state)
- val block = proveCandidate(candidate.get)
-
- history.append(block.header).get
- block.blockSections.foreach(s => if (!history.contains(s)) history.append(s).get)
-
- val outToPassNext = if (last.isEmpty) {
- block.transactions.flatMap(_.outputs).find(_.ergoTree == minerProp)
- } else {
- lastOut
- }
-
- assert(outToPassNext.isDefined)
-
- log.info(
- s"Block ${block.id} with ${block.transactions.size} transactions at height ${block.header.height} generated")
-
- loop(state.applyModifier(block, None)(_ => ()).get, outToPassNext, Some(block.header), acc :+ block.id)
- } else {
- acc
- }
- }
-
- private def genTransactions(height: Height,
- inOpt: Option[ErgoBox],
- ctx: ErgoStateContext): (Seq[ErgoTransaction], Option[ErgoBox]) = {
- inOpt
- .find { bx =>
- val canUnlock = (bx.creationHeight + RewardDelay <= height) || (bx.ergoTree != minerProp)
- canUnlock && bx.ergoTree != cs.monetary.emissionBoxProposition && bx.value >= MinTxAmount
- }
- .map { input =>
- val qty = MaxTxsPerBlock
- val amount = input.value
- val outs = (0 until qty).map(_ => new ErgoBoxCandidate(amount, selfAddressScript, height))
- val x = outs
- .foldLeft((Seq.empty[ErgoTransaction], input)) { case ((acc, in), out) =>
- val inputs = IndexedSeq(in)
- val unsignedTx = UnsignedErgoTransaction(
- inputs.map(_.id).map(id => new UnsignedInput(id)),
- IndexedSeq(out)
- )
-
- prover.sign(unsignedTx, inputs, emptyDataBoxes, ctx)
- .fold(_ => acc -> in, tx => (acc :+ ErgoTransaction(tx)) -> unsignedTx.outputs.head)
- }
- ._1
- (x, Some(x.last.outputs.head))
- }
- .getOrElse(Seq.empty -> inOpt)
- }
-
- private def genCandidate(minerPk: ProveDlog,
- lastHeaderOpt: Option[Header],
- ts: Long,
- txsFromPool: Seq[ErgoTransaction],
- state: UtxoStateReader): Try[CandidateBlock] = Try {
- val stateContext = state.stateContext
- val nBits: Long = lastHeaderOpt
- .map(parent => history.requiredDifficultyAfter(parent))
- .map(d => DifficultySerializer.encodeCompactBits(d))
- .getOrElse(settings.chainSettings.initialNBits)
-
- val interlinks = lastHeaderOpt
- .flatMap { h =>
- history.typedModifierById[Extension](h.extensionId)
- .flatMap(ext => NipopowAlgos.unpackInterlinks(ext.fields).toOption)
- .map(nipopowAlgos.updateInterlinks(h, _))
- }
- .getOrElse(Seq.empty)
- val interlinksExtension = nipopowAlgos.interlinksToExtension(interlinks)
-
- val (extensionCandidate, votes: Array[Byte], version: Byte) = lastHeaderOpt.map { header =>
- val newHeight = header.height + 1
- val currentParams = stateContext.currentParameters
- val betterVersion = protocolVersion > header.version
- val votingFinishHeight: Option[Height] = currentParams.softForkStartingHeight
- .map(_ + votingSettings.votingLength * votingSettings.softForkEpochs)
- val forkVotingAllowed = votingFinishHeight.forall(fh => newHeight < fh)
- val forkOrdered = settings.votingTargets.softFork != 0
- val voteForFork = betterVersion && forkOrdered && forkVotingAllowed
-
- if (newHeight % votingEpochLength == 0 && newHeight > 0) {
- val (newParams, _) = currentParams.update(newHeight, voteForFork, stateContext.votingData.epochVotes, emptyVSUpdate, votingSettings)
- (newParams.toExtensionCandidate ++ interlinksExtension,
- newParams.suggestVotes(settings.votingTargets.targets, voteForFork),
- newParams.blockVersion)
- } else {
- (nipopowAlgos.interlinksToExtension(interlinks),
- currentParams.vote(settings.votingTargets.targets, stateContext.votingData.epochVotes, voteForFork),
- currentParams.blockVersion)
- }
- }.getOrElse((interlinksExtension, Array(0: Byte, 0: Byte, 0: Byte), Header.InitialVersion))
-
- val emissionTxOpt = CandidateGenerator.collectEmission(state, minerPk, emptyStateContext)
- val txs = emissionTxOpt.toSeq ++ txsFromPool
-
- state.proofsForTransactions(txs).map { case (adProof, adDigest) =>
- CandidateBlock(lastHeaderOpt, version, nBits, adDigest, adProof, txs, ts, extensionCandidate, votes)
- }
- }.flatten
-
- @tailrec
- private def proveCandidate(candidate: CandidateBlock): ErgoFullBlock = {
- log.info(s"Trying to prove block with parent ${candidate.parentOpt.map(_.encodedId)} and timestamp ${candidate.timestamp}")
-
- pow.proveCandidate(candidate, prover.hdKeys.head.privateInput.w) match {
- case Some(fb) => fb
- case _ =>
- val interlinks = candidate.parentOpt
- .map(nipopowAlgos.updateInterlinks(_, NipopowAlgos.unpackInterlinks(candidate.extension.fields).get))
- .getOrElse(Seq.empty)
- val minerTag = scorex.utils.Random.randomBytes(Extension.FieldKeySize)
- proveCandidate {
- candidate.copy(
- extension = ExtensionCandidate(Seq(Array(0: Byte, 2: Byte) -> minerTag)) ++ nipopowAlgos.interlinksToExtension(interlinks)
- )
- }
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/tools/ConfigGenerator.scala b/ergo-core/src/test/scala/org/ergoplatform/tools/ConfigGenerator.scala
deleted file mode 100644
index 2ba172a4ad..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/tools/ConfigGenerator.scala
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.ergoplatform.tools
-
-import java.io.{File, PrintWriter}
-
-import org.ergoplatform.utils.ErgoTestHelpers
-import org.ergoplatform.wallet.mnemonic.Mnemonic
-import org.ergoplatform.wallet.interface4j.SecretString
-
-object ConfigGenerator extends App with ErgoTestHelpers {
-
- val seedStrength = 128
-
- val qty = args(0).toInt
- val apiKeyHash = args(1)
- val digestMode = if (args(2) == "true") true else false
- val mining = if (args(3) == "true") !digestMode else false
- val saveDirPath = if (args.length < 5) "/tmp/ergo/configs" else args(4)
-
- (0 to qty).foreach { i =>
- val stateType = if (digestMode) "digest" else "utxo"
- val cfgName = s"node-$stateType-$i-local.conf"
- val nodeName = s"node-$stateType-$i-devnet"
- val mnemonic = genMnemonic
- dumpToFile(saveDirPath, cfgName, template(digestMode, mining, mnemonic, apiKeyHash, nodeName))
- }
-
- private def dumpToFile(dir: String, cfgName: String, content: String): Unit = {
- new File(dir).mkdirs()
- val outWriter = new PrintWriter(new File(s"$dir/$cfgName"))
- outWriter.write(content)
- outWriter.close()
- }
-
- private def template(digestMode: Boolean, mining: Boolean,
- mnemonic: SecretString, apiKeyHash: String, nodeName: String): String =
- s"""
- |ergo.node.stateType = "${if (digestMode) "digest" else "utxo"}"
- |ergo.node.mining = ${if (mining) "true" else "false"}
- |ergo.node.offlineGeneration = true
- |ergo.node.useExternalMiner = false
- |ergo.testing.transactionGeneration = true
- |ergo.wallet.testMnemonic = "$mnemonic"
- |ergo.wallet.testKeysQty = 10
- |scorex.restApi.apiKeyHash = "$apiKeyHash"
- |scorex.network.nodeName = "$nodeName"
- """.stripMargin
-
- private def genMnemonic = {
- val entropy = scorex.utils.Random.randomBytes(seedStrength / 8)
- new Mnemonic(settings.walletSettings.mnemonicPhraseLanguage, settings.walletSettings.seedStrengthBits)
- .toMnemonic(entropy)
- .get
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/tools/DefaultParametersPrinter.scala b/ergo-core/src/test/scala/org/ergoplatform/tools/DefaultParametersPrinter.scala
deleted file mode 100644
index 05bee3973a..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/tools/DefaultParametersPrinter.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.ergoplatform.tools
-
-import org.ergoplatform.settings.LaunchParameters.parametersTable
-import org.ergoplatform.settings.Parameters.{maxValues, minValues, parametersDescs, stepsTable}
-
-object DefaultParametersPrinter extends App {
- lazy val parametersDescription: String = {
- """
- |\begin{tabular}{*{6}{l}}
- |Id & Description & Default & Step & Min & Max \\
- |\hline
- """.stripMargin +
- parametersDescs.toSeq.sortBy(_._1).map { case (id, desc) =>
- val defaultOpt = parametersTable.get(id)
- val stepOpt = stepsTable.get(id)
- val minValue = minValues.get(id)
- val maxValue = maxValues.get(id)
- s"$id & $desc & ${defaultOpt.getOrElse("-")} & ${stepOpt.getOrElse("-")} & ${minValue.getOrElse("-")} & ${maxValue.getOrElse("-")} \\\\"
- }.mkString("\n") +
- """
- |\end{tabular}
- """.stripMargin
- }
-
- print(parametersDescription)
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/tools/DifficultyControlSimulator.scala b/ergo-core/src/test/scala/org/ergoplatform/tools/DifficultyControlSimulator.scala
deleted file mode 100644
index 8c38a167e4..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/tools/DifficultyControlSimulator.scala
+++ /dev/null
@@ -1,162 +0,0 @@
-package org.ergoplatform.tools
-
-import org.ergoplatform.mining.difficulty.{DifficultyAdjustment, DifficultySerializer}
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.nodeView.history.ErgoHistory.Difficulty
-import org.ergoplatform.settings.ErgoSettings
-import org.ergoplatform.utils.generators.ErgoGenerators
-
-import scala.annotation.tailrec
-import scala.collection.mutable
-import scala.concurrent.duration._
-import scala.io.Source
-import scala.util.Random
-
-/**
- * Object that allows to simulate blockchain with the specified difficulty control function and estimate deviation
- * of block interval from the desired one
- */
-object DifficultyControlSimulator extends App with ErgoGenerators {
-
- val baseHeader = defaultHeaderGen.sample.get
- // val difficultyControl = new LinearDifficultyControl(1.minute, useLastEpochs = 100, epochLength = 1)
- val epochLength = 256
- val chainSettings = settings.chainSettings.copy(blockInterval = 2.minute, useLastEpochs = 8, epochLength = epochLength)
- val difficultyControl = new DifficultyAdjustment(chainSettings)
- // Constant rate: Stable simulated average interval = 119713, error = 0.23916666% | Init simulated average interval = 117794, error = 1.8383334%
- // Increasing rate: Stable simulated average interval = 119841, error = 0.1325% | Init simulated average interval = 119077, error = 0.76916665%
- // Random rate: Stable simulated average interval = 120539, error = 0.44916666% | Init simulated average interval = 115519, error = 3.7341666%
-
- blockchainSimulator(difficultyControl,
- baseHeader.copy(height = 0, timestamp = 0, nBits = 16842752),
- randomHashRate)
-
- /**
- * Generate blockchain starting from initial header with specified difficulty control and measure mean time interval between blocks
- *
- * @param difficultyControl
- * @param initialHeader
- */
- def blockchainSimulator(difficultyControl: DifficultyAdjustment,
- initialHeader: Header,
- timeForOneHash: Int => Int): Unit = {
- // number of blocks in simulated chain
- val chainLength = 100000
-
- val curChain = mutable.Map[Int, Header](initialHeader.height -> initialHeader)
-
- @tailrec
- def genchain(curHeight: Int): mutable.Map[Int, Header] = {
-
- if (curHeight >= chainLength) {
- curChain
- } else {
- val lastHeader = curChain(curHeight)
- val requiredDifficulty = requiredDifficultyAfter(lastHeader, curChain)
- val target = 1.toDouble / requiredDifficulty.toDouble
-
- val hashTime = timeForOneHash(curHeight)
-
- @tailrec
- def simulateTimeDiff(currentDiff: Long = 0): Long = {
- val hit = Random.nextDouble()
- if (hit < target) {
- currentDiff + hashTime
- } else {
- simulateTimeDiff(currentDiff + hashTime)
- }
- }
-
- val timeDiff = simulateTimeDiff()
- val newHeader = lastHeader.copy(timestamp = lastHeader.timestamp + timeDiff,
- height = curHeight + 1,
- nBits = DifficultySerializer.encodeCompactBits(requiredDifficulty))
- curChain(newHeader.height) = newHeader
-
- genchain(curHeight + 1)
- }
- }
-
- val chain = genchain(initialHeader.height)
-
- printEpochs(chain.values.toSeq.sortBy(_.height), difficultyControl)
-
-
- }
-
- def printTestnetData(): Unit = {
- val baseHeader = defaultHeaderGen.sample.get
- val chainSettings = ErgoSettings.read().chainSettings.copy(epochLength = 1)
- val difficultyControl = new DifficultyAdjustment(chainSettings)
-
- val headers = Source.fromResource("difficulty.csv").getLines().toSeq.tail.map { line =>
- val l = line.split(",")
- baseHeader.copy(
- height = l(0).toInt,
- timestamp = l(1).toLong,
- nBits = DifficultySerializer.encodeCompactBits(BigInt(l(2)))
- )
- }
- printEpochs(headers, difficultyControl)
- }
-
- def printEpochs(headers: Seq[Header], difficultyControl: DifficultyAdjustment): Unit = {
- case class Epoch(startHeight: Int, requiredDifficulty: BigInt, blockInterval: FiniteDuration, timestamp: Long) {
- val realDifficulty: BigInt = requiredDifficulty * difficultyControl.desiredInterval.toMillis / blockInterval.toMillis
-
- override def toString: String = s"$startHeight,$requiredDifficulty,$realDifficulty,${blockInterval.toMillis}"
- }
-
- val epochs: Seq[Epoch] = headers.filter(h => h.height % epochLength == 0).sliding(2).map { p =>
- val start = p.head
- val end = p.last
- val meanInterval = ((end.timestamp - start.timestamp) / (end.height - start.height)).millis
-
- Epoch(start.height, end.requiredDifficulty, meanInterval, end.timestamp)
- }.toSeq
-
- val initEpochs: Seq[Epoch] = epochs.take(difficultyControl.useLastEpochs).tail
- val stableEpochs: Seq[Epoch] = epochs.drop(difficultyControl.useLastEpochs)
- val simulatedInit = initEpochs.map(_.blockInterval.toMillis).sum / initEpochs.length
- val simulatedStable = stableEpochs.map(_.blockInterval.toMillis).sum / stableEpochs.length
- val desired = difficultyControl.desiredInterval.toMillis
- val errorInit = Math.abs(simulatedInit - desired).toFloat * 100 / desired
- val errorStable = Math.abs(simulatedStable - desired).toFloat * 100 / desired
-
- println(s"Control:")
- println(s"Desired interval = $desired, epoch length = $epochLength, use last epochs = " +
- difficultyControl.useLastEpochs)
- println(s"Init simulated average interval = $simulatedInit, error = $errorInit%")
- println(s"Stable simulated average interval = $simulatedStable, error = $errorStable%")
-
- /*
- println(s"height,requiredDifficulty,realDifficulty,timeDiff")
- epochs.foreach(d => println(d))
-*/
- }
-
-
- private def requiredDifficultyAfter(parent: Header, blockchain: mutable.Map[Int, Header]): Difficulty = {
- val parentHeight = parent.height
- val heights = difficultyControl.previousHeightsRequiredForRecalculation(parentHeight + 1, epochLength)
- .ensuring(_.last == parentHeight)
- if (heights.lengthCompare(1) == 0) {
- difficultyControl.calculate(Seq(parent), epochLength)
- } else {
- val headersToCalculate = heights.map(h => blockchain(h))
- difficultyControl.calculate(headersToCalculate, epochLength)
- }
- }
-
-
- def constantHashRate(height: Int): Int = {
- 1000
- }
-
- def linearGrowingHashRate(height: Int): Int = Math.max(2000 - height / 20, 100)
-
- def randomHashRate(height: Int): Int = {
- Random.nextInt(1000)
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/tools/FeeSimulator.scala b/ergo-core/src/test/scala/org/ergoplatform/tools/FeeSimulator.scala
deleted file mode 100644
index 9eebe3f4b7..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/tools/FeeSimulator.scala
+++ /dev/null
@@ -1,105 +0,0 @@
-package org.ergoplatform.tools
-
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.settings.Constants._
-import org.ergoplatform.settings.LaunchParameters._
-import org.ergoplatform.{ErgoBoxCandidate, Input}
-import scorex.crypto.authds.ADKey
-import scorex.utils.Random
-import sigma.Colls
-import sigmastate.crypto.DLogProtocol.DLogProverInput
-import sigmastate.eval.Extensions.ArrayByteOps
-import sigmastate.eval._
-import sigmastate.interpreter.{ContextExtension, ProverResult}
-
-
-object FeeSimulator extends App {
-
- //Block size is 500Kb
- private val BlockSize = 500 * 1024
-
- val k1 = DLogProverInput.random().publicImage
- val k2 = DLogProverInput.random().publicImage
-
- val input = Input(ADKey @@ Random.randomBytes(32), ProverResult(Random.randomBytes(65), ContextExtension(Map())))
- val creationHeight: Int = 100000
-
- val box1 = new ErgoBoxCandidate(
- scala.util.Random.nextLong(), k1, creationHeight,
- Colls.fromItems(Random.randomBytes(32).toTokenId -> scala.util.Random.nextLong()))
- val box2 = new ErgoBoxCandidate(scala.util.Random.nextLong(), k2, creationHeight)
-
- val simpleTx = ErgoTransaction(IndexedSeq(input, input), IndexedSeq(box1, box2))
- val stdSize = simpleTx.outputs.map(_.bytes.length).sum / simpleTx.outputs.length
- val simpleTxSize = simpleTx.size
- val outputsSize = simpleTx.outputs.map(_.bytes.length).sum
- lazy val perOutputFee = stdSize * storageFeeFactor / CoinsInOneErgo.toDouble
- val minStdDust = minValuePerByte * stdSize
- val byteFeeBitcoin = 0.00039128734 * CoinsInOneErgo
-
- println("=====================")
- println("Global parameters:")
- println(s"Storage fee factor: $storageFeeFactor")
- println(s"Output size: $stdSize B")
- println(s"Simple tx size: $simpleTxSize B")
- println(s"Block size: $BlockSize B")
- println(s"Storage fee for ordinary output: $perOutputFee")
- println(s"Min dust value of standard-size box: $minStdDust")
-
- println("=====================")
- println(s"Assume that Ergo state has the same number of outputs($bitcoinUtxos), as Bitcoin.")
-
- def bitcoinUtxos = 60000000
-
- println(s"Reward per block: ${perOutputFee * (bitcoinUtxos.toDouble / StoragePeriod)} Erg + tx fees")
-
-
- println("=====================")
- println(s"Assume that blocks are full and miner is requiring upfront payment equal to storage fee to move a box")
-
- println(s"Reward per block: ${BlockSize * storageFeeFactor / CoinsInOneErgo.toDouble} Erg")
-
- val minTxFee = storageFeeFactor * outputsSize / CoinsInOneErgo.toDouble
- println(s"Tx fee: $minTxFee")
-
- println(s"Everyday relocation: ${minTxFee * StoragePeriod / BlocksPerDay}")
- println(s"Weekly relocation: ${minTxFee * StoragePeriod / BlocksPerWeek}")
- println(s"Monthly relocation: ${minTxFee * StoragePeriod / BlocksPerMonth}")
- println(s"Yearly relocation: ${minTxFee * StoragePeriod / BlocksPerYear}")
-
- println("=====================")
- println("Assume tx byte in Ergo has the same USD cost as in Bitcoin")
-
- //(not very realistic, as we take current market price of Ergo token, but it will be much higher probably under the assumption of equality)
- val blockFee = maxBlockSize * byteFeeBitcoin
- println(s"Reward per block: ${blockFee / CoinsInOneErgo.toDouble} Erg")
- println(s"bytefee Bitcoin: ${byteFeeBitcoin / CoinsInOneErgo.toDouble} Erg")
-
-
- println("=====================")
- println("Assume that a miner is requiring minimum tx fee proportional to lifetime of its inputs and average" +
- " box lifetime equals to Bitcoin (8182 blocks)")
-
- // Mean lifetime of a box in Bitcoin = 8182 blocks.
- val LBitcoin = 8182
-
- val meanMinTxFee = outputsSize * storageFeeFactor * LBitcoin / StoragePeriod.toDouble
-
- println(s"Reward per block: ${BlockSize * storageFeeFactor * LBitcoin / StoragePeriod.toDouble / CoinsInOneErgo.toDouble} Erg")
-
- println(s"Tx fee: ${meanMinTxFee / CoinsInOneErgo.toDouble}")
-
- println("=====================")
- println("Assume that a miner is requiring minimum tx fee proportional to lifetime of its inputs and average" +
- " box lifetime equals to Bitcoin (56,8 days)")
-
- // Mean lifetime of a box in Ergo = 56,8 days
- val LErgo = LBitcoin * 5
-
- val meanMinTxFeeE = outputsSize * storageFeeFactor * LErgo / StoragePeriod.toDouble
-
- println(s"Reward per block: ${BlockSize * storageFeeFactor * LErgo / StoragePeriod.toDouble / CoinsInOneErgo.toDouble} Erg")
-
- println(s"Tx fee: ${meanMinTxFeeE / CoinsInOneErgo.toDouble}")
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/tools/MinerBench.scala b/ergo-core/src/test/scala/org/ergoplatform/tools/MinerBench.scala
deleted file mode 100644
index 7a997bfb05..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/tools/MinerBench.scala
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.ergoplatform.tools
-
-import com.google.common.primitives.Bytes
-import org.bouncycastle.util.BigIntegers
-import org.ergoplatform.mining._
-import org.ergoplatform.mining.difficulty.DifficultySerializer
-import org.ergoplatform.modifiers.history.extension.ExtensionCandidate
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.utils.ErgoTestHelpers
-import scorex.crypto.hash.{Blake2b256, Blake2b512, CryptographicHash, Digest}
-
-import scala.annotation.tailrec
-
-object MinerBench extends App with ErgoTestHelpers {
-
- validationBench()
- // numericHashBench()
-
- def numericHashBench(): Unit = {
- val Steps = 100000000
-
- def numericHash(hf: CryptographicHash[_ <: Digest], validRange: BigInt): Unit = {
- @tailrec
- def hash(input: Array[Byte]): BigInt = {
- val hashed = hf.apply(input)
- val bi = BigInt(BigIntegers.fromUnsignedByteArray(hashed))
- if (bi < validRange) {
- bi.mod(q)
- } else {
- log.debug(s"Calculate one more hash for ${encoder.encode(input)} and p=$q")
- hash(hashed)
- }
- }
- }
-
- val data = Bytes.concat(Array.fill(16486)(1.toByte))
- // test Blake2b256
- val validRange256: BigInt = (BigInt(2).pow(Blake2b256.DigestSize * 8) / q) * q
-
- // prepare JVM
- (0 until Steps).foreach(_ => numericHash(Blake2b256, validRange256))
-
- val st = System.currentTimeMillis()
- (0 until Steps).foreach(_ => numericHash(Blake2b256, validRange256))
- val st2 = System.currentTimeMillis()
-
- val validRange512: BigInt = (BigInt(2).pow(Blake2b512.DigestSize * 8) / q) * q
-
- // prepare JVM
- (0 until Steps).foreach(_ => numericHash(Blake2b512, validRange512))
-
- val st3 = System.currentTimeMillis()
- (0 until Steps).foreach(_ => numericHash(Blake2b512, validRange512))
- val st4 = System.currentTimeMillis()
-
- println(s"Calculation time of $Steps numberic hashes over ${data.length} bytes")
- println(s"Blake2b256: ${st2 - st} ms")
- println(s"Blake2b512: ${st4 - st3} ms")
-
- }
-
- def validationBench() {
- val pow = new AutolykosPowScheme(powScheme.k, powScheme.n)
- val sk = randomSecret()
- val difficulty = 1000
- val fb = invalidErgoFullBlockGen.sample.get
- val inHeader = fb.header
- val nBits = DifficultySerializer.encodeCompactBits(difficulty)
- val h = inHeader.copy(nBits = nBits)
-
- val candidate = new CandidateBlock(None, Header.InitialVersion, nBits: Long, h.stateRoot,
- fb.adProofs.get.proofBytes,
- fb.blockTransactions.txs,
- System.currentTimeMillis(),
- ExtensionCandidate(Seq.empty),
- Array())
- val newHeader = pow.proveCandidate(candidate, sk).get.header
-
- val Steps = 10000
-
- (0 until Steps / 10) foreach (_ => pow.validate(newHeader))
-
- val st = System.currentTimeMillis()
-
- (0 until Steps) foreach (_ => pow.validate(newHeader))
-
- println(s"M = ${pow.M.length / 1024} Kb:${(System.currentTimeMillis() - st).toDouble / Steps} ms")
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/tools/emission.csv b/ergo-core/src/test/scala/org/ergoplatform/tools/emission.csv
deleted file mode 100644
index 19515a1926..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/tools/emission.csv
+++ /dev/null
@@ -1,1169 +0,0 @@
-age (years), total coins, current rate
-0.0, 0, 75.0
-0.00684931506849315, 135000, 75.0
-0.0136986301369863, 270000, 75.0
-0.02054794520547945, 405000, 75.0
-0.0273972602739726, 540000, 75.0
-0.03424657534246575, 675000, 75.0
-0.0410958904109589, 810000, 75.0
-0.04794520547945205, 945000, 75.0
-0.0547945205479452, 1080000, 75.0
-0.06164383561643835, 1215000, 75.0
-0.0684931506849315, 1350000, 75.0
-0.07534246575342465, 1485000, 75.0
-0.0821917808219178, 1620000, 75.0
-0.08904109589041095, 1755000, 75.0
-0.0958904109589041, 1890000, 75.0
-0.10273972602739725, 2025000, 75.0
-0.1095890410958904, 2160000, 75.0
-0.11643835616438356, 2295000, 75.0
-0.1232876712328767, 2430000, 75.0
-0.13013698630136986, 2565000, 75.0
-0.136986301369863, 2700000, 75.0
-0.14383561643835616, 2835000, 75.0
-0.1506849315068493, 2970000, 75.0
-0.15753424657534246, 3105000, 75.0
-0.1643835616438356, 3240000, 75.0
-0.17123287671232876, 3375000, 75.0
-0.1780821917808219, 3510000, 75.0
-0.18493150684931506, 3645000, 75.0
-0.1917808219178082, 3780000, 75.0
-0.19863013698630136, 3915000, 75.0
-0.2054794520547945, 4050000, 75.0
-0.21232876712328766, 4185000, 75.0
-0.2191780821917808, 4320000, 75.0
-0.22602739726027396, 4455000, 75.0
-0.2328767123287671, 4590000, 75.0
-0.23972602739726026, 4725000, 75.0
-0.2465753424657534, 4860000, 75.0
-0.2534246575342466, 4995000, 75.0
-0.2602739726027397, 5130000, 75.0
-0.2671232876712329, 5265000, 75.0
-0.273972602739726, 5400000, 75.0
-0.2808219178082192, 5535000, 75.0
-0.2876712328767123, 5670000, 75.0
-0.2945205479452055, 5805000, 75.0
-0.3013698630136986, 5940000, 75.0
-0.3082191780821918, 6075000, 75.0
-0.3150684931506849, 6210000, 75.0
-0.3219178082191781, 6345000, 75.0
-0.3287671232876712, 6480000, 75.0
-0.3356164383561644, 6615000, 75.0
-0.3424657534246575, 6750000, 75.0
-0.3493150684931507, 6885000, 75.0
-0.3561643835616438, 7020000, 75.0
-0.363013698630137, 7155000, 75.0
-0.3698630136986301, 7290000, 75.0
-0.3767123287671233, 7425000, 75.0
-0.3835616438356164, 7560000, 75.0
-0.3904109589041096, 7695000, 75.0
-0.3972602739726027, 7830000, 75.0
-0.4041095890410959, 7965000, 75.0
-0.410958904109589, 8100000, 75.0
-0.4178082191780822, 8235000, 75.0
-0.4246575342465753, 8370000, 75.0
-0.4315068493150685, 8505000, 75.0
-0.4383561643835616, 8640000, 75.0
-0.4452054794520548, 8775000, 75.0
-0.4520547945205479, 8910000, 75.0
-0.4589041095890411, 9045000, 75.0
-0.4657534246575342, 9180000, 75.0
-0.4726027397260274, 9315000, 75.0
-0.4794520547945205, 9450000, 75.0
-0.4863013698630137, 9585000, 75.0
-0.4931506849315068, 9720000, 75.0
-0.5, 9855000, 75.0
-0.5068493150684932, 9990000, 75.0
-0.5136986301369864, 10125000, 75.0
-0.5205479452054794, 10260000, 75.0
-0.5273972602739726, 10395000, 75.0
-0.5342465753424658, 10530000, 75.0
-0.541095890410959, 10665000, 75.0
-0.547945205479452, 10800000, 75.0
-0.5547945205479452, 10935000, 75.0
-0.5616438356164384, 11070000, 75.0
-0.5684931506849316, 11205000, 75.0
-0.5753424657534246, 11340000, 75.0
-0.5821917808219178, 11475000, 75.0
-0.589041095890411, 11610000, 75.0
-0.5958904109589042, 11745000, 75.0
-0.6027397260273972, 11880000, 75.0
-0.6095890410958904, 12015000, 75.0
-0.6164383561643836, 12150000, 75.0
-0.6232876712328768, 12285000, 75.0
-0.6301369863013698, 12420000, 75.0
-0.636986301369863, 12555000, 75.0
-0.6438356164383562, 12690000, 75.0
-0.6506849315068494, 12825000, 75.0
-0.6575342465753424, 12960000, 75.0
-0.6643835616438356, 13095000, 75.0
-0.6712328767123288, 13230000, 75.0
-0.678082191780822, 13365000, 75.0
-0.684931506849315, 13500000, 75.0
-0.6917808219178082, 13635000, 75.0
-0.6986301369863014, 13770000, 75.0
-0.7054794520547946, 13905000, 75.0
-0.7123287671232876, 14040000, 75.0
-0.7191780821917808, 14175000, 75.0
-0.726027397260274, 14310000, 75.0
-0.7328767123287672, 14445000, 75.0
-0.7397260273972602, 14580000, 75.0
-0.7465753424657534, 14715000, 75.0
-0.7534246575342466, 14850000, 75.0
-0.7602739726027398, 14985000, 75.0
-0.7671232876712328, 15120000, 75.0
-0.773972602739726, 15255000, 75.0
-0.7808219178082192, 15390000, 75.0
-0.7876712328767124, 15525000, 75.0
-0.7945205479452054, 15660000, 75.0
-0.8013698630136986, 15795000, 75.0
-0.8082191780821918, 15930000, 75.0
-0.815068493150685, 16065000, 75.0
-0.821917808219178, 16200000, 75.0
-0.8287671232876712, 16335000, 75.0
-0.8356164383561644, 16470000, 75.0
-0.8424657534246576, 16605000, 75.0
-0.8493150684931506, 16740000, 75.0
-0.8561643835616438, 16875000, 75.0
-0.863013698630137, 17010000, 75.0
-0.8698630136986302, 17145000, 75.0
-0.8767123287671232, 17280000, 75.0
-0.8835616438356164, 17415000, 75.0
-0.8904109589041096, 17550000, 75.0
-0.8972602739726028, 17685000, 75.0
-0.9041095890410958, 17820000, 75.0
-0.910958904109589, 17955000, 75.0
-0.9178082191780822, 18090000, 75.0
-0.9246575342465754, 18225000, 75.0
-0.9315068493150684, 18360000, 75.0
-0.9383561643835616, 18495000, 75.0
-0.9452054794520548, 18630000, 75.0
-0.952054794520548, 18765000, 75.0
-0.958904109589041, 18900000, 75.0
-0.9657534246575342, 19035000, 75.0
-0.9726027397260274, 19170000, 75.0
-0.9794520547945206, 19305000, 75.0
-0.9863013698630136, 19440000, 75.0
-0.9931506849315068, 19575000, 75.0
-1.0, 19710000, 75.0
-1.0068493150684932, 19845000, 75.0
-1.0136986301369864, 19980000, 75.0
-1.0205479452054795, 20115000, 75.0
-1.0273972602739727, 20250000, 75.0
-1.0342465753424657, 20385000, 75.0
-1.0410958904109588, 20520000, 75.0
-1.047945205479452, 20655000, 75.0
-1.0547945205479452, 20790000, 75.0
-1.0616438356164384, 20925000, 75.0
-1.0684931506849316, 21060000, 75.0
-1.0753424657534247, 21195000, 75.0
-1.082191780821918, 21330000, 75.0
-1.0890410958904109, 21465000, 75.0
-1.095890410958904, 21600000, 75.0
-1.1027397260273972, 21735000, 75.0
-1.1095890410958904, 21870000, 75.0
-1.1164383561643836, 22005000, 75.0
-1.1232876712328768, 22140000, 75.0
-1.13013698630137, 22275000, 75.0
-1.1369863013698631, 22410000, 75.0
-1.143835616438356, 22545000, 75.0
-1.1506849315068493, 22680000, 75.0
-1.1575342465753424, 22815000, 75.0
-1.1643835616438356, 22950000, 75.0
-1.1712328767123288, 23085000, 75.0
-1.178082191780822, 23220000, 75.0
-1.1849315068493151, 23355000, 75.0
-1.1917808219178083, 23490000, 75.0
-1.1986301369863013, 23625000, 75.0
-1.2054794520547945, 23760000, 75.0
-1.2123287671232876, 23895000, 75.0
-1.2191780821917808, 24030000, 75.0
-1.226027397260274, 24165000, 75.0
-1.2328767123287672, 24300000, 75.0
-1.2397260273972603, 24435000, 75.0
-1.2465753424657535, 24570000, 75.0
-1.2534246575342465, 24705000, 75.0
-1.2602739726027397, 24840000, 75.0
-1.2671232876712328, 24975000, 75.0
-1.273972602739726, 25110000, 75.0
-1.2808219178082192, 25245000, 75.0
-1.2876712328767124, 25380000, 75.0
-1.2945205479452055, 25515000, 75.0
-1.3013698630136987, 25650000, 75.0
-1.3082191780821917, 25785000, 75.0
-1.3150684931506849, 25920000, 75.0
-1.321917808219178, 26055000, 75.0
-1.3287671232876712, 26190000, 75.0
-1.3356164383561644, 26325000, 75.0
-1.3424657534246576, 26460000, 75.0
-1.3493150684931507, 26595000, 75.0
-1.356164383561644, 26730000, 75.0
-1.3630136986301369, 26865000, 75.0
-1.36986301369863, 27000000, 75.0
-1.3767123287671232, 27135000, 75.0
-1.3835616438356164, 27270000, 75.0
-1.3904109589041096, 27405000, 75.0
-1.3972602739726028, 27540000, 75.0
-1.404109589041096, 27675000, 75.0
-1.4109589041095891, 27810000, 75.0
-1.417808219178082, 27945000, 75.0
-1.4246575342465753, 28080000, 75.0
-1.4315068493150684, 28215000, 75.0
-1.4383561643835616, 28350000, 75.0
-1.4452054794520548, 28485000, 75.0
-1.452054794520548, 28620000, 75.0
-1.4589041095890412, 28755000, 75.0
-1.4657534246575343, 28890000, 75.0
-1.4726027397260273, 29025000, 75.0
-1.4794520547945205, 29160000, 75.0
-1.4863013698630136, 29295000, 75.0
-1.4931506849315068, 29430000, 75.0
-1.5, 29565000, 75.0
-1.5068493150684932, 29700000, 75.0
-1.5136986301369864, 29835000, 75.0
-1.5205479452054795, 29970000, 75.0
-1.5273972602739727, 30105000, 75.0
-1.5342465753424657, 30240000, 75.0
-1.5410958904109588, 30375000, 75.0
-1.547945205479452, 30510000, 75.0
-1.5547945205479452, 30645000, 75.0
-1.5616438356164384, 30780000, 75.0
-1.5684931506849316, 30915000, 75.0
-1.5753424657534247, 31050000, 75.0
-1.582191780821918, 31185000, 75.0
-1.5890410958904109, 31320000, 75.0
-1.595890410958904, 31455000, 75.0
-1.6027397260273972, 31590000, 75.0
-1.6095890410958904, 31725000, 75.0
-1.6164383561643836, 31860000, 75.0
-1.6232876712328768, 31995000, 75.0
-1.63013698630137, 32130000, 75.0
-1.6369863013698631, 32265000, 75.0
-1.643835616438356, 32400000, 75.0
-1.6506849315068493, 32535000, 75.0
-1.6575342465753424, 32670000, 75.0
-1.6643835616438356, 32805000, 75.0
-1.6712328767123288, 32940000, 75.0
-1.678082191780822, 33075000, 75.0
-1.6849315068493151, 33210000, 75.0
-1.6917808219178083, 33345000, 75.0
-1.6986301369863013, 33480000, 75.0
-1.7054794520547945, 33615000, 75.0
-1.7123287671232876, 33750000, 75.0
-1.7191780821917808, 33885000, 75.0
-1.726027397260274, 34020000, 75.0
-1.7328767123287672, 34155000, 75.0
-1.7397260273972603, 34290000, 75.0
-1.7465753424657535, 34425000, 75.0
-1.7534246575342465, 34560000, 75.0
-1.7602739726027397, 34695000, 75.0
-1.7671232876712328, 34830000, 75.0
-1.773972602739726, 34965000, 75.0
-1.7808219178082192, 35100000, 75.0
-1.7876712328767124, 35235000, 75.0
-1.7945205479452055, 35370000, 75.0
-1.8013698630136987, 35505000, 75.0
-1.8082191780821917, 35640000, 75.0
-1.8150684931506849, 35775000, 75.0
-1.821917808219178, 35910000, 75.0
-1.8287671232876712, 36045000, 75.0
-1.8356164383561644, 36180000, 75.0
-1.8424657534246576, 36315000, 75.0
-1.8493150684931507, 36450000, 75.0
-1.856164383561644, 36585000, 75.0
-1.8630136986301369, 36720000, 75.0
-1.86986301369863, 36855000, 75.0
-1.8767123287671232, 36990000, 75.0
-1.8835616438356164, 37125000, 75.0
-1.8904109589041096, 37260000, 75.0
-1.8972602739726028, 37395000, 75.0
-1.904109589041096, 37530000, 75.0
-1.9109589041095891, 37665000, 75.0
-1.917808219178082, 37800000, 75.0
-1.9246575342465753, 37935000, 75.0
-1.9315068493150684, 38070000, 75.0
-1.9383561643835616, 38205000, 75.0
-1.9452054794520548, 38340000, 75.0
-1.952054794520548, 38475000, 75.0
-1.9589041095890412, 38610000, 75.0
-1.9657534246575343, 38745000, 75.0
-1.9726027397260273, 38880000, 75.0
-1.9794520547945205, 39015000, 75.0
-1.9863013698630136, 39150000, 75.0
-1.9931506849315068, 39285000, 75.0
-2.0, 39420000, 72.0
-2.006849315068493, 39549600, 72.0
-2.0136986301369864, 39679200, 72.0
-2.0205479452054793, 39808800, 72.0
-2.0273972602739727, 39938400, 72.0
-2.0342465753424657, 40068000, 72.0
-2.041095890410959, 40197600, 72.0
-2.047945205479452, 40327200, 72.0
-2.0547945205479454, 40456800, 72.0
-2.0616438356164384, 40586400, 72.0
-2.0684931506849313, 40716000, 72.0
-2.0753424657534247, 40845600, 72.0
-2.0821917808219177, 40975200, 72.0
-2.089041095890411, 41104800, 72.0
-2.095890410958904, 41234400, 72.0
-2.1027397260273974, 41364000, 72.0
-2.1095890410958904, 41493600, 72.0
-2.1164383561643834, 41623200, 72.0
-2.1232876712328768, 41752800, 72.0
-2.1301369863013697, 41882400, 72.0
-2.136986301369863, 42012000, 72.0
-2.143835616438356, 42141600, 72.0
-2.1506849315068495, 42271200, 72.0
-2.1575342465753424, 42400800, 72.0
-2.164383561643836, 42530400, 72.0
-2.171232876712329, 42660000, 72.0
-2.1780821917808217, 42789600, 72.0
-2.184931506849315, 42919200, 72.0
-2.191780821917808, 43048800, 72.0
-2.1986301369863015, 43178400, 72.0
-2.2054794520547945, 43308000, 72.0
-2.212328767123288, 43437600, 72.0
-2.219178082191781, 43567200, 72.0
-2.2260273972602738, 43696800, 72.0
-2.232876712328767, 43826400, 72.0
-2.23972602739726, 43956000, 72.0
-2.2465753424657535, 44085600, 69.0
-2.2534246575342465, 44209800, 69.0
-2.26027397260274, 44334000, 69.0
-2.267123287671233, 44458200, 69.0
-2.2739726027397262, 44582400, 69.0
-2.280821917808219, 44706600, 69.0
-2.287671232876712, 44830800, 69.0
-2.2945205479452055, 44955000, 69.0
-2.3013698630136985, 45079200, 69.0
-2.308219178082192, 45203400, 69.0
-2.315068493150685, 45327600, 69.0
-2.3219178082191783, 45451800, 69.0
-2.328767123287671, 45576000, 69.0
-2.335616438356164, 45700200, 69.0
-2.3424657534246576, 45824400, 69.0
-2.3493150684931505, 45948600, 69.0
-2.356164383561644, 46072800, 69.0
-2.363013698630137, 46197000, 69.0
-2.3698630136986303, 46321200, 69.0
-2.3767123287671232, 46445400, 69.0
-2.3835616438356166, 46569600, 69.0
-2.3904109589041096, 46693800, 69.0
-2.3972602739726026, 46818000, 69.0
-2.404109589041096, 46942200, 69.0
-2.410958904109589, 47066400, 69.0
-2.4178082191780823, 47190600, 69.0
-2.4246575342465753, 47314800, 69.0
-2.4315068493150687, 47439000, 69.0
-2.4383561643835616, 47563200, 69.0
-2.4452054794520546, 47687400, 69.0
-2.452054794520548, 47811600, 69.0
-2.458904109589041, 47935800, 69.0
-2.4657534246575343, 48060000, 69.0
-2.4726027397260273, 48184200, 69.0
-2.4794520547945207, 48308400, 69.0
-2.4863013698630136, 48432600, 69.0
-2.493150684931507, 48556800, 66.0
-2.5, 48675600, 66.0
-2.506849315068493, 48794400, 66.0
-2.5136986301369864, 48913200, 66.0
-2.5205479452054793, 49032000, 66.0
-2.5273972602739727, 49150800, 66.0
-2.5342465753424657, 49269600, 66.0
-2.541095890410959, 49388400, 66.0
-2.547945205479452, 49507200, 66.0
-2.5547945205479454, 49626000, 66.0
-2.5616438356164384, 49744800, 66.0
-2.5684931506849313, 49863600, 66.0
-2.5753424657534247, 49982400, 66.0
-2.5821917808219177, 50101200, 66.0
-2.589041095890411, 50220000, 66.0
-2.595890410958904, 50338800, 66.0
-2.6027397260273974, 50457600, 66.0
-2.6095890410958904, 50576400, 66.0
-2.6164383561643834, 50695200, 66.0
-2.6232876712328768, 50814000, 66.0
-2.6301369863013697, 50932800, 66.0
-2.636986301369863, 51051600, 66.0
-2.643835616438356, 51170400, 66.0
-2.6506849315068495, 51289200, 66.0
-2.6575342465753424, 51408000, 66.0
-2.664383561643836, 51526800, 66.0
-2.671232876712329, 51645600, 66.0
-2.6780821917808217, 51764400, 66.0
-2.684931506849315, 51883200, 66.0
-2.691780821917808, 52002000, 66.0
-2.6986301369863015, 52120800, 66.0
-2.7054794520547945, 52239600, 66.0
-2.712328767123288, 52358400, 66.0
-2.719178082191781, 52477200, 66.0
-2.7260273972602738, 52596000, 66.0
-2.732876712328767, 52714800, 66.0
-2.73972602739726, 52833600, 63.0
-2.7465753424657535, 52947000, 63.0
-2.7534246575342465, 53060400, 63.0
-2.76027397260274, 53173800, 63.0
-2.767123287671233, 53287200, 63.0
-2.7739726027397262, 53400600, 63.0
-2.780821917808219, 53514000, 63.0
-2.787671232876712, 53627400, 63.0
-2.7945205479452055, 53740800, 63.0
-2.8013698630136985, 53854200, 63.0
-2.808219178082192, 53967600, 63.0
-2.815068493150685, 54081000, 63.0
-2.8219178082191783, 54194400, 63.0
-2.828767123287671, 54307800, 63.0
-2.835616438356164, 54421200, 63.0
-2.8424657534246576, 54534600, 63.0
-2.8493150684931505, 54648000, 63.0
-2.856164383561644, 54761400, 63.0
-2.863013698630137, 54874800, 63.0
-2.8698630136986303, 54988200, 63.0
-2.8767123287671232, 55101600, 63.0
-2.8835616438356166, 55215000, 63.0
-2.8904109589041096, 55328400, 63.0
-2.8972602739726026, 55441800, 63.0
-2.904109589041096, 55555200, 63.0
-2.910958904109589, 55668600, 63.0
-2.9178082191780823, 55782000, 63.0
-2.9246575342465753, 55895400, 63.0
-2.9315068493150687, 56008800, 63.0
-2.9383561643835616, 56122200, 63.0
-2.9452054794520546, 56235600, 63.0
-2.952054794520548, 56349000, 63.0
-2.958904109589041, 56462400, 63.0
-2.9657534246575343, 56575800, 63.0
-2.9726027397260273, 56689200, 63.0
-2.9794520547945207, 56802600, 63.0
-2.9863013698630136, 56916000, 60.0
-2.993150684931507, 57024000, 60.0
-3.0, 57132000, 60.0
-3.006849315068493, 57240000, 60.0
-3.0136986301369864, 57348000, 60.0
-3.0205479452054793, 57456000, 60.0
-3.0273972602739727, 57564000, 60.0
-3.0342465753424657, 57672000, 60.0
-3.041095890410959, 57780000, 60.0
-3.047945205479452, 57888000, 60.0
-3.0547945205479454, 57996000, 60.0
-3.0616438356164384, 58104000, 60.0
-3.0684931506849313, 58212000, 60.0
-3.0753424657534247, 58320000, 60.0
-3.0821917808219177, 58428000, 60.0
-3.089041095890411, 58536000, 60.0
-3.095890410958904, 58644000, 60.0
-3.1027397260273974, 58752000, 60.0
-3.1095890410958904, 58860000, 60.0
-3.1164383561643834, 58968000, 60.0
-3.1232876712328768, 59076000, 60.0
-3.1301369863013697, 59184000, 60.0
-3.136986301369863, 59292000, 60.0
-3.143835616438356, 59400000, 60.0
-3.1506849315068495, 59508000, 60.0
-3.1575342465753424, 59616000, 60.0
-3.164383561643836, 59724000, 60.0
-3.171232876712329, 59832000, 60.0
-3.1780821917808217, 59940000, 60.0
-3.184931506849315, 60048000, 60.0
-3.191780821917808, 60156000, 60.0
-3.1986301369863015, 60264000, 60.0
-3.2054794520547945, 60372000, 60.0
-3.212328767123288, 60480000, 60.0
-3.219178082191781, 60588000, 60.0
-3.2260273972602738, 60696000, 60.0
-3.232876712328767, 60804000, 57.0
-3.23972602739726, 60906600, 57.0
-3.2465753424657535, 61009200, 57.0
-3.2534246575342465, 61111800, 57.0
-3.26027397260274, 61214400, 57.0
-3.267123287671233, 61317000, 57.0
-3.2739726027397262, 61419600, 57.0
-3.280821917808219, 61522200, 57.0
-3.287671232876712, 61624800, 57.0
-3.2945205479452055, 61727400, 57.0
-3.3013698630136985, 61830000, 57.0
-3.308219178082192, 61932600, 57.0
-3.315068493150685, 62035200, 57.0
-3.3219178082191783, 62137800, 57.0
-3.328767123287671, 62240400, 57.0
-3.335616438356164, 62343000, 57.0
-3.3424657534246576, 62445600, 57.0
-3.3493150684931505, 62548200, 57.0
-3.356164383561644, 62650800, 57.0
-3.363013698630137, 62753400, 57.0
-3.3698630136986303, 62856000, 57.0
-3.3767123287671232, 62958600, 57.0
-3.3835616438356166, 63061200, 57.0
-3.3904109589041096, 63163800, 57.0
-3.3972602739726026, 63266400, 57.0
-3.404109589041096, 63369000, 57.0
-3.410958904109589, 63471600, 57.0
-3.4178082191780823, 63574200, 57.0
-3.4246575342465753, 63676800, 57.0
-3.4315068493150687, 63779400, 57.0
-3.4383561643835616, 63882000, 57.0
-3.4452054794520546, 63984600, 57.0
-3.452054794520548, 64087200, 57.0
-3.458904109589041, 64189800, 57.0
-3.4657534246575343, 64292400, 57.0
-3.4726027397260273, 64395000, 57.0
-3.4794520547945207, 64497600, 54.0
-3.4863013698630136, 64594800, 54.0
-3.493150684931507, 64692000, 54.0
-3.5, 64789200, 54.0
-3.506849315068493, 64886400, 54.0
-3.5136986301369864, 64983600, 54.0
-3.5205479452054793, 65080800, 54.0
-3.5273972602739727, 65178000, 54.0
-3.5342465753424657, 65275200, 54.0
-3.541095890410959, 65372400, 54.0
-3.547945205479452, 65469600, 54.0
-3.5547945205479454, 65566800, 54.0
-3.5616438356164384, 65664000, 54.0
-3.5684931506849313, 65761200, 54.0
-3.5753424657534247, 65858400, 54.0
-3.5821917808219177, 65955600, 54.0
-3.589041095890411, 66052800, 54.0
-3.595890410958904, 66150000, 54.0
-3.6027397260273974, 66247200, 54.0
-3.6095890410958904, 66344400, 54.0
-3.6164383561643834, 66441600, 54.0
-3.6232876712328768, 66538800, 54.0
-3.6301369863013697, 66636000, 54.0
-3.636986301369863, 66733200, 54.0
-3.643835616438356, 66830400, 54.0
-3.6506849315068495, 66927600, 54.0
-3.6575342465753424, 67024800, 54.0
-3.664383561643836, 67122000, 54.0
-3.671232876712329, 67219200, 54.0
-3.6780821917808217, 67316400, 54.0
-3.684931506849315, 67413600, 54.0
-3.691780821917808, 67510800, 54.0
-3.6986301369863015, 67608000, 54.0
-3.7054794520547945, 67705200, 54.0
-3.712328767123288, 67802400, 54.0
-3.719178082191781, 67899600, 54.0
-3.7260273972602738, 67996800, 51.0
-3.732876712328767, 68088600, 51.0
-3.73972602739726, 68180400, 51.0
-3.7465753424657535, 68272200, 51.0
-3.7534246575342465, 68364000, 51.0
-3.76027397260274, 68455800, 51.0
-3.767123287671233, 68547600, 51.0
-3.7739726027397262, 68639400, 51.0
-3.780821917808219, 68731200, 51.0
-3.787671232876712, 68823000, 51.0
-3.7945205479452055, 68914800, 51.0
-3.8013698630136985, 69006600, 51.0
-3.808219178082192, 69098400, 51.0
-3.815068493150685, 69190200, 51.0
-3.8219178082191783, 69282000, 51.0
-3.828767123287671, 69373800, 51.0
-3.835616438356164, 69465600, 51.0
-3.8424657534246576, 69557400, 51.0
-3.8493150684931505, 69649200, 51.0
-3.856164383561644, 69741000, 51.0
-3.863013698630137, 69832800, 51.0
-3.8698630136986303, 69924600, 51.0
-3.8767123287671232, 70016400, 51.0
-3.8835616438356166, 70108200, 51.0
-3.8904109589041096, 70200000, 51.0
-3.8972602739726026, 70291800, 51.0
-3.904109589041096, 70383600, 51.0
-3.910958904109589, 70475400, 51.0
-3.9178082191780823, 70567200, 51.0
-3.9246575342465753, 70659000, 51.0
-3.9315068493150687, 70750800, 51.0
-3.9383561643835616, 70842600, 51.0
-3.9452054794520546, 70934400, 51.0
-3.952054794520548, 71026200, 51.0
-3.958904109589041, 71118000, 51.0
-3.9657534246575343, 71209800, 51.0
-3.9726027397260273, 71301600, 48.0
-3.9794520547945207, 71388000, 48.0
-3.9863013698630136, 71474400, 48.0
-3.993150684931507, 71560800, 48.0
-4.0, 71647200, 48.0
-4.006849315068493, 71733600, 48.0
-4.013698630136986, 71820000, 48.0
-4.02054794520548, 71906400, 48.0
-4.027397260273973, 71992800, 48.0
-4.034246575342466, 72079200, 48.0
-4.041095890410959, 72165600, 48.0
-4.0479452054794525, 72252000, 48.0
-4.054794520547945, 72338400, 48.0
-4.061643835616438, 72424800, 48.0
-4.068493150684931, 72511200, 48.0
-4.075342465753424, 72597600, 48.0
-4.082191780821918, 72684000, 48.0
-4.089041095890411, 72770400, 48.0
-4.095890410958904, 72856800, 48.0
-4.102739726027397, 72943200, 48.0
-4.109589041095891, 73029600, 48.0
-4.116438356164384, 73116000, 48.0
-4.123287671232877, 73202400, 48.0
-4.13013698630137, 73288800, 48.0
-4.136986301369863, 73375200, 48.0
-4.1438356164383565, 73461600, 48.0
-4.1506849315068495, 73548000, 48.0
-4.157534246575342, 73634400, 48.0
-4.164383561643835, 73720800, 48.0
-4.171232876712328, 73807200, 48.0
-4.178082191780822, 73893600, 48.0
-4.184931506849315, 73980000, 48.0
-4.191780821917808, 74066400, 48.0
-4.198630136986301, 74152800, 48.0
-4.205479452054795, 74239200, 48.0
-4.212328767123288, 74325600, 48.0
-4.219178082191781, 74412000, 45.0
-4.226027397260274, 74493000, 45.0
-4.232876712328767, 74574000, 45.0
-4.239726027397261, 74655000, 45.0
-4.2465753424657535, 74736000, 45.0
-4.2534246575342465, 74817000, 45.0
-4.260273972602739, 74898000, 45.0
-4.267123287671233, 74979000, 45.0
-4.273972602739726, 75060000, 45.0
-4.280821917808219, 75141000, 45.0
-4.287671232876712, 75222000, 45.0
-4.294520547945205, 75303000, 45.0
-4.301369863013699, 75384000, 45.0
-4.308219178082192, 75465000, 45.0
-4.315068493150685, 75546000, 45.0
-4.321917808219178, 75627000, 45.0
-4.328767123287672, 75708000, 45.0
-4.335616438356165, 75789000, 45.0
-4.342465753424658, 75870000, 45.0
-4.3493150684931505, 75951000, 45.0
-4.3561643835616435, 76032000, 45.0
-4.363013698630137, 76113000, 45.0
-4.36986301369863, 76194000, 45.0
-4.376712328767123, 76275000, 45.0
-4.383561643835616, 76356000, 45.0
-4.390410958904109, 76437000, 45.0
-4.397260273972603, 76518000, 45.0
-4.404109589041096, 76599000, 45.0
-4.410958904109589, 76680000, 45.0
-4.417808219178082, 76761000, 45.0
-4.424657534246576, 76842000, 45.0
-4.431506849315069, 76923000, 45.0
-4.438356164383562, 77004000, 45.0
-4.445205479452055, 77085000, 45.0
-4.4520547945205475, 77166000, 45.0
-4.458904109589041, 77247000, 45.0
-4.465753424657534, 77328000, 42.0
-4.472602739726027, 77403600, 42.0
-4.47945205479452, 77479200, 42.0
-4.486301369863014, 77554800, 42.0
-4.493150684931507, 77630400, 42.0
-4.5, 77706000, 42.0
-4.506849315068493, 77781600, 42.0
-4.513698630136986, 77857200, 42.0
-4.52054794520548, 77932800, 42.0
-4.527397260273973, 78008400, 42.0
-4.534246575342466, 78084000, 42.0
-4.541095890410959, 78159600, 42.0
-4.5479452054794525, 78235200, 42.0
-4.554794520547945, 78310800, 42.0
-4.561643835616438, 78386400, 42.0
-4.568493150684931, 78462000, 42.0
-4.575342465753424, 78537600, 42.0
-4.582191780821918, 78613200, 42.0
-4.589041095890411, 78688800, 42.0
-4.595890410958904, 78764400, 42.0
-4.602739726027397, 78840000, 42.0
-4.609589041095891, 78915600, 42.0
-4.616438356164384, 78991200, 42.0
-4.623287671232877, 79066800, 42.0
-4.63013698630137, 79142400, 42.0
-4.636986301369863, 79218000, 42.0
-4.6438356164383565, 79293600, 42.0
-4.6506849315068495, 79369200, 42.0
-4.657534246575342, 79444800, 42.0
-4.664383561643835, 79520400, 42.0
-4.671232876712328, 79596000, 42.0
-4.678082191780822, 79671600, 42.0
-4.684931506849315, 79747200, 42.0
-4.691780821917808, 79822800, 42.0
-4.698630136986301, 79898400, 42.0
-4.705479452054795, 79974000, 42.0
-4.712328767123288, 80049600, 39.0
-4.719178082191781, 80119800, 39.0
-4.726027397260274, 80190000, 39.0
-4.732876712328767, 80260200, 39.0
-4.739726027397261, 80330400, 39.0
-4.7465753424657535, 80400600, 39.0
-4.7534246575342465, 80470800, 39.0
-4.760273972602739, 80541000, 39.0
-4.767123287671233, 80611200, 39.0
-4.773972602739726, 80681400, 39.0
-4.780821917808219, 80751600, 39.0
-4.787671232876712, 80821800, 39.0
-4.794520547945205, 80892000, 39.0
-4.801369863013699, 80962200, 39.0
-4.808219178082192, 81032400, 39.0
-4.815068493150685, 81102600, 39.0
-4.821917808219178, 81172800, 39.0
-4.828767123287672, 81243000, 39.0
-4.835616438356165, 81313200, 39.0
-4.842465753424658, 81383400, 39.0
-4.8493150684931505, 81453600, 39.0
-4.8561643835616435, 81523800, 39.0
-4.863013698630137, 81594000, 39.0
-4.86986301369863, 81664200, 39.0
-4.876712328767123, 81734400, 39.0
-4.883561643835616, 81804600, 39.0
-4.890410958904109, 81874800, 39.0
-4.897260273972603, 81945000, 39.0
-4.904109589041096, 82015200, 39.0
-4.910958904109589, 82085400, 39.0
-4.917808219178082, 82155600, 39.0
-4.924657534246576, 82225800, 39.0
-4.931506849315069, 82296000, 39.0
-4.938356164383562, 82366200, 39.0
-4.945205479452055, 82436400, 39.0
-4.9520547945205475, 82506600, 39.0
-4.958904109589041, 82576800, 36.0
-4.965753424657534, 82641600, 36.0
-4.972602739726027, 82706400, 36.0
-4.97945205479452, 82771200, 36.0
-4.986301369863014, 82836000, 36.0
-4.993150684931507, 82900800, 36.0
-5.0, 82965600, 36.0
-5.006849315068493, 83030400, 36.0
-5.013698630136986, 83095200, 36.0
-5.02054794520548, 83160000, 36.0
-5.027397260273973, 83224800, 36.0
-5.034246575342466, 83289600, 36.0
-5.041095890410959, 83354400, 36.0
-5.0479452054794525, 83419200, 36.0
-5.054794520547945, 83484000, 36.0
-5.061643835616438, 83548800, 36.0
-5.068493150684931, 83613600, 36.0
-5.075342465753424, 83678400, 36.0
-5.082191780821918, 83743200, 36.0
-5.089041095890411, 83808000, 36.0
-5.095890410958904, 83872800, 36.0
-5.102739726027397, 83937600, 36.0
-5.109589041095891, 84002400, 36.0
-5.116438356164384, 84067200, 36.0
-5.123287671232877, 84132000, 36.0
-5.13013698630137, 84196800, 36.0
-5.136986301369863, 84261600, 36.0
-5.1438356164383565, 84326400, 36.0
-5.1506849315068495, 84391200, 36.0
-5.157534246575342, 84456000, 36.0
-5.164383561643835, 84520800, 36.0
-5.171232876712328, 84585600, 36.0
-5.178082191780822, 84650400, 36.0
-5.184931506849315, 84715200, 36.0
-5.191780821917808, 84780000, 36.0
-5.198630136986301, 84844800, 36.0
-5.205479452054795, 84909600, 33.0
-5.212328767123288, 84969000, 33.0
-5.219178082191781, 85028400, 33.0
-5.226027397260274, 85087800, 33.0
-5.232876712328767, 85147200, 33.0
-5.239726027397261, 85206600, 33.0
-5.2465753424657535, 85266000, 33.0
-5.2534246575342465, 85325400, 33.0
-5.260273972602739, 85384800, 33.0
-5.267123287671233, 85444200, 33.0
-5.273972602739726, 85503600, 33.0
-5.280821917808219, 85563000, 33.0
-5.287671232876712, 85622400, 33.0
-5.294520547945205, 85681800, 33.0
-5.301369863013699, 85741200, 33.0
-5.308219178082192, 85800600, 33.0
-5.315068493150685, 85860000, 33.0
-5.321917808219178, 85919400, 33.0
-5.328767123287672, 85978800, 33.0
-5.335616438356165, 86038200, 33.0
-5.342465753424658, 86097600, 33.0
-5.3493150684931505, 86157000, 33.0
-5.3561643835616435, 86216400, 33.0
-5.363013698630137, 86275800, 33.0
-5.36986301369863, 86335200, 33.0
-5.376712328767123, 86394600, 33.0
-5.383561643835616, 86454000, 33.0
-5.390410958904109, 86513400, 33.0
-5.397260273972603, 86572800, 33.0
-5.404109589041096, 86632200, 33.0
-5.410958904109589, 86691600, 33.0
-5.417808219178082, 86751000, 33.0
-5.424657534246576, 86810400, 33.0
-5.431506849315069, 86869800, 33.0
-5.438356164383562, 86929200, 33.0
-5.445205479452055, 86988600, 33.0
-5.4520547945205475, 87048000, 30.0
-5.458904109589041, 87102000, 30.0
-5.465753424657534, 87156000, 30.0
-5.472602739726027, 87210000, 30.0
-5.47945205479452, 87264000, 30.0
-5.486301369863014, 87318000, 30.0
-5.493150684931507, 87372000, 30.0
-5.5, 87426000, 30.0
-5.506849315068493, 87480000, 30.0
-5.513698630136986, 87534000, 30.0
-5.52054794520548, 87588000, 30.0
-5.527397260273973, 87642000, 30.0
-5.534246575342466, 87696000, 30.0
-5.541095890410959, 87750000, 30.0
-5.5479452054794525, 87804000, 30.0
-5.554794520547945, 87858000, 30.0
-5.561643835616438, 87912000, 30.0
-5.568493150684931, 87966000, 30.0
-5.575342465753424, 88020000, 30.0
-5.582191780821918, 88074000, 30.0
-5.589041095890411, 88128000, 30.0
-5.595890410958904, 88182000, 30.0
-5.602739726027397, 88236000, 30.0
-5.609589041095891, 88290000, 30.0
-5.616438356164384, 88344000, 30.0
-5.623287671232877, 88398000, 30.0
-5.63013698630137, 88452000, 30.0
-5.636986301369863, 88506000, 30.0
-5.6438356164383565, 88560000, 30.0
-5.6506849315068495, 88614000, 30.0
-5.657534246575342, 88668000, 30.0
-5.664383561643835, 88722000, 30.0
-5.671232876712328, 88776000, 30.0
-5.678082191780822, 88830000, 30.0
-5.684931506849315, 88884000, 30.0
-5.691780821917808, 88938000, 30.0
-5.698630136986301, 88992000, 27.0
-5.705479452054795, 89040600, 27.0
-5.712328767123288, 89089200, 27.0
-5.719178082191781, 89137800, 27.0
-5.726027397260274, 89186400, 27.0
-5.732876712328767, 89235000, 27.0
-5.739726027397261, 89283600, 27.0
-5.7465753424657535, 89332200, 27.0
-5.7534246575342465, 89380800, 27.0
-5.760273972602739, 89429400, 27.0
-5.767123287671233, 89478000, 27.0
-5.773972602739726, 89526600, 27.0
-5.780821917808219, 89575200, 27.0
-5.787671232876712, 89623800, 27.0
-5.794520547945205, 89672400, 27.0
-5.801369863013699, 89721000, 27.0
-5.808219178082192, 89769600, 27.0
-5.815068493150685, 89818200, 27.0
-5.821917808219178, 89866800, 27.0
-5.828767123287672, 89915400, 27.0
-5.835616438356165, 89964000, 27.0
-5.842465753424658, 90012600, 27.0
-5.8493150684931505, 90061200, 27.0
-5.8561643835616435, 90109800, 27.0
-5.863013698630137, 90158400, 27.0
-5.86986301369863, 90207000, 27.0
-5.876712328767123, 90255600, 27.0
-5.883561643835616, 90304200, 27.0
-5.890410958904109, 90352800, 27.0
-5.897260273972603, 90401400, 27.0
-5.904109589041096, 90450000, 27.0
-5.910958904109589, 90498600, 27.0
-5.917808219178082, 90547200, 27.0
-5.924657534246576, 90595800, 27.0
-5.931506849315069, 90644400, 27.0
-5.938356164383562, 90693000, 27.0
-5.945205479452055, 90741600, 24.0
-5.9520547945205475, 90784800, 24.0
-5.958904109589041, 90828000, 24.0
-5.965753424657534, 90871200, 24.0
-5.972602739726027, 90914400, 24.0
-5.97945205479452, 90957600, 24.0
-5.986301369863014, 91000800, 24.0
-5.993150684931507, 91044000, 24.0
-6.0, 91087200, 24.0
-6.006849315068493, 91130400, 24.0
-6.013698630136986, 91173600, 24.0
-6.02054794520548, 91216800, 24.0
-6.027397260273973, 91260000, 24.0
-6.034246575342466, 91303200, 24.0
-6.041095890410959, 91346400, 24.0
-6.0479452054794525, 91389600, 24.0
-6.054794520547945, 91432800, 24.0
-6.061643835616438, 91476000, 24.0
-6.068493150684931, 91519200, 24.0
-6.075342465753424, 91562400, 24.0
-6.082191780821918, 91605600, 24.0
-6.089041095890411, 91648800, 24.0
-6.095890410958904, 91692000, 24.0
-6.102739726027397, 91735200, 24.0
-6.109589041095891, 91778400, 24.0
-6.116438356164384, 91821600, 24.0
-6.123287671232877, 91864800, 24.0
-6.13013698630137, 91908000, 24.0
-6.136986301369863, 91951200, 24.0
-6.1438356164383565, 91994400, 24.0
-6.1506849315068495, 92037600, 24.0
-6.157534246575342, 92080800, 24.0
-6.164383561643835, 92124000, 24.0
-6.171232876712328, 92167200, 24.0
-6.178082191780822, 92210400, 24.0
-6.184931506849315, 92253600, 24.0
-6.191780821917808, 92296800, 21.0
-6.198630136986301, 92334600, 21.0
-6.205479452054795, 92372400, 21.0
-6.212328767123288, 92410200, 21.0
-6.219178082191781, 92448000, 21.0
-6.226027397260274, 92485800, 21.0
-6.232876712328767, 92523600, 21.0
-6.239726027397261, 92561400, 21.0
-6.2465753424657535, 92599200, 21.0
-6.2534246575342465, 92637000, 21.0
-6.260273972602739, 92674800, 21.0
-6.267123287671233, 92712600, 21.0
-6.273972602739726, 92750400, 21.0
-6.280821917808219, 92788200, 21.0
-6.287671232876712, 92826000, 21.0
-6.294520547945205, 92863800, 21.0
-6.301369863013699, 92901600, 21.0
-6.308219178082192, 92939400, 21.0
-6.315068493150685, 92977200, 21.0
-6.321917808219178, 93015000, 21.0
-6.328767123287672, 93052800, 21.0
-6.335616438356165, 93090600, 21.0
-6.342465753424658, 93128400, 21.0
-6.3493150684931505, 93166200, 21.0
-6.3561643835616435, 93204000, 21.0
-6.363013698630137, 93241800, 21.0
-6.36986301369863, 93279600, 21.0
-6.376712328767123, 93317400, 21.0
-6.383561643835616, 93355200, 21.0
-6.390410958904109, 93393000, 21.0
-6.397260273972603, 93430800, 21.0
-6.404109589041096, 93468600, 21.0
-6.410958904109589, 93506400, 21.0
-6.417808219178082, 93544200, 21.0
-6.424657534246576, 93582000, 21.0
-6.431506849315069, 93619800, 21.0
-6.438356164383562, 93657600, 18.0
-6.445205479452055, 93690000, 18.0
-6.4520547945205475, 93722400, 18.0
-6.458904109589041, 93754800, 18.0
-6.465753424657534, 93787200, 18.0
-6.472602739726027, 93819600, 18.0
-6.47945205479452, 93852000, 18.0
-6.486301369863014, 93884400, 18.0
-6.493150684931507, 93916800, 18.0
-6.5, 93949200, 18.0
-6.506849315068493, 93981600, 18.0
-6.513698630136986, 94014000, 18.0
-6.52054794520548, 94046400, 18.0
-6.527397260273973, 94078800, 18.0
-6.534246575342466, 94111200, 18.0
-6.541095890410959, 94143600, 18.0
-6.5479452054794525, 94176000, 18.0
-6.554794520547945, 94208400, 18.0
-6.561643835616438, 94240800, 18.0
-6.568493150684931, 94273200, 18.0
-6.575342465753424, 94305600, 18.0
-6.582191780821918, 94338000, 18.0
-6.589041095890411, 94370400, 18.0
-6.595890410958904, 94402800, 18.0
-6.602739726027397, 94435200, 18.0
-6.609589041095891, 94467600, 18.0
-6.616438356164384, 94500000, 18.0
-6.623287671232877, 94532400, 18.0
-6.63013698630137, 94564800, 18.0
-6.636986301369863, 94597200, 18.0
-6.6438356164383565, 94629600, 18.0
-6.6506849315068495, 94662000, 18.0
-6.657534246575342, 94694400, 18.0
-6.664383561643835, 94726800, 18.0
-6.671232876712328, 94759200, 18.0
-6.678082191780822, 94791600, 18.0
-6.684931506849315, 94824000, 15.0
-6.691780821917808, 94851000, 15.0
-6.698630136986301, 94878000, 15.0
-6.705479452054795, 94905000, 15.0
-6.712328767123288, 94932000, 15.0
-6.719178082191781, 94959000, 15.0
-6.726027397260274, 94986000, 15.0
-6.732876712328767, 95013000, 15.0
-6.739726027397261, 95040000, 15.0
-6.7465753424657535, 95067000, 15.0
-6.7534246575342465, 95094000, 15.0
-6.760273972602739, 95121000, 15.0
-6.767123287671233, 95148000, 15.0
-6.773972602739726, 95175000, 15.0
-6.780821917808219, 95202000, 15.0
-6.787671232876712, 95229000, 15.0
-6.794520547945205, 95256000, 15.0
-6.801369863013699, 95283000, 15.0
-6.808219178082192, 95310000, 15.0
-6.815068493150685, 95337000, 15.0
-6.821917808219178, 95364000, 15.0
-6.828767123287672, 95391000, 15.0
-6.835616438356165, 95418000, 15.0
-6.842465753424658, 95445000, 15.0
-6.8493150684931505, 95472000, 15.0
-6.8561643835616435, 95499000, 15.0
-6.863013698630137, 95526000, 15.0
-6.86986301369863, 95553000, 15.0
-6.876712328767123, 95580000, 15.0
-6.883561643835616, 95607000, 15.0
-6.890410958904109, 95634000, 15.0
-6.897260273972603, 95661000, 15.0
-6.904109589041096, 95688000, 15.0
-6.910958904109589, 95715000, 15.0
-6.917808219178082, 95742000, 15.0
-6.924657534246576, 95769000, 15.0
-6.931506849315069, 95796000, 12.0
-6.938356164383562, 95817600, 12.0
-6.945205479452055, 95839200, 12.0
-6.9520547945205475, 95860800, 12.0
-6.958904109589041, 95882400, 12.0
-6.965753424657534, 95904000, 12.0
-6.972602739726027, 95925600, 12.0
-6.97945205479452, 95947200, 12.0
-6.986301369863014, 95968800, 12.0
-6.993150684931507, 95990400, 12.0
-7.0, 96012000, 12.0
-7.006849315068493, 96033600, 12.0
-7.013698630136986, 96055200, 12.0
-7.02054794520548, 96076800, 12.0
-7.027397260273973, 96098400, 12.0
-7.034246575342466, 96120000, 12.0
-7.041095890410959, 96141600, 12.0
-7.0479452054794525, 96163200, 12.0
-7.054794520547945, 96184800, 12.0
-7.061643835616438, 96206400, 12.0
-7.068493150684931, 96228000, 12.0
-7.075342465753424, 96249600, 12.0
-7.082191780821918, 96271200, 12.0
-7.089041095890411, 96292800, 12.0
-7.095890410958904, 96314400, 12.0
-7.102739726027397, 96336000, 12.0
-7.109589041095891, 96357600, 12.0
-7.116438356164384, 96379200, 12.0
-7.123287671232877, 96400800, 12.0
-7.13013698630137, 96422400, 12.0
-7.136986301369863, 96444000, 12.0
-7.1438356164383565, 96465600, 12.0
-7.1506849315068495, 96487200, 12.0
-7.157534246575342, 96508800, 12.0
-7.164383561643835, 96530400, 12.0
-7.171232876712328, 96552000, 12.0
-7.178082191780822, 96573600, 9.0
-7.184931506849315, 96589800, 9.0
-7.191780821917808, 96606000, 9.0
-7.198630136986301, 96622200, 9.0
-7.205479452054795, 96638400, 9.0
-7.212328767123288, 96654600, 9.0
-7.219178082191781, 96670800, 9.0
-7.226027397260274, 96687000, 9.0
-7.232876712328767, 96703200, 9.0
-7.239726027397261, 96719400, 9.0
-7.2465753424657535, 96735600, 9.0
-7.2534246575342465, 96751800, 9.0
-7.260273972602739, 96768000, 9.0
-7.267123287671233, 96784200, 9.0
-7.273972602739726, 96800400, 9.0
-7.280821917808219, 96816600, 9.0
-7.287671232876712, 96832800, 9.0
-7.294520547945205, 96849000, 9.0
-7.301369863013699, 96865200, 9.0
-7.308219178082192, 96881400, 9.0
-7.315068493150685, 96897600, 9.0
-7.321917808219178, 96913800, 9.0
-7.328767123287672, 96930000, 9.0
-7.335616438356165, 96946200, 9.0
-7.342465753424658, 96962400, 9.0
-7.3493150684931505, 96978600, 9.0
-7.3561643835616435, 96994800, 9.0
-7.363013698630137, 97011000, 9.0
-7.36986301369863, 97027200, 9.0
-7.376712328767123, 97043400, 9.0
-7.383561643835616, 97059600, 9.0
-7.390410958904109, 97075800, 9.0
-7.397260273972603, 97092000, 9.0
-7.404109589041096, 97108200, 9.0
-7.410958904109589, 97124400, 9.0
-7.417808219178082, 97140600, 9.0
-7.424657534246576, 97156800, 6.0
-7.431506849315069, 97167600, 6.0
-7.438356164383562, 97178400, 6.0
-7.445205479452055, 97189200, 6.0
-7.4520547945205475, 97200000, 6.0
-7.458904109589041, 97210800, 6.0
-7.465753424657534, 97221600, 6.0
-7.472602739726027, 97232400, 6.0
-7.47945205479452, 97243200, 6.0
-7.486301369863014, 97254000, 6.0
-7.493150684931507, 97264800, 6.0
-7.5, 97275600, 6.0
-7.506849315068493, 97286400, 6.0
-7.513698630136986, 97297200, 6.0
-7.52054794520548, 97308000, 6.0
-7.527397260273973, 97318800, 6.0
-7.534246575342466, 97329600, 6.0
-7.541095890410959, 97340400, 6.0
-7.5479452054794525, 97351200, 6.0
-7.554794520547945, 97362000, 6.0
-7.561643835616438, 97372800, 6.0
-7.568493150684931, 97383600, 6.0
-7.575342465753424, 97394400, 6.0
-7.582191780821918, 97405200, 6.0
-7.589041095890411, 97416000, 6.0
-7.595890410958904, 97426800, 6.0
-7.602739726027397, 97437600, 6.0
-7.609589041095891, 97448400, 6.0
-7.616438356164384, 97459200, 6.0
-7.623287671232877, 97470000, 6.0
-7.63013698630137, 97480800, 6.0
-7.636986301369863, 97491600, 6.0
-7.6438356164383565, 97502400, 6.0
-7.6506849315068495, 97513200, 6.0
-7.657534246575342, 97524000, 6.0
-7.664383561643835, 97534800, 6.0
-7.671232876712328, 97545600, 3.0
-7.678082191780822, 97551000, 3.0
-7.684931506849315, 97556400, 3.0
-7.691780821917808, 97561800, 3.0
-7.698630136986301, 97567200, 3.0
-7.705479452054795, 97572600, 3.0
-7.712328767123288, 97578000, 3.0
-7.719178082191781, 97583400, 3.0
-7.726027397260274, 97588800, 3.0
-7.732876712328767, 97594200, 3.0
-7.739726027397261, 97599600, 3.0
-7.7465753424657535, 97605000, 3.0
-7.7534246575342465, 97610400, 3.0
-7.760273972602739, 97615800, 3.0
-7.767123287671233, 97621200, 3.0
-7.773972602739726, 97626600, 3.0
-7.780821917808219, 97632000, 3.0
-7.787671232876712, 97637400, 3.0
-7.794520547945205, 97642800, 3.0
-7.801369863013699, 97648200, 3.0
-7.808219178082192, 97653600, 3.0
-7.815068493150685, 97659000, 3.0
-7.821917808219178, 97664400, 3.0
-7.828767123287672, 97669800, 3.0
-7.835616438356165, 97675200, 3.0
-7.842465753424658, 97680600, 3.0
-7.8493150684931505, 97686000, 3.0
-7.8561643835616435, 97691400, 3.0
-7.863013698630137, 97696800, 3.0
-7.86986301369863, 97702200, 3.0
-7.876712328767123, 97707600, 3.0
-7.883561643835616, 97713000, 3.0
-7.890410958904109, 97718400, 3.0
-7.897260273972603, 97723800, 3.0
-7.904109589041096, 97729200, 3.0
-7.910958904109589, 97734600, 3.0
-7.917808219178082, 97740000, 0.0
-7.924657534246576, 97740000, 0.0
-7.931506849315069, 97740000, 0.0
-7.938356164383562, 97740000, 0.0
-7.945205479452055, 97740000, 0.0
-7.9520547945205475, 97740000, 0.0
-7.958904109589041, 97740000, 0.0
-7.965753424657534, 97740000, 0.0
-7.972602739726027, 97740000, 0.0
-7.97945205479452, 97740000, 0.0
-7.986301369863014, 97740000, 0.0
-7.993150684931507, 97740000, 0.0
diff --git a/ergo-core/src/test/scala/org/ergoplatform/tools/emissionPlot.gnu b/ergo-core/src/test/scala/org/ergoplatform/tools/emissionPlot.gnu
deleted file mode 100644
index f750368869..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/tools/emissionPlot.gnu
+++ /dev/null
@@ -1,20 +0,0 @@
-set print "-"
-
-set term png
-#set terminal png enhanced size 1280, 1024 font ',20'
-set terminal png enhanced font ',20'
-set xlabel "Time (years)" font ",20"
-set tics font ", 20"
-set key font ",20"
-set style line 1 lt 20 lw 4 linecolor 7
-
-set output "EmissionCurve.png"
-set ylabel "Coins total" font ",20"
-
-plot 'emission.csv' using 1:2 with lines ls 1 notitle
-
-set output "EmissionRate.png"
-
-set ylabel "Coins per block" font ",20"
-
-plot 'emission.csv' using 1:3 with lines ls 1 notitle
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoPropertyTest.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoPropertyTest.scala
deleted file mode 100644
index 7ec6cd2466..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoPropertyTest.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.ergoplatform.utils
-
-import org.ergoplatform.utils.generators.{ErgoGenerators, ValidBlocksGenerators}
-import org.scalatest.propspec.AnyPropSpec
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-import scorex.testkit.utils.NoShrink
-
-trait ErgoPropertyTest extends AnyPropSpec
- with ScalaCheckPropertyChecks
- with ErgoTestHelpers
- with ErgoGenerators
- with NoShrink
- with ValidBlocksGenerators
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoTestConstants.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoTestConstants.scala
deleted file mode 100644
index 51d7e80597..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoTestConstants.scala
+++ /dev/null
@@ -1,112 +0,0 @@
-package org.ergoplatform.utils
-
-import akka.util.Timeout
-import org.ergoplatform.mining.difficulty.DifficultyAdjustment
-import org.ergoplatform.mining.emission.EmissionRules
-import org.ergoplatform.mining.{AutolykosPowScheme, DefaultFakePowScheme}
-import org.ergoplatform.modifiers.history.extension.ExtensionCandidate
-import org.ergoplatform.modifiers.history.popow.NipopowAlgos
-import org.ergoplatform.nodeView.state._
-import org.ergoplatform.sdk.wallet.secrets.ExtendedSecretKey
-import org.ergoplatform.settings.Constants.HashLength
-import org.ergoplatform.settings.Parameters.{MaxBlockCostIncrease, MinValuePerByteIncrease}
-import org.ergoplatform.settings.ValidationRules._
-import org.ergoplatform.settings._
-import org.ergoplatform.wallet.interface4j.SecretString
-import org.ergoplatform.wallet.interpreter.{ErgoInterpreter, ErgoProvingInterpreter}
-import org.ergoplatform.wallet.mnemonic.Mnemonic
-import org.ergoplatform.{DataInput, ErgoBox, ErgoTreePredef}
-import scorex.core.app.Version
-import scorex.core.network.PeerSpec
-import scorex.crypto.authds.ADDigest
-import scorex.crypto.hash.Digest32
-import scorex.util.ScorexLogging
-import sigmastate.Values.ErgoTree
-import sigmastate.crypto.CryptoConstants.EcPointType
-import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog}
-import sigmastate.interpreter.{ContextExtension, ProverResult}
-
-import scala.concurrent.duration._
-
-trait ErgoTestConstants extends ScorexLogging {
-
- implicit val votingSettings: VotingSettings = VotingSettings(1024, 32, 128, 32 * 1024, "01")
- val validationSettings: ErgoValidationSettings = ErgoValidationSettings.initial
- implicit val validationSettingsNoIl: ErgoValidationSettings = validationSettings
- .updated(ErgoValidationSettingsUpdate(Seq(exIlUnableToValidate, exIlEncoding, exIlStructure, exEmpty), Seq()))
-
- val parameters: Parameters = LaunchParameters
-
- val extendedParameters: Parameters = {
- // Randomness in tests is causing occasional cost overflow in the state context and insufficient box value
- val extension = Map(
- MaxBlockCostIncrease -> Math.ceil(parameters.parametersTable(MaxBlockCostIncrease) * 1.3).toInt,
- MinValuePerByteIncrease -> (parameters.parametersTable(MinValuePerByteIncrease) - 30)
- )
- Parameters(0, Parameters.DefaultParameters ++ extension, ErgoValidationSettingsUpdate.empty)
- }
-
- val initSettings: ErgoSettings = ErgoSettings.read(Args(Some("src/test/resources/application.conf"), None))
-
- implicit val settings: ErgoSettings = initSettings
-
- val nipopowAlgos = new NipopowAlgos(settings.chainSettings)
-
- val lightModeSettings: ErgoSettings = initSettings.copy(
- nodeSettings = initSettings.nodeSettings.copy(stateType = StateType.Digest)
- )
-
- val emission: EmissionRules = settings.chainSettings.emissionRules
- val coinsTotal: Long = emission.coinsTotal
- val genesisStateDigest: ADDigest = settings.chainSettings.genesisStateDigest
- val feeProp: ErgoTree = ErgoTreePredef.feeProposition(emission.settings.minerRewardDelay)
-
- val emptyProverResult: ProverResult = ProverResult(Array.emptyByteArray, ContextExtension.empty)
- lazy val defaultSeed: Array[Byte] = Mnemonic.toSeed(settings.walletSettings.testMnemonic.fold[SecretString](SecretString.empty())(SecretString.create(_)))
- val defaultRootSecret: ExtendedSecretKey = ExtendedSecretKey.deriveMasterKey(defaultSeed, usePre1627KeyDerivation = false)
- val defaultChildSecrets: IndexedSeq[ExtendedSecretKey] = settings.walletSettings.testKeysQty
- .toIndexedSeq
- .flatMap(x => (0 until x).map(defaultRootSecret.child))
- val genesisBoxes: Seq[ErgoBox] = ErgoState.genesisBoxes(settings.chainSettings)
- val genesisEmissionBox: ErgoBox = ErgoState.genesisBoxes(settings.chainSettings).head
- val defaultProver: ErgoProvingInterpreter = ErgoProvingInterpreter(
- defaultRootSecret +: defaultChildSecrets, parameters)
- val defaultMinerSecret: DLogProverInput = defaultProver.hdKeys.head.privateInput
- val defaultMinerSecretNumber: BigInt = defaultProver.hdKeys.head.privateInput.w
- val defaultMinerPk: ProveDlog = defaultMinerSecret.publicImage
- val defaultMinerPkPoint: EcPointType = defaultMinerPk.value
-
- val defaultTimestamp: Long = 1552217190000L
- val defaultNBits: Long = settings.chainSettings.initialNBits
- val defaultVotes: Array[Byte] = Array.fill(3)(0.toByte)
- val defaultVersion: Byte = 0
- lazy val powScheme: AutolykosPowScheme = settings.chainSettings.powScheme.ensuring(_.isInstanceOf[DefaultFakePowScheme])
- val emptyVSUpdate = ErgoValidationSettingsUpdate.empty
- val emptyStateContext: UpcomingStateContext = ErgoStateContext.empty(genesisStateDigest, settings, parameters)
- .upcoming(defaultMinerPkPoint, defaultTimestamp, defaultNBits, defaultVotes, emptyVSUpdate, defaultVersion)
- def stateContextWith(parameters: Parameters): UpcomingStateContext = ErgoStateContext.empty(genesisStateDigest, settings, parameters)
- .upcoming(defaultMinerPkPoint, defaultTimestamp, defaultNBits, defaultVotes, emptyVSUpdate, defaultVersion)
- val startHeight: Int = emptyStateContext.currentHeight
- val startDigest: ADDigest = emptyStateContext.genesisStateDigest
-
- val EmptyStateRoot: ADDigest = ADDigest @@ Array.fill(HashLength + 1)(0.toByte)
- val EmptyDigest32: Digest32 = Digest32 @@ Array.fill(HashLength)(0.toByte)
- val defaultDifficultyControl = new DifficultyAdjustment(settings.chainSettings)
- val defaultExtension: ExtensionCandidate = ExtensionCandidate(Seq(Array(0: Byte, 8: Byte) -> EmptyDigest32))
- val emptyExtension: ExtensionCandidate = ExtensionCandidate(Seq())
- val emptyDataInputs: IndexedSeq[DataInput] = IndexedSeq()
- val emptyDataBoxes: IndexedSeq[ErgoBox] = IndexedSeq()
- def emptyVerifier: ErgoInterpreter = ErgoInterpreter(emptyStateContext.currentParameters)
-
- val defaultTimeout: Timeout = Timeout(14.seconds)
- val defaultAwaitDuration: FiniteDuration = defaultTimeout.duration + 1.second
-
- val defaultPeerSpec = PeerSpec(
- settings.scorexSettings.network.agentName,
- Version(settings.scorexSettings.network.appVersion),
- settings.scorexSettings.network.nodeName,
- None,
- Seq.empty
- )
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoTestHelpers.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoTestHelpers.scala
deleted file mode 100644
index bf9d61ac3e..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoTestHelpers.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.ergoplatform.utils
-
-import org.ergoplatform.ErgoBoxCandidate
-import org.ergoplatform.utils.generators.ValidBlocksGenerators
-import org.scalatest.{EitherValues, OptionValues}
-import scorex.core.network.peer.PeerInfo
-import scorex.core.utils.ScorexEncoding
-import scorex.util.ScorexLogging
-
-import java.net.InetSocketAddress
-import java.util.concurrent.Executors
-import scala.concurrent.{Await, ExecutionContext, Future}
-
-trait ErgoTestHelpers
- extends ValidBlocksGenerators
- with ScorexLogging
- with ScorexEncoding
- with OptionValues
- with EitherValues {
-
- def await[A](f: Future[A]): A = Await.result[A](f, defaultAwaitDuration)
-
- def updateHeight(box: ErgoBoxCandidate, creationHeight: Int): ErgoBoxCandidate =
- new ErgoBoxCandidate(box.value, box.ergoTree, creationHeight, box.additionalTokens, box.additionalRegisters)
-
- def changeValue(box: ErgoBoxCandidate, delta: Long): Option[ErgoBoxCandidate] = {
- if (-delta >= box.value) {
- None
- } else {
- Some(new ErgoBoxCandidate(Math.addExact(box.value, delta), box.ergoTree, box.creationHeight,
- box.additionalTokens, box.additionalRegisters))
- }
- }
-
- val inetAddr1 = new InetSocketAddress("92.92.92.92", 27017)
- val inetAddr2 = new InetSocketAddress("93.93.93.93", 27017)
-
- val peers: Map[InetSocketAddress, PeerInfo] = Map(
- inetAddr1 -> PeerInfo(defaultPeerSpec.copy(nodeName = "first"), System.currentTimeMillis()),
- inetAddr2 -> PeerInfo(defaultPeerSpec.copy(nodeName = "second"), System.currentTimeMillis())
- )
-}
-
-object ErgoTestHelpers {
-
- implicit val defaultExecutionContext: ExecutionContext =
- ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/HistoryTestHelpers.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/HistoryTestHelpers.scala
deleted file mode 100644
index b38d920120..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/HistoryTestHelpers.scala
+++ /dev/null
@@ -1,92 +0,0 @@
-package org.ergoplatform.utils
-
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.history.storage.modifierprocessors.{EmptyBlockSectionProcessor, FullBlockPruningProcessor, ToDownloadProcessor}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.SortingOption
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.settings._
-import org.scalacheck.Gen
-import scorex.core.settings.ScorexSettings
-import scorex.util.ModifierId
-import scorex.util.encode.Base16
-
-import scala.concurrent.duration._
-
-trait HistoryTestHelpers extends ErgoPropertyTest {
-
- override lazy val smallInt: Gen[Int] = Gen.choose(0, BlocksInChain)
-
- val BlocksInChain = 10
- val BlocksToKeep: Int = BlocksInChain + 1
-
- def ensureMinimalHeight(history: ErgoHistory, height: Int = BlocksInChain): ErgoHistory = {
- val historyHeight = history.headersHeight
- if (historyHeight < height) {
- history match {
- case _: EmptyBlockSectionProcessor =>
- val chain = genHeaderChain(height - historyHeight, history, diffBitsOpt = None, useRealTs = false)
- if (history.isEmpty) applyHeaderChain(history, chain) else applyHeaderChain(history, chain.tail)
- case _ =>
- ???
- }
- } else {
- history
- }
- }
-
- // todo looks like copy-paste from Stubs.generateHistory
- def generateHistory(verifyTransactions: Boolean,
- stateType: StateType,
- PoPoWBootstrap: Boolean,
- blocksToKeep: Int,
- epochLength: Int = 100000000,
- useLastEpochs: Int = 10,
- initialDiffOpt: Option[BigInt] = None,
- genesisIdOpt: Option[ModifierId] = None): ErgoHistory = {
-
- val txCostLimit = initSettings.nodeSettings.maxTransactionCost
- val txSizeLimit = initSettings.nodeSettings.maxTransactionSize
- val nodeSettings: NodeConfigurationSettings = NodeConfigurationSettings(stateType, verifyTransactions, blocksToKeep,
- UtxoSettings(false, 0, 2), NipopowSettings(false, 1), mining = false, txCostLimit, txSizeLimit, useExternalMiner = false,
- internalMinersCount = 1, internalMinerPollingInterval = 1.second, miningPubKeyHex = None,
- offlineGeneration = false, 200, 5.minutes, 100000, 1.minute, mempoolSorting = SortingOption.FeePerByte,
- rebroadcastCount = 200, 1000000, 100, adProofsSuffixLength = 112*1024, extraIndex = false
-)
- val scorexSettings: ScorexSettings = null
- val walletSettings: WalletSettings = null
- val chainSettings = initialDiffOpt match {
- case Some(diff) =>
- val diffHex = Base16.encode(diff.toByteArray)
- settings.chainSettings.copy(epochLength = epochLength, useLastEpochs = useLastEpochs, initialDifficultyHex = diffHex, genesisId = genesisIdOpt)
- case _ =>
- settings.chainSettings.copy(epochLength = epochLength, useLastEpochs = useLastEpochs, genesisId = genesisIdOpt)
- }
-
- val dir = createTempDir
- val fullHistorySettings: ErgoSettings = ErgoSettings(dir.getAbsolutePath, NetworkType.TestNet, chainSettings,
- nodeSettings, scorexSettings, walletSettings, settings.cacheSettings)
-
- ErgoHistory.readOrGenerate(fullHistorySettings)(null)
- }
-
-}
-
-object HistoryTestHelpers {
-
- /**
- * Use reflection to set `minimalFullBlockHeightVar` to 0 to change regular synchronization rule, that we
- * first apply headers chain, and apply full blocks only after that
- */
- def allowToApplyOldBlocks(history: ErgoHistory): Unit = {
- import scala.reflect.runtime.{universe => ru}
- val runtimeMirror = ru.runtimeMirror(getClass.getClassLoader)
- val procInstance = runtimeMirror.reflect(history.asInstanceOf[ToDownloadProcessor])
- val ppM = ru.typeOf[ToDownloadProcessor].member(ru.TermName("pruningProcessor")).asMethod
- val pp = procInstance.reflectMethod(ppM).apply().asInstanceOf[FullBlockPruningProcessor]
- val f = ru.typeOf[FullBlockPruningProcessor].member(ru.TermName("minimalFullBlockHeightVar")).asTerm.accessed.asTerm
- runtimeMirror.reflect(pp).reflectField(f).set(ErgoHistory.GenesisHeight)
- val f2 = ru.typeOf[FullBlockPruningProcessor].member(ru.TermName("isHeadersChainSyncedVar")).asTerm.accessed.asTerm
- runtimeMirror.reflect(pp).reflectField(f2).set(true)
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/MempoolTestHelpers.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/MempoolTestHelpers.scala
deleted file mode 100644
index 2473790652..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/MempoolTestHelpers.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.ergoplatform.utils
-
-import org.ergoplatform.ErgoBox.BoxId
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.nodeView.mempool.{ErgoMemPoolReader, OrderedTxPool}
-import scorex.util.ModifierId
-
-trait MempoolTestHelpers {
-
- // mempool reader stub specifically for this test only take is defined as only this method is used in rebroadcasting
- class FakeMempool(txs: Seq[UnconfirmedTransaction]) extends ErgoMemPoolReader {
-
- override def modifierById(modifierId: ModifierId): Option[ErgoTransaction] = ???
-
- override def getAll(ids: Seq[ModifierId]): Seq[UnconfirmedTransaction] = ???
-
- override def size: Int = ???
-
- override def weightedTransactionIds(limit: Int): Seq[OrderedTxPool.WeightedTxId] = ???
-
- override def getAll: Seq[UnconfirmedTransaction] = ???
-
- override def getAllPrioritized: Seq[UnconfirmedTransaction] = txs
-
- override def take(limit: Int): Iterable[UnconfirmedTransaction] = txs.take(limit)
-
- override def random(limit: Int): Iterable[UnconfirmedTransaction] = take(limit)
-
- override def spentInputs: Iterator[BoxId] = txs.map(_.transaction).flatMap(_.inputs).map(_.boxId).toIterator
-
- override def getRecommendedFee(expectedWaitTimeMinutes: Int, txSize: Int) : Long = 0
-
- override def getExpectedWaitTime(txFee: Long, txSize: Int): Long = 0
-
- }
-
-}
-
-
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/NodeViewTestConfig.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/NodeViewTestConfig.scala
deleted file mode 100644
index 8df386a697..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/NodeViewTestConfig.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.ergoplatform.utils
-
-import org.ergoplatform.mining.DefaultFakePowScheme
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.settings.{ErgoSettings, NipopowSettings}
-
-
-case class NodeViewTestConfig(stateType: StateType,
- verifyTransactions: Boolean,
- popowBootstrap: Boolean) {
-
- def toSettings: ErgoSettings = {
- val defaultSettings = ErgoSettings.read()
- defaultSettings.copy(
- chainSettings = defaultSettings.chainSettings.copy(
- powScheme = new DefaultFakePowScheme(defaultSettings.chainSettings.powScheme.k, defaultSettings.chainSettings.powScheme.n)
- ),
- nodeSettings = defaultSettings.nodeSettings.copy(
- stateType = stateType,
- verifyTransactions = verifyTransactions,
- nipopowSettings = NipopowSettings(popowBootstrap, 1)
- )
- )
- }
-
- override def toString: String = {
- s"State: $stateType, Verify Transactions: $verifyTransactions, PoPoW Bootstrap: $popowBootstrap"
- }
-}
-
-object NodeViewTestConfig {
-
- def defaultConfig(config: ErgoSettings): ErgoSettings = config
-
- val allConfigs: List[NodeViewTestConfig] = List(
- NodeViewTestConfig(StateType.Digest, verifyTransactions = true, popowBootstrap = true),
- NodeViewTestConfig(StateType.Digest, verifyTransactions = false, popowBootstrap = true),
- NodeViewTestConfig(StateType.Digest, verifyTransactions = false, popowBootstrap = false),
- NodeViewTestConfig(StateType.Digest, verifyTransactions = true, popowBootstrap = false),
- NodeViewTestConfig(StateType.Utxo, verifyTransactions = true, popowBootstrap = true),
- NodeViewTestConfig(StateType.Utxo, verifyTransactions = true, popowBootstrap = false)
- )
-
- def verifyTxConfigs: List[NodeViewTestConfig] = NodeViewTestConfig.allConfigs.filter(_.verifyTransactions)
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/NodeViewTestContext.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/NodeViewTestContext.scala
deleted file mode 100644
index 22aaef02c0..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/NodeViewTestContext.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.ergoplatform.utils
-
-import akka.actor.{ActorRef, ActorSystem}
-import akka.testkit.TestProbe
-import org.ergoplatform.settings.ErgoSettings
-
-trait NodeViewTestContext {
- def settings: ErgoSettings
- def actorSystem: ActorSystem
- def testProbe: TestProbe
- def nodeViewHolderRef: ActorRef
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/NodeViewTestOps.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/NodeViewTestOps.scala
deleted file mode 100644
index d78b852d81..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/NodeViewTestOps.scala
+++ /dev/null
@@ -1,157 +0,0 @@
-package org.ergoplatform.utils
-
-import akka.actor.ActorRef
-import akka.pattern.ask
-import akka.util.Timeout
-import org.ergoplatform.modifiers.history.extension.Extension
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.modifiers.{ErgoFullBlock, BlockSection}
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.state.{ErgoState, StateType, UtxoState}
-import org.ergoplatform.settings.Algos
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.CurrentView
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.{GetDataFromCurrentView, LocallyGeneratedModifier}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages._
-import scorex.core.validation.MalformedModifierError
-import scorex.util.ModifierId
-
-import scala.concurrent.duration._
-import scala.reflect.ClassTag
-import scala.util.{Failure, Success, Try}
-
-trait NodeViewBaseOps extends ErgoTestHelpers {
-
- type Ctx = NodeViewTestContext
- type CurView = CurrentView[ErgoState[_]]
- implicit private val timeout: Timeout = defaultTimeout
-
- def getCurrentView(implicit ctx: Ctx): CurView = {
- val request = GetDataFromCurrentView[ErgoState[_], CurView](view => view)
- await((nodeViewHolderRef ? request).mapTo[CurView])
- }
-
- def getHistory(implicit ctx: Ctx): ErgoHistory = getCurrentView.history
-
- def getCurrentState(implicit ctx: Ctx): ErgoState[_] = getCurrentView.state
-
- def verifyTransactions(implicit ctx: Ctx): Boolean = ctx.settings.nodeSettings.verifyTransactions
-
- def stateType(implicit ctx: Ctx): StateType = ctx.settings.nodeSettings.stateType
-
- def applyHeader(header: Header)(implicit ctx: Ctx): Try[Unit] = {
- subscribeModificationOutcome()
- nodeViewHolderRef ! LocallyGeneratedModifier(header)
- expectModificationOutcome(header)
- }
-
- def applyBlock(fullBlock: ErgoFullBlock, excludeExt: Boolean = false)(implicit ctx: Ctx): Try[Unit] = {
- subscribeModificationOutcome()
- nodeViewHolderRef ! LocallyGeneratedModifier(fullBlock.header)
- expectModificationOutcome(fullBlock.header).flatMap(_ => applyPayload(fullBlock, excludeExt))
- }
-
- def applyPayload(fullBlock: ErgoFullBlock, excludeExt: Boolean = false)(implicit ctx: Ctx): Try[Unit] = {
- subscribeModificationOutcome()
- val sections = if (verifyTransactions && excludeExt) {
- fullBlock.blockSections.filterNot(_.modifierTypeId == Extension.modifierTypeId)
- } else if (verifyTransactions) {
- fullBlock.blockSections
- } else {
- Seq.empty
- }
- sections.foldLeft(Success(()): Try[Unit]) { (lastResult, section) =>
- lastResult.flatMap { _ =>
- nodeViewHolderRef ! LocallyGeneratedModifier(section)
- section match {
- case Extension(_, Seq(), _) => Success(()) // doesn't send back any outcome
- case _ => expectModificationOutcome(section) // normal flow
- }
- }
- }
- }
-
- def subscribeModificationOutcome()(implicit ctx: Ctx): Unit = {
- subscribeEvents(classOf[SyntacticallySuccessfulModifier])
- subscribeEvents(classOf[SyntacticallyFailedModification])
- }
-
- def expectModificationOutcome(section: BlockSection)(implicit ctx: Ctx): Try[Unit] = {
- expectMsgType[ModificationOutcome] match {
- case SyntacticallySuccessfulModifier(_, modId) if modId == section.id =>
- Success(())
- case outcome =>
- val msg = section match {
- case header: Header => s"Error applying header ${header.id}: $outcome"
- case other => s"Error applying section $other: $outcome"
- }
- val e = new MalformedModifierError(msg, section.id, section.modifierTypeId)
- log.error(msg, e)
- Failure(e)
- }
- }
-
- /** Creates next block in chain from transactions, works only for UTXO configurations
- */
- def makeNextBlock(utxoState: UtxoState,
- txs: Seq[ErgoTransaction])
- (implicit ctx: Ctx): ErgoFullBlock = {
- val time = System.currentTimeMillis()
- val parent = getHistory.bestFullBlockOpt
- validFullBlock(parent, utxoState, txs, Some(time))
- }
-
- @inline private def nodeViewHolderRef(implicit ctx: Ctx): ActorRef = ctx.nodeViewHolderRef
-
- @inline def send(msg: Any)(implicit ctx: Ctx): Unit = ctx.testProbe.send(nodeViewHolderRef, msg)
-
- @inline def ctxTimeout(implicit ctx: Ctx): FiniteDuration = ctx.testProbe.remainingOrDefault
-
- @inline def expectMsg[T](obj: T)(implicit ctx: Ctx): T = ctx.testProbe.expectMsg(obj)
-
- @inline def expectMsgType[T](implicit ctx: Ctx, t: ClassTag[T]): T = ctx.testProbe.expectMsgType
-
- @inline def expectNoMsg()(implicit ctx: Ctx): Unit = ctx.testProbe.expectNoMessage(ctxTimeout)
-
- @inline def ignoreMsg(f: PartialFunction[Any, Boolean])(implicit ctx: Ctx): Unit = ctx.testProbe.ignoreMsg(f)
-
- @inline def ignoreNoMsg()(implicit ctx: Ctx): Unit = ctx.testProbe.ignoreNoMsg()
-
- @inline def subscribeEvents(eventType: Class[_])(implicit ctx: Ctx): Boolean = {
- ctx.actorSystem.eventStream.subscribe(ctx.testProbe.ref, eventType)
- }
-
- @inline def unsubscribeEvents(eventType: Class[_])(implicit ctx: Ctx): Boolean = {
- ctx.actorSystem.eventStream.unsubscribe(ctx.testProbe.ref, eventType)
- }
-}
-
-trait NodeViewTestOps extends NodeViewBaseOps {
-
- def getBestHeaderOpt(implicit ctx: Ctx): Option[Header] = getHistory.bestHeaderOpt
-
- def getPoolSize(implicit ctx: Ctx): Int = getCurrentView.pool.size
-
- def getRootHash(implicit ctx: Ctx): String = Algos.encode(getCurrentState.rootDigest)
-
- def getBestFullBlockOpt(implicit ctx: Ctx): Option[ErgoFullBlock] = getHistory.bestFullBlockOpt
-
- def getBestFullBlockEncodedId(implicit ctx: Ctx): Option[String] = getBestFullBlockOpt.map(_.header.encodedId)
-
- def getBestHeaderEncodedId(implicit ctx: Ctx): Option[String] = getBestHeaderOpt.map(_.encodedId)
-
-
- def getHistoryHeight(implicit ctx: Ctx): Int = getHistory.headersHeight
-
- def getHeightOf(id: scorex.util.ModifierId)(implicit ctx: Ctx): Option[Int] = getHistory.heightOf(id)
-
- def getLastHeadersLength(count: Int)(implicit ctx: Ctx): Int = getHistory.lastHeaders(count).size
-
- def getModifierById(id: ModifierId)(implicit ctx: Ctx): Option[BlockSection] = getHistory.modifierById(id)
-
- def getGenesisStateDigest(implicit ctx: Ctx): Array[Byte] =
- ctx.settings.chainSettings.genesisStateDigest
-
-}
-
-object NodeViewTestOps extends NodeViewTestOps
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/RandomLike.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/RandomLike.scala
deleted file mode 100644
index fe4dfe6821..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/RandomLike.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.ergoplatform.utils
-
-import scala.util.Random
-
-trait RandomLike {
- def nextInt(i: Int): Int
- def nextBoolean(): Boolean
- def nextLong(): Long
- def nextDouble(): Double
-}
-
-class RandomWrapper(seed: Option[Int] = None) extends RandomLike {
- private[this] val rnd = seed.fold(new Random)(s => new Random(s))
- override def nextInt(i: Int): Int = rnd.nextInt(i)
- override def nextBoolean(): Boolean = rnd.nextBoolean()
- override def nextLong(): Long = rnd.nextLong()
- override def nextDouble(): Double = rnd.nextDouble()
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/Stubs.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/Stubs.scala
deleted file mode 100644
index b68886a573..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/Stubs.scala
+++ /dev/null
@@ -1,405 +0,0 @@
-package org.ergoplatform.utils
-
-import akka.actor.{Actor, ActorRef, ActorSystem, Props}
-import akka.pattern.StatusReply
-import org.bouncycastle.util.BigIntegers
-import org.ergoplatform.P2PKAddress
-import org.ergoplatform.mining.CandidateGenerator.Candidate
-import org.ergoplatform.mining.{AutolykosSolution, CandidateGenerator, ErgoMiner, WorkMessage}
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedTransaction
-import org.ergoplatform.nodeView.ErgoReadersHolder.{GetDataFromHistory, GetReaders, Readers}
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.{ProcessingOutcome, SortingOption}
-import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
-import org.ergoplatform.nodeView.state.{DigestState, ErgoStateContext, StateType}
-import org.ergoplatform.nodeView.wallet.ErgoWalletActor._
-import org.ergoplatform.nodeView.wallet.ErgoWalletService.DeriveNextKeyResult
-import org.ergoplatform.nodeView.wallet._
-import org.ergoplatform.nodeView.wallet.persistence.WalletDigest
-import org.ergoplatform.nodeView.wallet.scanning.Scan
-import org.ergoplatform.sanity.ErgoSanity.HT
-import org.ergoplatform.sdk.wallet.secrets.{DerivationPath, ExtendedSecretKey}
-import org.ergoplatform.settings.Constants.HashLength
-import org.ergoplatform.settings._
-import org.ergoplatform.utils.generators.{ChainGenerator, ErgoGenerators, ErgoTransactionGenerators}
-import org.ergoplatform.wallet.Constants.{PaymentsScanId, ScanId}
-import org.ergoplatform.wallet.boxes.{ChainStatus, TrackedBox}
-import org.ergoplatform.wallet.interface4j.SecretString
-import org.ergoplatform.wallet.interpreter.ErgoProvingInterpreter
-import org.ergoplatform.wallet.mnemonic.Mnemonic
-import org.ergoplatform.wallet.utils.TestFileUtils
-import org.scalacheck.Gen
-import scorex.core.app.Version
-import scorex.core.network.NetworkController.ReceivableMessages.GetConnectedPeers
-import scorex.core.network.peer.PeerManager.ReceivableMessages.{GetAllPeers, GetBlacklistedPeers}
-import scorex.core.network.{Handshake, PeerSpec}
-import scorex.core.settings.ScorexSettings
-import scorex.crypto.authds.ADDigest
-import scorex.crypto.hash.Digest32
-import scorex.db.ByteArrayWrapper
-import scorex.util.Random
-import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog}
-
-import scala.collection.mutable
-import scala.concurrent.duration._
-import scala.util.{Failure, Success, Try}
-
-trait Stubs extends ErgoGenerators with ErgoTestHelpers with ChainGenerator with TestFileUtils {
-
- implicit val system: ActorSystem
-
- val chain: Seq[ErgoFullBlock] = genChain(6)
-
- val history: HT = applyChain(generateHistory(), chain)
-
- val digestState: DigestState = {
- boxesHolderGen.map(WrappedUtxoState(_, createTempDir, None, parameters, settings)).map { wus =>
- DigestState.create(Some(wus.version), Some(wus.rootDigest), createTempDir, settings)
- }
- }.sample.value
-
- val utxoSettings: ErgoSettings = settings.copy(nodeSettings = settings.nodeSettings.copy(stateType = StateType.Utxo))
-
- val utxoState: WrappedUtxoState =
- boxesHolderGen.map(WrappedUtxoState(_, createTempDir, None, parameters, utxoSettings)).sample.value
-
- lazy val wallet = new WalletStub
-
- val txs: Seq[ErgoTransaction] = validTransactionsFromBoxHolder(boxesHolderGen.sample.get)._1
- val memPool: ErgoMemPool = ErgoMemPool.empty(settings).put(txs.map(tx => UnconfirmedTransaction(tx, None)))
-
- val digestReaders = Readers(history, digestState, memPool, wallet)
-
- val utxoReaders = Readers(history, utxoState, memPool, wallet)
-
- val protocolVersion = Version("1.1.1")
-
- val peerSpec: PeerSpec = defaultPeerSpec.copy(protocolVersion = protocolVersion)
-
- val connectedPeers: Seq[Handshake] = Seq(
- Handshake(peerSpec.copy(nodeName = "first"), System.currentTimeMillis() - 100),
- Handshake(peerSpec.copy(nodeName = "second"), System.currentTimeMillis() + 100)
- )
-
- val blacklistedPeers: Seq[String] = Seq("4.4.4.4:1111", "8.8.8.8:2222")
-
- val pk: ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray(Random.randomBytes(32))).publicImage
- val externalWorkMessage = WorkMessage(Array.fill(32)(2: Byte), BigInt(9999), None, pk, None)
-
- class PeersManagerStub extends Actor {
- def receive: Receive = {
- case GetAllPeers => sender() ! peers
- case GetBlacklistedPeers => sender() ! blacklistedPeers
- }
- }
-
- object PeersManagerStub {
- def props(): Props = Props(new PeersManagerStub)
- }
-
- class MinerStub extends Actor {
- def receive: Receive = {
- case CandidateGenerator.GenerateCandidate(_, reply) =>
- if (reply) {
- val candidate = Candidate(null, externalWorkMessage, Seq.empty) // API does not use CandidateBlock
- sender() ! StatusReply.success(candidate)
- }
- case _: AutolykosSolution => sender() ! StatusReply.success(())
- case ErgoMiner.ReadMinerPk => sender() ! StatusReply.success(pk)
- }
- }
-
- object MinerStub {
- def props(): Props = Props(new MinerStub)
- }
-
- class NodeViewStub extends Actor {
- def receive: Receive = {
- case LocallyGeneratedTransaction(utx) =>
- sender() ! new ProcessingOutcome.Accepted(utx, System.currentTimeMillis())
- case _ =>
- }
- }
-
- class FailingNodeViewStub extends Actor {
- def receive: Receive = {
- case LocallyGeneratedTransaction(_) =>
- sender() ! new ProcessingOutcome.Invalidated(new Error("Transaction invalid"), System.currentTimeMillis())
- case _ =>
- }
- }
-
- object NodeViewStub {
- def props(): Props = Props(new NodeViewStub)
- def failingProps(): Props = Props(new FailingNodeViewStub)
- }
-
- class NetworkControllerStub extends Actor {
- def receive: Receive = {
- case GetConnectedPeers => sender() ! connectedPeers
- case _ =>
- }
- }
-
- object NetworkControllerStub {
- def props(): Props = Props(new NetworkControllerStub)
- }
-
- class PeerManagerStub extends Actor {
- def receive: Receive = {
- case _ =>
- }
- }
-
- object PeerManagerStub {
- def props(): Props = Props(new PeerManagerStub)
- }
-
- class WalletActorStub extends Actor {
-
- import WalletActorStub._
-
- private val prover: ErgoProvingInterpreter = defaultProver
- private val trackedAddresses: Seq[P2PKAddress] = prover.hdPubKeys.map(epk => P2PKAddress(epk.key))
-
- private val apps = mutable.Map[ScanId, Scan]()
-
- private val ergoWalletService = new ErgoWalletServiceImpl(settings)
-
- def receive: Receive = {
-
- case _: InitWallet => sender() ! Success(SecretString.create(WalletActorStub.mnemonic))
-
- case _: RestoreWallet => sender() ! Success(())
-
- case _: UnlockWallet => sender() ! Success(())
-
- case LockWallet => ()
-
- case RescanWallet(_) => sender ! Success(())
-
- case GetWalletStatus => sender() ! WalletStatus(true, true, None, ErgoHistory.GenesisHeight, error = None)
-
- case _: CheckSeed => sender() ! true
-
- case GetWalletBoxes(unspentOnly, _) =>
- val boxes = if (unspentOnly) {
- Seq(walletBox10_10, walletBox20_30)
- } else {
- Seq(walletBox10_10, walletBox20_30, walletBoxSpent21_31)
- }
- sender() ! boxes.sortBy(_.trackedBox.inclusionHeightOpt)
-
- case GetScanTransactions(scanId, includeUnconfirmed) =>
- if (includeUnconfirmed) {
- sender() ! ScanRelatedTxsResponse(walletTxsForScan(scanId, includeUnconfirmed = true))
- } else {
- sender() ! ScanRelatedTxsResponse(walletTxsForScan(scanId))
- }
-
- case GetTransactions =>
- sender() ! walletTxs
-
- case DeriveKey(_) => sender() ! Success(WalletActorStub.address)
-
- case DeriveNextKey => sender() !
- DeriveNextKeyResult(Success((WalletActorStub.path, WalletActorStub.address, WalletActorStub.secretKey)))
-
- case ReadPublicKeys(from, until) =>
- sender() ! trackedAddresses.slice(from, until)
-
- case ReadBalances(chainStatus) =>
- sender() ! WalletDigest(0, WalletActorStub.balance(chainStatus), mutable.WrappedArray.empty)
-
- case AddScan(req) =>
- val scanId = ScanId @@ (apps.lastOption.map(_._1).getOrElse(100: Short) + 1).toShort
- val app = req.toScan(scanId)
- apps += scanId -> app.get
- sender() ! AddScanResponse(app)
-
- case RemoveScan(scanId) =>
- val res: Try[Unit] = if(apps.exists(_._1 == scanId)) {
- apps.remove(scanId)
- Success(())
- } else {
- Failure(new Exception(""))
- }
- sender() ! RemoveScanResponse(res)
-
- case GetScanUnspentBoxes(_, considerUnconfirmed, minHeight, maxHeight) =>
- val unfiltered = if(considerUnconfirmed) {
- Seq(walletBoxN_N)
- } else {
- Seq(walletBox10_10, walletBox20_30, walletBoxSpent21_31)
- }
- val res = unfiltered.filter { box =>
- box.trackedBox.inclusionHeightOpt.getOrElse(0) >= minHeight &&
- (maxHeight == -1 || box.trackedBox.inclusionHeightOpt.getOrElse(Int.MaxValue) <= maxHeight)
- }
- sender() ! res
-
- case GetScanSpentBoxes(_) =>
- sender() ! Seq(walletBox10_10, walletBox20_30, walletBoxSpent21_31)
-
- case StopTracking(_, _) =>
- sender() ! StopTrackingResponse(Success(()))
-
- case ReadScans =>
- sender() ! ReadScansResponse(apps.values.toSeq)
-
- case GenerateTransaction(_, _, _, _) =>
- val input = ErgoTransactionGenerators.inputGen.sample.value
- val tx = ErgoTransaction(IndexedSeq(input), IndexedSeq(ergoBoxCandidateGen.sample.value))
- sender() ! Success(tx)
-
- case SignTransaction(tx, secrets, hints, boxesToSpendOpt, dataBoxesOpt) =>
- val sc = ErgoStateContext.empty(settings, parameters)
- sender() ! ergoWalletService.signTransaction(Some(prover), tx, secrets, hints, boxesToSpendOpt, dataBoxesOpt, parameters, sc) { boxId =>
- utxoState.versionedBoxHolder.get(ByteArrayWrapper(boxId))
- }
- }
- }
-
- object WalletActorStub {
- val mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon"
- val path = DerivationPath(List(0, 1, 2), publicBranch = false)
- val secretKey = ExtendedSecretKey.deriveMasterKey(Mnemonic.toSeed(SecretString.create(mnemonic)), usePre1627KeyDerivation = false).derive(path)
- val address = P2PKAddress(proveDlogGen.sample.get)
-
- val walletBoxN_N: WalletBox = WalletBox(
- TrackedBox(
- creationTxId = modifierIdGen.sample.get,
- creationOutIndex = 0,
- inclusionHeightOpt = None,
- spendingTxIdOpt = Some(modifierIdGen.sample.get),
- spendingHeightOpt = None,
- box = ergoBoxGen.sample.get,
- scans = Set(PaymentsScanId)
- ),
- confirmationsNumOpt = None
- )
-
- val walletBox10_10: WalletBox = WalletBox(
- TrackedBox(
- creationTxId = modifierIdGen.sample.get,
- creationOutIndex = 0,
- inclusionHeightOpt = Some(10),
- spendingTxIdOpt = Some(modifierIdGen.sample.get),
- spendingHeightOpt = None,
- box = ergoBoxGen.sample.get,
- scans = Set(PaymentsScanId)
- ),
- confirmationsNumOpt = Some(10)
- )
- val walletBox20_30: WalletBox = walletBox10_10.copy(
- confirmationsNumOpt = Some(20),
- trackedBox = walletBox10_10.trackedBox.copy(inclusionHeightOpt = Some(30))
- )
- val walletBoxSpent21_31: WalletBox = walletBox10_10.copy(
- confirmationsNumOpt = Some(21),
- trackedBox = walletBox10_10.trackedBox.copy(
- inclusionHeightOpt = Some(31),
- spendingHeightOpt = Some(32),
- spendingTxIdOpt = Some(modifierIdGen.sample.get)
- )
- )
- val walletTxs: Seq[AugWalletTransaction] =
- Gen.listOf(augWalletTransactionGen).sample.get
-
- def walletTxsForScan(scanId: ScanId, includeUnconfirmed: Boolean = false): Seq[AugWalletTransaction] =
- Gen.listOf(augWalletTransactionForScanGen(scanId, includeUnconfirmed)).sample.get
-
- def props(): Props = Props(new WalletActorStub)
-
- def balance(chainStatus: ChainStatus): Long = if (chainStatus.onChain) confirmedBalance else unconfirmedBalance
-
- def confirmedBalance: Long = 1L
-
- def unconfirmedBalance: Long = 2L
- }
-
- class WalletStub extends ErgoWalletReader {
- val walletActor: ActorRef = system.actorOf(WalletActorStub.props())
- }
-
-
- class DigestReadersStub extends Actor {
- def receive: PartialFunction[Any, Unit] = {
- case GetReaders => sender() ! digestReaders
- case GetDataFromHistory(f) => sender() ! f(history)
- }
- }
-
- object DigestReadersStub {
- def props(): Props = Props(new DigestReadersStub)
- }
-
- class UtxoReadersStub extends Actor {
- def receive: PartialFunction[Any, Unit] = {
- case GetReaders => sender() ! utxoReaders
- case GetDataFromHistory(f) => sender() ! f(history)
- }
- }
-
- object UtxoReadersStub {
- def props(): Props = Props(new UtxoReadersStub)
- }
-
-
- lazy val digestReadersRef: ActorRef = system.actorOf(DigestReadersStub.props())
- lazy val utxoReadersRef: ActorRef = system.actorOf(UtxoReadersStub.props())
-
- lazy val minerRef: ActorRef = system.actorOf(MinerStub.props())
- lazy val peerManagerRef: ActorRef = system.actorOf(PeerManagerStub.props())
- lazy val pmRef: ActorRef = system.actorOf(PeersManagerStub.props())
- lazy val nodeViewRef: ActorRef = system.actorOf(NodeViewStub.props())
- lazy val networkControllerRef: ActorRef = system.actorOf(NetworkControllerStub.props())
-
- def generateHistory(verifyTransactions: Boolean = true,
- stateType: StateType = StateType.Digest,
- poPoWBootstrap: Boolean = false,
- blocksToKeep: Int = 100,
- epochLength: Int = 100000000,
- useLastEpochs: Int = 10): ErgoHistory = {
-
- val txCostLimit = initSettings.nodeSettings.maxTransactionCost
- val txSizeLimit = initSettings.nodeSettings.maxTransactionSize
- val nodeSettings: NodeConfigurationSettings = NodeConfigurationSettings(stateType, verifyTransactions, blocksToKeep,
- UtxoSettings(false, 0, 2), NipopowSettings(poPoWBootstrap, 1), mining = false, txCostLimit, txSizeLimit, useExternalMiner = false,
- internalMinersCount = 1, internalMinerPollingInterval = 1.second,miningPubKeyHex = None,
- offlineGeneration = false, 200, 5.minutes, 100000, 1.minute, mempoolSorting = SortingOption.FeePerByte,
- rebroadcastCount = 200, 1000000, 100, adProofsSuffixLength = 112*1024, extraIndex = false
-)
- val scorexSettings: ScorexSettings = null
- val walletSettings: WalletSettings = null
- val chainSettings = settings.chainSettings.copy(epochLength = epochLength, useLastEpochs = useLastEpochs)
-
- val dir = createTempDir
- val fullHistorySettings: ErgoSettings = ErgoSettings(dir.getAbsolutePath, NetworkType.TestNet, chainSettings,
- nodeSettings, scorexSettings, walletSettings, settings.cacheSettings)
-
- ErgoHistory.readOrGenerate(fullHistorySettings)(null)
- }
-
- def syntacticallyValidModifier(history: HT): Header = {
- val bestTimestamp = history.bestHeaderOpt.map(_.timestamp + 1).getOrElse(System.currentTimeMillis())
-
- powScheme.prove(
- history.bestHeaderOpt,
- Header.InitialVersion,
- settings.chainSettings.initialNBits,
- ADDigest @@ Array.fill(HashLength + 1)(0.toByte),
- Digest32 @@ Array.fill(HashLength)(0.toByte),
- Digest32 @@ Array.fill(HashLength)(0.toByte),
- Math.max(System.currentTimeMillis(), bestTimestamp),
- Digest32 @@ Array.fill(HashLength)(0.toByte),
- Array.fill(3)(0: Byte),
- defaultMinerSecretNumber
- ).value
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/TestCase.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/TestCase.scala
deleted file mode 100644
index 50d000026d..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/TestCase.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.ergoplatform.utils
-
-import org.ergoplatform.settings.Parameters
-import org.ergoplatform.utils.fixtures.NodeViewFixture
-
-case class TestCase(name: String)(test: NodeViewFixture => Unit) {
- def run(parameters: Parameters, c: NodeViewTestConfig): Unit =
- new NodeViewFixture(c.toSettings, parameters).apply(test)
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala
deleted file mode 100644
index 42407311f2..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala
+++ /dev/null
@@ -1,142 +0,0 @@
-package org.ergoplatform.utils
-
-import org.ergoplatform.ErgoBox.TokenId
-import org.ergoplatform._
-import org.ergoplatform.mining.CandidateGenerator
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.state.{ErgoState, UtxoState}
-import org.ergoplatform.nodeView.wallet.ErgoWallet
-import org.ergoplatform.nodeView.wallet.IdUtils._
-import org.ergoplatform.nodeView.wallet.persistence.WalletDigest
-import org.ergoplatform.sdk.wallet.TokensMap
-import org.ergoplatform.settings.Constants
-import org.ergoplatform.utils.fixtures.WalletFixture
-import scorex.crypto.authds.ADKey
-import scorex.crypto.hash.Blake2b256
-import scorex.util.ModifierId
-import sigma.Colls
-import sigmastate.Values.ErgoTree
-import sigmastate.crypto.DLogProtocol.ProveDlog
-import sigmastate.eval.Extensions._
-import sigmastate.eval._
-import sigmastate.interpreter.ProverResult
-import sigma.Extensions._
-
-trait WalletTestOps extends NodeViewBaseOps {
-
- def newAssetIdStub: TokenId = Blake2b256.hash("new_asset").toTokenId
-
- def withFixture[T](test: WalletFixture => T): T =
- new WalletFixture(settings, parameters, getCurrentView(_).vault).apply(test)
-
- def wallet(implicit w: WalletFixture): ErgoWallet = w.wallet
-
- def getPublicKeys(implicit w: WalletFixture): Seq[P2PKAddress] =
- await(w.wallet.publicKeys(0, Int.MaxValue))
-
- def getConfirmedBalances(implicit w: WalletFixture): WalletDigest =
- await(w.wallet.confirmedBalances)
-
- def getBalancesWithUnconfirmed(implicit w: WalletFixture): WalletDigest =
- await(w.wallet.balancesWithUnconfirmed)
-
- def offchainScanTime(tx: ErgoTransaction): Long = tx.outputs.size * 100 + 300
-
- def balanceAmount(boxes: Seq[ErgoBox]): Long = boxes.map(_.value).sum
-
- def boxesAvailable(block: ErgoFullBlock, pk: ProveDlog): Seq[ErgoBox] =
- block.transactions.flatMap(boxesAvailable(_, pk))
-
- def boxesAvailable(tx: ErgoTransaction, pk: ProveDlog): Seq[ErgoBox] =
- tx.outputs.filter(_.propositionBytes.containsSlice(org.ergoplatform.mining.groupElemToBytes(pk.value)))
-
- def assetAmount(boxes: Seq[ErgoBoxCandidate]): Seq[(ModifierId, Long)] =
- assetsByTokenId(boxes).map { case (tokenId, sum) => (tokenId.toModifierId, sum) }.toArray[(ModifierId, Long)]
-
- def toAssetMap(assetSeq: Seq[(TokenId, Long)]): TokensMap =
- assetSeq.map { case (tokenId, sum) => (tokenId.toModifierId, sum) }.toMap
-
- def assetsByTokenId(boxes: Seq[ErgoBoxCandidate]): Map[TokenId, Long] = {
- boxes
- .flatMap(_.additionalTokens.toArray)
- .foldLeft(Map.empty[EncodedTokenId, Long]) { case (acc, (id, amt)) =>
- acc.updated(encodedTokenId(id), acc.getOrElse(encodedTokenId(id), 0L) + amt)
- }
- .map(x => decodedTokenId(x._1) -> x._2)
- }
-
- def getUtxoState(implicit ctx: Ctx): UtxoState = getCurrentState.asInstanceOf[UtxoState]
-
- def getHeightOf(state: ErgoState[_])(implicit ctx: Ctx): Option[Int] =
- getHistory.heightOf(scorex.core.versionToId(state.version))
-
- def makeGenesisBlock(script: ProveDlog, assets: Seq[(TokenId, Long)] = Seq.empty)
- (implicit ctx: Ctx): ErgoFullBlock = {
- makeNextBlock(getUtxoState, Seq(makeGenesisTx(script, assets)))
- }
-
- def makeGenesisTxWithAsset(publicKey: ProveDlog, issueAsset: Boolean): ErgoTransaction = {
- val inputs = IndexedSeq(new Input(genesisEmissionBox.id, emptyProverResult))
- val assets: Seq[(TokenId, Long)] = if (issueAsset) {
- Seq(inputs.head.boxId.toTokenId -> 1L)
- } else {
- Seq.empty
- }
-
- CandidateGenerator.collectRewards(Some(genesisEmissionBox),
- ErgoHistory.EmptyHistoryHeight,
- Seq.empty,
- publicKey,
- emptyStateContext,
- Colls.fromArray(assets.toArray)).head
- }
-
- def makeGenesisTx(publicKey: ProveDlog, assetsIn: Seq[(TokenId, Long)] = Seq.empty): ErgoTransaction = {
- val inputs = IndexedSeq(new Input(genesisEmissionBox.id, emptyProverResult))
- val assets: Seq[(TokenId, Long)] = replaceNewAssetStub(assetsIn, inputs)
- CandidateGenerator.collectRewards(Some(genesisEmissionBox),
- ErgoHistory.EmptyHistoryHeight,
- Seq.empty,
- publicKey,
- emptyStateContext,
- Colls.fromArray(assets.toArray)).head
- }
-
- def makeSpendingTx(boxesToSpend: Seq[ErgoBox],
- addressToReturn: ErgoAddress,
- balanceToReturn: Long = 0,
- assets: Seq[(TokenId, Long)] = Seq.empty): ErgoTransaction = {
- makeTx(boxesToSpend, emptyProverResult, balanceToReturn, addressToReturn.script, assets)
- }
-
- def makeTx(boxesToSpend: Seq[ErgoBox],
- proofToSpend: ProverResult,
- balanceToReturn: Long,
- scriptToReturn: ErgoTree,
- assets: Seq[(TokenId, Long)] = Seq.empty): ErgoTransaction = {
- val inputs = boxesToSpend.map(box => Input(box.id, proofToSpend))
- val balanceToSpend = boxesToSpend.map(_.value).sum - balanceToReturn
-
- def creatingCandidate = new ErgoBoxCandidate(balanceToReturn, scriptToReturn, startHeight, replaceNewAssetStub(assets, inputs).toColl)
-
- val spendingOutput = if (balanceToSpend > 0) Some(new ErgoBoxCandidate(balanceToSpend, Constants.TrueLeaf, creationHeight = startHeight)) else None
- val creatingOutput = if (balanceToReturn > 0) Some(creatingCandidate) else None
- ErgoTransaction(inputs.toIndexedSeq, spendingOutput.toIndexedSeq ++ creatingOutput.toIndexedSeq)
- }
-
- private def replaceNewAssetStub(assets: Seq[(TokenId, Long)], inputs: Seq[Input]): Seq[(TokenId, Long)] = {
- def isNewAsset(tokenId: TokenId, value: Long): Boolean = tokenId == newAssetIdStub
-
- val (newAsset, spentAssets) = assets.partition((isNewAsset _).tupled)
- newAsset.map(inputs.head.boxId.toTokenId -> _._2) ++ spentAssets
- }
-
- def randomNewAsset: Seq[(TokenId, Long)] = Seq(newAssetIdStub -> randomLong())
-
- def assetsWithRandom(boxes: Seq[ErgoBox]): Seq[(TokenId, Long)] = randomNewAsset ++ assetsByTokenId(boxes)
-
- val fakeInputs: IndexedSeq[Input] = IndexedSeq(Input(ADKey @@ Array.fill(32)(0: Byte), emptyProverResult))
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/fixtures/NodeViewFixture.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/fixtures/NodeViewFixture.scala
deleted file mode 100644
index 5127620226..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/fixtures/NodeViewFixture.scala
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.ergoplatform.utils.fixtures
-
-import akka.actor.{ActorRef, ActorSystem}
-import akka.testkit.TestProbe
-import org.ergoplatform.mining.emission.EmissionRules
-import org.ergoplatform.nodeView.ErgoNodeViewRef
-import org.ergoplatform.settings.{ErgoSettings, Parameters}
-import org.ergoplatform.utils.NodeViewTestContext
-import org.ergoplatform.wallet.utils.TestFileUtils
-
-import scala.concurrent.ExecutionContext
-
-/** This uses TestProbe to receive messages from actor.
- * To make TestProbe work `defaultSender` implicit should be imported
- */
-class NodeViewFixture(protoSettings: ErgoSettings, parameters: Parameters) extends NodeViewTestContext with TestFileUtils { self =>
-
- implicit val actorSystem: ActorSystem = ActorSystem()
- implicit val executionContext: ExecutionContext = actorSystem.dispatchers.lookup("scorex.executionContext")
- implicit def ctx: NodeViewTestContext = this
-
- val nodeViewDir: java.io.File = createTempDir
- @volatile var settings: ErgoSettings = protoSettings.copy(directory = nodeViewDir.getAbsolutePath)
- val emission: EmissionRules = new EmissionRules(settings.chainSettings.monetary)
- @volatile var nodeViewHolderRef: ActorRef = ErgoNodeViewRef(settings)
- val testProbe = new TestProbe(actorSystem)
-
- /** This sender should be imported to make TestProbe work! */
- implicit val defaultSender: ActorRef = testProbe.testActor
-
- def apply[T](test: self.type => T): T = try test(self) finally stop()
-
- def startNodeViewHolder(): Unit = {
- nodeViewHolderRef = ErgoNodeViewRef(settings)
- }
-
- def stopNodeViewHolder(): Unit = {
- actorSystem.stop(nodeViewHolderRef)
- Thread.sleep(2000)
- }
-
- /** Restarts nodeViewHolder and applies config override */
- def updateConfig(settingsOverride: ErgoSettings => ErgoSettings): Unit = {
- stopNodeViewHolder()
- settings = settingsOverride(settings)
- startNodeViewHolder()
- }
-
- def stop(): Unit = {
- stopNodeViewHolder()
- actorSystem.stop(testProbe.testActor)
- actorSystem.terminate()
- }
-}
-
-object NodeViewFixture {
- def apply(protoSettings: ErgoSettings, parameters: Parameters): NodeViewFixture =
- new NodeViewFixture(protoSettings, parameters)
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/fixtures/SequentialAkkaFixture.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/fixtures/SequentialAkkaFixture.scala
deleted file mode 100644
index 7258cbb214..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/fixtures/SequentialAkkaFixture.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.ergoplatform.utils.fixtures
-
-import java.util.concurrent.atomic.AtomicInteger
-
-import akka.actor.ActorSystem
-import akka.testkit.{TestKit, ImplicitSender}
-import org.scalatest.{Outcome, propspec}
-
-import scala.concurrent.Await
-import scala.concurrent.duration.Duration
-
-object SequentialAkkaFixture {
- val sysId = new AtomicInteger()
-}
-
-trait SequentialAkkaFixture extends propspec.FixtureAnyPropSpec {
- import SequentialAkkaFixture._
- type Fixture <: TestKit
- type FixtureParam = Fixture
-
- class AkkaFixture extends TestKit(ActorSystem("WithIsoFix-%d".format(sysId.incrementAndGet()))) with ImplicitSender
-
- def createAkkaFixture(): Fixture
-
- override def withFixture(test: OneArgTest): Outcome = {
- val sys = createAkkaFixture()
- try {
- test(sys)
- } finally {
- Await.result(sys.system.terminate(), Duration.Inf)
- }
- }
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/fixtures/WalletFixture.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/fixtures/WalletFixture.scala
deleted file mode 100644
index 56a1d90f7a..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/fixtures/WalletFixture.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.ergoplatform.utils.fixtures
-
-import org.ergoplatform.nodeView.wallet.ErgoWallet
-import org.ergoplatform.settings.{ErgoSettings, Parameters}
-
-class WalletFixture(
- settings: ErgoSettings,
- params: Parameters,
- getWallet: WalletFixture => ErgoWallet
-) extends NodeViewFixture(settings, params) {
- val wallet: ErgoWallet = getWallet(this)
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ChainGenerator.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ChainGenerator.scala
deleted file mode 100644
index cfe35ca205..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ChainGenerator.scala
+++ /dev/null
@@ -1,197 +0,0 @@
-package org.ergoplatform.utils.generators
-
-import org.ergoplatform.Input
-import org.ergoplatform.mining.difficulty.DifficultyAdjustment
-import org.ergoplatform.modifiers.history.HeaderChain
-import org.ergoplatform.modifiers.history.extension.{Extension, ExtensionCandidate}
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.history.popow.{NipopowAlgos, PoPowHeader}
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.modifiers.{BlockSection, ErgoFullBlock, NonHeaderBlockSection}
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.settings.Constants
-import org.ergoplatform.utils.{BoxUtils, ErgoTestConstants}
-import scorex.crypto.authds.{ADKey, SerializedAdProof}
-import scorex.crypto.hash.Digest32
-import sigma.Colls
-import sigmastate.eval._
-import sigmastate.helpers.TestingHelpers._
-import sigmastate.interpreter.{ContextExtension, ProverResult}
-
-import scala.util.Random
-
-trait ChainGenerator extends ErgoTestConstants {
-
- private def emptyProofs = SerializedAdProof @@ scorex.utils.Random.randomBytes(Random.nextInt(5000))
-
- /** Generates a [[HeaderChain]] of given height starting from last block of the `history`
- */
- def genHeaderChain(height: Int,
- history: ErgoHistory,
- diffBitsOpt: Option[Long],
- useRealTs: Boolean): HeaderChain = {
- val bestHeaderOpt = history.bestHeaderOpt
- bestHeaderOpt
- .flatMap(h => history.typedModifierById[Extension](h.extensionId))
- .map(ext => NipopowAlgos.unpackInterlinks(ext.fields).get)
- .getOrElse(Seq.empty)
- genHeaderChain(
- height,
- bestHeaderOpt,
- history.difficultyCalculator,
- diffBitsOpt = diffBitsOpt,
- useRealTs = useRealTs
- )
- }
-
- /** Generates a [[HeaderChain]] of given height starting from a given header
- */
- final def genHeaderChain(height: Int,
- prefixOpt: Option[Header] = None,
- control: DifficultyAdjustment = defaultDifficultyControl,
- extensionHash: Digest32 = EmptyDigest32,
- diffBitsOpt: Option[Long],
- useRealTs: Boolean): HeaderChain =
- HeaderChain(headerStream(prefixOpt, control, extensionHash, diffBitsOpt, useRealTs).take(height + prefixOpt.size))
-
- /** Generates a minimal [[HeaderChain]] that satisfies the given condition
- */
- final def genHeaderChain(until: Seq[Header] => Boolean,
- prefix: Option[Header],
- control: DifficultyAdjustment,
- diffBitsOpt: Option[Long],
- useRealTs: Boolean): HeaderChain = {
- val headers = headerStream(prefix, control, diffBitsOpt = diffBitsOpt, useRealTs = useRealTs)
- val chain = Iterator.from(prefix.size).map(size => headers.take(size)).find(until).get
- HeaderChain(chain)
- }
-
- def popowHeaderChain(chain: HeaderChain): Seq[PoPowHeader] = {
- chain.headers.foldLeft((Seq.empty[PoPowHeader], None: Option[PoPowHeader])) {
- case ((acc, bestHeaderOpt), h) =>
- val links = if (bestHeaderOpt.isEmpty) {
- Seq(scorex.util.bytesToId(Array.fill(32)(0: Byte)))
- } else {
- nipopowAlgos.updateInterlinks(
- bestHeaderOpt.map(_.header),
- bestHeaderOpt.map(ph => nipopowAlgos.interlinksToExtension(ph.interlinks).toExtension(ph.id))
- )
- }
- val interlinkProof = NipopowAlgos.proofForInterlinkVector(ExtensionCandidate(NipopowAlgos.packInterlinks(links)))
- .getOrElse(throw new Error(s"Failed to build interlink proof."))
- val poPowH = PoPowHeader(h, links, interlinkProof)
- (acc :+ poPowH, Some(poPowH))
- }._1
- }
-
- private def headerStream(prefix: Option[Header],
- control: DifficultyAdjustment,
- extensionHash: Digest32 = EmptyDigest32,
- diffBitsOpt: Option[Long],
- useRealTs: Boolean): Stream[Header] = {
- val firstHeader = nextHeader(prefix, control, extensionHash, diffBitsOpt = diffBitsOpt, useRealTs = useRealTs)
- lazy val headers: Stream[Header] = firstHeader #:: headers.map(cur =>
- nextHeader(Option(cur), control, extensionHash, diffBitsOpt = diffBitsOpt, useRealTs = useRealTs))
- prefix.toSeq ++: headers
- }
-
- def nextHeader(prev: Option[Header],
- control: DifficultyAdjustment,
- extensionHash: Digest32 = EmptyDigest32,
- tsOpt: Option[Long] = None,
- diffBitsOpt: Option[Long] = None,
- useRealTs: Boolean): Header =
- powScheme.prove(
- prev,
- Header.InitialVersion,
- diffBitsOpt.getOrElse(settings.chainSettings.initialNBits),
- EmptyStateRoot,
- EmptyDigest32,
- EmptyDigest32,
- tsOpt.getOrElse(prev.map(_.timestamp + control.desiredInterval.toMillis)
- .getOrElse(if (useRealTs) System.currentTimeMillis() else 0)),
- extensionHash,
- Array.fill(3)(0: Byte),
- defaultMinerSecretNumber
- ).get
-
- def genChain(height: Int): Seq[ErgoFullBlock] =
- blockStream(None).take(height)
-
- def genChain(height: Int, prefix: ErgoFullBlock): Seq[ErgoFullBlock] =
- blockStream(Option(prefix)).take(height + 1)
-
- def genChain(height: Int,
- history: ErgoHistory,
- blockVersion: Header.Version = Header.InitialVersion,
- nBits: Long = settings.chainSettings.initialNBits,
- extension: ExtensionCandidate = defaultExtension): Seq[ErgoFullBlock] = {
- val prefix = history.bestFullBlockOpt
- blockStream(prefix, blockVersion, nBits, extension).take(height + prefix.size)
- }
-
- protected def blockStream(prefix: Option[ErgoFullBlock],
- blockVersion: Header.Version = Header.InitialVersion,
- nBits: Long = settings.chainSettings.initialNBits,
- extension: ExtensionCandidate = defaultExtension): Stream[ErgoFullBlock] = {
- val proof = ProverResult(Array(0x7c.toByte), ContextExtension.empty)
- val inputs = IndexedSeq(Input(ADKey @@ Array.fill(32)(0: Byte), proof))
- val minimalAmount = BoxUtils.minimalErgoAmountSimulated(Constants.TrueLeaf, Colls.emptyColl, Map(), parameters)
- val outputs = IndexedSeq(testBox(minimalAmount, Constants.TrueLeaf, creationHeight = startHeight))
-
- def txs = Seq(ErgoTransaction(inputs, outputs))
-
- lazy val blocks: Stream[ErgoFullBlock] =
- nextBlock(prefix, txs, extension, blockVersion, nBits) #::
- blocks.zip(Stream.from(2)).map { case (prev, _) =>
- nextBlock(Option(prev), txs, extension, blockVersion, nBits)
- }
- prefix ++: blocks
- }
-
- def nextBlock(prev: Option[ErgoFullBlock],
- txs: Seq[ErgoTransaction],
- extension: ExtensionCandidate,
- blockVersion: Header.Version = Header.InitialVersion,
- nBits: Long = settings.chainSettings.initialNBits): ErgoFullBlock = {
- val interlinks = prev.toSeq.flatMap(x =>
- nipopowAlgos.updateInterlinks(x.header, NipopowAlgos.unpackInterlinks(x.extension.fields).get))
- val validExtension = extension ++ nipopowAlgos.interlinksToExtension(interlinks)
- powScheme.proveBlock(
- prev.map(_.header),
- blockVersion,
- nBits,
- EmptyStateRoot,
- emptyProofs,
- txs,
- Math.max(System.currentTimeMillis(), prev.map(_.header.timestamp + 1).getOrElse(System.currentTimeMillis())),
- validExtension,
- Array.fill(3)(0: Byte),
- defaultMinerSecretNumber
- ).get
- }
-
- def applyHeaderChain(historyIn: ErgoHistory, chain: HeaderChain): ErgoHistory = {
- var history = historyIn
- chain.headers.foreach { header =>
- history = history.append(header).get._1
- }
- history
- }
-
- def applyChain(historyIn: ErgoHistory, blocks: Seq[ErgoFullBlock]): ErgoHistory = {
- def appendOrPass(mod: BlockSection, history: ErgoHistory) =
- if (history.contains(mod)) history else history.append(mod).get._1
- blocks.foldLeft(historyIn) { (history, block) =>
- val historyWithBlockHeader = appendOrPass(block.header, history)
- val historyWithTxs = appendOrPass(block.blockTransactions, historyWithBlockHeader)
- val historyWithExtension = appendOrPass(block.extension, historyWithTxs)
- block.adProofs.map(p => appendOrPass(p, historyWithExtension)).getOrElse(historyWithExtension)
- }
- }
-
- def applyBlock(historyIn: ErgoHistory, block: ErgoFullBlock): ErgoHistory = applyChain(historyIn, Seq(block))
-
- def applySection(historyIn: ErgoHistory, section: NonHeaderBlockSection): ErgoHistory = historyIn.append(section).get._1
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoGenerators.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoGenerators.scala
deleted file mode 100644
index ad49b7557a..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoGenerators.scala
+++ /dev/null
@@ -1,216 +0,0 @@
-package org.ergoplatform.utils.generators
-
-import com.google.common.primitives.Shorts
-import org.bouncycastle.util.BigIntegers
-import org.ergoplatform.mining.difficulty.DifficultySerializer
-import org.ergoplatform.mining.{AutolykosSolution, genPk, q}
-import org.ergoplatform.modifiers.history.ADProofs
-import org.ergoplatform.modifiers.history.extension.Extension
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.history.popow.{NipopowProof, PoPowParams}
-import org.ergoplatform.network.ModePeerFeature
-import org.ergoplatform.nodeView.history.{ErgoSyncInfo, ErgoSyncInfoV1, ErgoSyncInfoV2}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.settings.{Constants, ErgoValidationSettings, ErgoValidationSettingsUpdate, ValidationRules}
-import org.ergoplatform.utils.ErgoTestConstants
-import org.ergoplatform.validation.{ChangedRule, DisabledRule, EnabledRule, ReplacedRule}
-import org.ergoplatform.wallet.utils.Generators
-import org.scalacheck.Arbitrary.arbByte
-import org.scalacheck.{Arbitrary, Gen}
-import org.scalatest.matchers.should.Matchers
-import scorex.crypto.authds.{ADDigest, SerializedAdProof}
-import scorex.crypto.hash.Digest32
-import scorex.testkit.generators.CoreGenerators
-import sigmastate.Values.ErgoTree
-import sigmastate.crypto.CryptoConstants.EcPointType
-import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog}
-import sigmastate.crypto.{CryptoConstants, DiffieHellmanTupleProverInput, ProveDHTuple}
-import sigmastate.interpreter.ProverResult
-
-import scala.util.Random
-
-trait ErgoGenerators extends CoreGenerators with ChainGenerator with Generators with Matchers with ErgoTestConstants {
-
- lazy val trueLeafGen: Gen[ErgoTree] = Gen.const(Constants.TrueLeaf)
- lazy val falseLeafGen: Gen[ErgoTree] = Gen.const(Constants.FalseLeaf)
-
- lazy val smallPositiveInt: Gen[Int] = Gen.choose(1, 5)
-
- lazy val noProofGen: Gen[ProverResult] =
- Gen.const(emptyProverResult)
-
- lazy val dlogSecretWithPublicImageGen: Gen[(DLogProverInput, ProveDlog)] = for {
- secret <- genBytes(32).map(seed => BigIntegers.fromUnsignedByteArray(seed))
- dlpi = DLogProverInput(secret)
- } yield (dlpi, dlpi.publicImage)
-
- lazy val dhtSecretWithPublicImageGen: Gen[(DiffieHellmanTupleProverInput, ProveDHTuple)] = for {
- secret <- genBytes(32).map(seed => BigIntegers.fromUnsignedByteArray(seed))
- g <- genECPoint
- h <- genECPoint
- u = CryptoConstants.dlogGroup.exponentiate(g, secret)
- v = CryptoConstants.dlogGroup.exponentiate(h, secret)
- dhtpi = DiffieHellmanTupleProverInput(secret, ProveDHTuple(g, h, u, v))
- } yield (dhtpi, dhtpi.publicImage)
-
- lazy val proveDlogGen: Gen[ProveDlog] = for {
- seed <- genBytes(32)
- } yield DLogProverInput(BigIntegers.fromUnsignedByteArray(seed)).publicImage
-
- lazy val proveDlogTreeGen: Gen[ErgoTree] = proveDlogGen.map(_.toSigmaProp)
-
- lazy val ergoPropositionGen: Gen[ErgoTree] = Gen.oneOf(trueLeafGen, falseLeafGen, proveDlogTreeGen)
-
- lazy val positiveIntGen: Gen[Int] = Gen.choose(1, Int.MaxValue)
-
- lazy val ergoSyncInfoV1Gen: Gen[ErgoSyncInfoV1] = for {
- ids <- Gen.nonEmptyListOf(modifierIdGen).map(_.take(ErgoSyncInfo.MaxBlockIds))
- } yield ErgoSyncInfoV1(ids)
-
- lazy val ergoSyncInfoV2Gen: Gen[ErgoSyncInfoV2] = for {
- hds <- Gen.nonEmptyListOf(invalidHeaderGen).map(_.take(5))
- } yield ErgoSyncInfoV2(hds)
-
- lazy val digest32Gen: Gen[Digest32] = {
- val x = Digest32 @@ genBytes(32)
- x
- }
-
- lazy val stateRootGen: Gen[ADDigest] = {
- val x = ADDigest @@ genBytes(Constants.ModifierIdSize + 1)
- x
- }
-
- lazy val serializedAdProofGen: Gen[SerializedAdProof] = {
- val x = SerializedAdProof @@ genBoundedBytes(32, 32 * 1024)
- x
- }
-
- def genSecureBoundedBytes(minSize: Int, maxSize: Int): Gen[Array[Byte]] =
- Gen.choose(minSize, maxSize).flatMap {
- scorex.util.Random.randomBytes
- }
-
- def extensionKvGen(keySize: Int, valuesSize: Int): Gen[(Array[Byte], Array[Byte])] = for {
- key <- genSecureBoundedBytes(keySize, keySize)
- value <- if (key.head == 0) genSecureBoundedBytes(4, 4) else genSecureBoundedBytes(valuesSize, valuesSize)
- } yield (key, value)
-
- lazy val extensionGen: Gen[Extension] = for {
- headerId <- modifierIdGen
- mandatoryElements <- Gen.mapOf(extensionKvGen(Extension.FieldKeySize, Extension.FieldValueMaxSize))
- } yield {
- val me = mandatoryElements
- .map(kv => Shorts.fromByteArray(kv._1) -> kv._2)
- .map(kv => Shorts.toByteArray(kv._1) -> kv._2)
- Extension(headerId, me.toSeq)
- }
-
- lazy val genECPoint: Gen[EcPointType] = genBytes(32).map(b => genPk(BigInt(b).mod(q)))
-
- lazy val powSolutionGen: Gen[AutolykosSolution] = for {
- pk <- genECPoint
- w <- genECPoint
- n <- genBytes(8)
- d <- Arbitrary.arbitrary[BigInt].map(_.mod(q - 1) + 1)
- } yield AutolykosSolution(pk, w, n, d)
-
- /**
- * Generates required difficulty in interval [1, 2^^255]
- **/
- lazy val requiredDifficultyGen: Gen[BigInt] = Arbitrary.arbitrary[BigInt].map(_.mod(BigInt(2).pow(255)).abs + 1)
-
- /*
- TODO: this generator is used sometimes to construct a full block. A generator for the latter is not generating
- a proper extension section for a beginning of a voting epoch (network parameter values should be in the extension
- in this case. Currently we're fixing it here with filtering out heights corresponding to the beginning of voting
- epochs. A more careful solution would be to implement proper generators.
- */
- lazy val invalidHeaderGen: Gen[Header] = for {
- version <- Arbitrary.arbitrary[Byte]
- parentId <- modifierIdGen
- stateRoot <- stateRootGen
- adRoot <- digest32Gen
- transactionsRoot <- digest32Gen
- requiredDifficulty <- requiredDifficultyGen
- height <- Gen.choose(1, Int.MaxValue).retryUntil(_ % settings.chainSettings.voting.votingLength != 0)
- powSolution <- powSolutionGen
- timestamp <- positiveLongGen
- extensionHash <- digest32Gen
- } yield Header(
- version,
- parentId,
- adRoot,
- stateRoot,
- transactionsRoot,
- timestamp,
- DifficultySerializer.encodeCompactBits(requiredDifficulty),
- height,
- extensionHash,
- powSolution,
- Array.fill(3)(0: Byte),
- None
- )
-
- /**
- * Header generator with default miner pk in pow solution
- */
- lazy val defaultHeaderGen: Gen[Header] = invalidHeaderGen.map { h =>
- h.copy(powSolution = h.powSolution.copy(pk = defaultMinerPkPoint))
- }
-
- lazy val randomADProofsGen: Gen[ADProofs] = for {
- headerId <- modifierIdGen
- proof <- serializedAdProofGen
- } yield ADProofs(headerId, proof)
-
- lazy val emptyMemPoolGen: Gen[ErgoMemPool] =
- Gen.resultOf({ _: Unit => ErgoMemPool.empty(settings) })(Arbitrary(Gen.const(())))
-
- lazy val modeFeatureGen: Gen[ModePeerFeature] = for {
- stateTypeCode <- Gen.choose(StateType.Utxo.stateTypeCode, StateType.Utxo.stateTypeCode)
- popowSuffix <- Gen.choose(1, 10)
- blocksToKeep <- Gen.choose(1, 100000)
- } yield ModePeerFeature(
- StateType.fromCode(stateTypeCode),
- Random.nextBoolean(),
- if (Random.nextBoolean()) Some(popowSuffix) else None,
- blocksToKeep)
-
- lazy val ergoValidationSettingsUpdateGen: Gen[ErgoValidationSettingsUpdate] = for {
- n <- Gen.choose(1, 200)
- disabledRules = ValidationRules.rulesSpec.filter(_._2.mayBeDisabled).keys.take(n).toSeq
- replacedRuleCode <- Gen.choose(org.ergoplatform.validation.ValidationRules.FirstRuleId, Short.MaxValue)
- changedRuleValue <- genBoundedBytes(0, 127)
- statuses <- Gen.listOf(Gen.oneOf(DisabledRule, EnabledRule, ReplacedRule(replacedRuleCode), ChangedRule(changedRuleValue)))
- statusUpdates = org.ergoplatform.validation.ValidationRules.ruleSpecs.take(statuses.size).map(_.id).zip(statuses)
- } yield ErgoValidationSettingsUpdate(disabledRules, statusUpdates)
-
- lazy val ergoValidationSettingsGen: Gen[ErgoValidationSettings] = ergoValidationSettingsUpdateGen
- .map(u => ErgoValidationSettings.initial.updated(u))
-
- /** Random long from 1 to maximum - 1
- *
- * @param maximum should be positive
- */
- def randomLong(maximum: Long = Long.MaxValue): Long = {
- if (maximum < 3) 1 else Math.abs(Random.nextLong()) % (maximum - 2) + 1
- }
-
- lazy val poPowProofGen: Gen[NipopowProof] = for {
- m <- Gen.chooseNum(1, 128)
- k <- Gen.chooseNum(1, 128)
- proof <- validNiPoPowProofGen(m, k)
- } yield proof
-
- def validNiPoPowProofGen(m: Int, k: Int): Gen[NipopowProof] = for {
- mulM <- Gen.chooseNum(1, 20)
- } yield {
- val chain = genHeaderChain(m * mulM + k, diffBitsOpt = None, useRealTs = false)
- val popowChain = popowHeaderChain(chain)
- val params = PoPowParams(m, k, continuous = false)
- nipopowAlgos.prove(popowChain)(params).get
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoTransactionGenerators.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoTransactionGenerators.scala
deleted file mode 100644
index 978617e43d..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoTransactionGenerators.scala
+++ /dev/null
@@ -1,358 +0,0 @@
-package org.ergoplatform.utils.generators
-
-import org.ergoplatform.ErgoBox.TokenId
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.BlockTransactions
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction}
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
-import org.ergoplatform.nodeView.state.{BoxHolder, ErgoStateContext, VotingData}
-import org.ergoplatform.nodeView.wallet.requests.{ExternalSecret, TransactionSigningRequest}
-import org.ergoplatform.nodeView.wallet.{AugWalletTransaction, WalletTransaction}
-import org.ergoplatform.sdk.wallet.secrets.{DhtSecretKey, DlogSecretKey}
-import org.ergoplatform.settings.Parameters._
-import org.ergoplatform.settings.{Constants, Parameters}
-import org.ergoplatform.utils.{BoxUtils, RandomLike, RandomWrapper}
-import org.ergoplatform.sdk.wallet.Constants.MaxAssetsPerBox
-import org.ergoplatform.wallet.interpreter.TransactionHintsBag
-import org.ergoplatform.wallet.utils.Generators
-import org.ergoplatform._
-import org.ergoplatform.wallet.Constants.ScanId
-import org.scalacheck.Gen
-import scorex.crypto.hash.Blake2b256
-import scorex.db.ByteArrayWrapper
-import scorex.util.encode.Base16
-import sigmastate.Values.ErgoTree
-import sigmastate.crypto.DLogProtocol.ProveDlog
-import sigmastate.eval.Extensions._
-import sigmastate.eval._
-import sigmastate.helpers.TestingHelpers._
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-import scala.util.Random
-
-trait ErgoTransactionGenerators extends ErgoGenerators with Generators {
-
- protected implicit val addressEncoder: ErgoAddressEncoder =
- ErgoAddressEncoder(settings.chainSettings.addressPrefix)
-
- val creationHeightGen: Gen[Int] = Gen.choose(0, Int.MaxValue / 2)
-
- lazy val ergoBoxCandidateGen: Gen[ErgoBoxCandidate] = for {
- h <- creationHeightGen
- prop <- trueLeafGen
- ar <- additionalRegistersGen
- tokens <- additionalTokensGen
- value <- validValueGen
- } yield new ErgoBoxCandidate(value, prop, h, tokens.toColl, ar)
-
- def ergoAddressGen: Gen[ErgoAddress] = proveDlogGen.map(P2PKAddress.apply)
-
- def ergoBoxCandidateGen(prop: ProveDlog): Gen[ErgoBoxCandidate] = for {
- h <- creationHeightGen
- ar <- additionalRegistersGen
- tokens <- additionalTokensGen
- value <- validValueGen
- } yield new ErgoBoxCandidate(value, prop, h, tokens.toColl, ar)
-
- lazy val ergoBoxGenNoProp: Gen[ErgoBox] = ergoBoxGen(propGen = trueLeafGen)
-
- def ergoBoxGenForTokens(tokens: Seq[(TokenId, Long)],
- propositionGen: Gen[ErgoTree]): Gen[ErgoBox] = {
- ergoBoxGen(propGen = propositionGen, tokensGen = Gen.oneOf(tokens, tokens), heightGen = ErgoHistory.EmptyHistoryHeight)
- }
-
- def unspendableErgoBoxGen(minValue: Long = parameters.minValuePerByte * 200,
- maxValue: Long = coinsTotal): Gen[ErgoBox] = {
- ergoBoxGen(propGen = falseLeafGen, valueGenOpt = Some(Gen.choose(minValue, maxValue)))
- }
-
- lazy val inputGen: Gen[Input] = for {
- boxId <- boxIdGen
- spendingProof <- noProofGen
- } yield Input(boxId, spendingProof)
-
- lazy val dataInputGen: Gen[DataInput] = for {
- boxId <- boxIdGen
- } yield DataInput(boxId)
-
- lazy val reallySmallInt: Gen[Int] = Gen.choose(0, 3)
-
- lazy val invalidErgoTransactionGen: Gen[ErgoTransaction] = for {
- from: IndexedSeq[Input] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, inputGen).map(_.toIndexedSeq))
- dataInputs: IndexedSeq[DataInput] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, dataInputGen).map(_.toIndexedSeq))
- to: IndexedSeq[ErgoBoxCandidate] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, ergoBoxCandidateGen).map(_.toIndexedSeq))
- } yield ErgoTransaction(from, dataInputs, to)
-
- def invalidErgoTransactionGen(prop: ProveDlog): Gen[ErgoTransaction] = for {
- from: IndexedSeq[Input] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, inputGen).map(_.toIndexedSeq))
- dataInputs: IndexedSeq[DataInput] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, dataInputGen).map(_.toIndexedSeq))
- to: IndexedSeq[ErgoBoxCandidate] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, ergoBoxCandidateGen(prop)).map(_.toIndexedSeq))
- } yield ErgoTransaction(from, dataInputs, to)
-
- lazy val walletTransactionGen: Gen[WalletTransaction] = for {
- tx <- invalidErgoTransactionGen
- inclusionHeight <- Gen.posNum[Int]
- scanId <- ScanId @@ Gen.posNum[Short]
- } yield WalletTransaction(tx, inclusionHeight, Seq(scanId))
-
- def walletTransactionForScanGen(scanId: ScanId): Gen[WalletTransaction] = for {
- tx <- invalidErgoTransactionGen
- inclusionHeight <- Gen.posNum[Int]
- } yield WalletTransaction(tx, inclusionHeight, Seq(scanId))
-
- def augWalletTransactionForScanGen(scanId: ScanId, includeUnconfirmed: Boolean): Gen[AugWalletTransaction] = for {
- tx <- walletTransactionForScanGen(scanId)
- numConfirmation <- if (includeUnconfirmed) Gen.const(0) else Gen.posNum[Int]
- } yield AugWalletTransaction(tx, numConfirmation)
-
- lazy val augWalletTransactionGen: Gen[AugWalletTransaction] = for {
- tx <- walletTransactionGen
- numConfirmation <- Gen.posNum[Int]
- } yield AugWalletTransaction(tx, numConfirmation)
-
- /**
- * Generates a transaction that is valid if correct boxes were provided.
- * Generated transaction may still be invalid, if:
- * - default prover does not know how to sign at least one input
- * - number of assets exceeds MaxAssetsPerBox
- */
- def validUnsignedTransactionFromBoxes(boxesToSpend: IndexedSeq[ErgoBox],
- rnd: RandomLike = new RandomWrapper,
- issueNew: Boolean = true,
- outputsProposition: ErgoTree = Constants.TrueLeaf,
- dataBoxes: IndexedSeq[ErgoBox] = IndexedSeq()): UnsignedErgoTransaction = {
- require(boxesToSpend.nonEmpty, "At least one box is needed to generate a transaction")
-
- val inputSum = boxesToSpend.map(_.value).reduce(Math.addExact(_, _))
- val assetsMap: mutable.Map[ByteArrayWrapper, Long] =
- mutable.Map(boxesToSpend.flatMap(_.additionalTokens.toArray).map { case (bs, amt) =>
- ByteArrayWrapper(bs.toArray) -> amt
- }: _*)
-
- //randomly creating a new asset
- if (rnd.nextBoolean() && issueNew) {
- assetsMap.put(ByteArrayWrapper(boxesToSpend.head.id), rnd.nextInt(Int.MaxValue))
- }
-
- val minValue = BoxUtils.sufficientAmount(extendedParameters)
-
- require(inputSum >= minValue)
- val inputsCount = boxesToSpend.size
- val maxOutputs = Math.min(Short.MaxValue, inputSum / minValue).toInt
- val outputsCount = Math.min(maxOutputs, Math.max(inputsCount + 1, rnd.nextInt(inputsCount * 2)))
- require(outputsCount > 0, s"outputs count is not positive: $outputsCount")
-
- require(minValue * outputsCount <= inputSum)
- val outputPreamounts = (1 to outputsCount).map(_ => minValue).toBuffer
-
- var remainder = inputSum - minValue * outputsCount
- do {
- val idx = Random.nextInt(outputsCount)
- if (remainder < inputSum / inputsCount) {
- outputPreamounts.update(idx, outputPreamounts(idx) + remainder)
- remainder = 0
- } else {
- val value = Math.abs(rnd.nextLong()) % (remainder / outputsCount)
- outputPreamounts.update(idx, outputPreamounts(idx) + value)
- remainder = remainder - value
- }
- } while (remainder > 0)
-
- val outputAmounts = outputPreamounts.toIndexedSeq
-
- val tokenAmounts: mutable.IndexedSeq[mutable.Map[ByteArrayWrapper, Long]] =
- mutable.IndexedSeq.fill(outputsCount)(mutable.Map[ByteArrayWrapper, Long]())
-
- var availableTokenSlots = outputsCount * MaxAssetsPerBox
-
- if (assetsMap.nonEmpty) {
- do {
- val in = assetsMap.head
- val outIdx = Stream.from(1, 1).map(_ => rnd.nextInt(tokenAmounts.size))
- .find(idx => tokenAmounts(idx).size < MaxAssetsPerBox).get
- val out = tokenAmounts(outIdx)
- val contains = out.contains(in._1)
-
- val amt = if (in._2 == 1 || (availableTokenSlots < assetsMap.size * 2 && !contains) || rnd.nextBoolean()) {
- in._2
- } else {
- Math.max(1, Math.min((rnd.nextDouble() * in._2).toLong, in._2))
- }
-
- if (amt == in._2) assetsMap.remove(in._1) else assetsMap.update(in._1, in._2 - amt)
- if (contains) {
- val outAmt = out(in._1)
- out.update(in._1, outAmt + amt)
- } else {
- availableTokenSlots = availableTokenSlots - 1
- out.update(in._1, amt)
- }
- tokenAmounts(outIdx) = out
- } while (assetsMap.nonEmpty && availableTokenSlots > 0)
- }
-
- val newBoxes = outputAmounts.zip(tokenAmounts.toIndexedSeq).map { case (amt, tokens) =>
- val normalizedTokens = tokens.toSeq.map(t => t._1.data.toTokenId -> t._2)
- testBox(amt, outputsProposition, 0, normalizedTokens)
- }
- val inputs = boxesToSpend.map(b => Input(b.id, emptyProverResult))
- val dataInputs = dataBoxes.map(b => DataInput(b.id))
- val unsignedTx = UnsignedErgoTransaction(inputs, dataInputs, newBoxes)
- require(unsignedTx.dataInputs.length == dataBoxes.length, s"${unsignedTx.dataInputs.length} == ${dataBoxes.length}")
- unsignedTx
- }
-
- def validTransactionFromBoxes(boxesToSpend: IndexedSeq[ErgoBox],
- rnd: RandomLike = new RandomWrapper,
- issueNew: Boolean = true,
- outputsProposition: ErgoTree = Constants.TrueLeaf,
- stateCtxOpt: Option[ErgoStateContext] = None,
- dataBoxes: IndexedSeq[ErgoBox] = IndexedSeq()): ErgoTransaction = {
- val unsignedTx = validUnsignedTransactionFromBoxes(boxesToSpend, rnd, issueNew, outputsProposition, dataBoxes)
- defaultProver.sign(unsignedTx, boxesToSpend, dataBoxes, stateCtxOpt.getOrElse(emptyStateContext))
- .map(ErgoTransaction.apply)
- .getOrElse {
- log.debug(s"Going to generate a transaction with incorrect spending proofs: $unsignedTx")
- ErgoTransaction(boxesToSpend.map(b => Input(b.id, emptyProverResult)), unsignedTx.dataInputs, unsignedTx.outputs)
- }
- }
-
- def disperseTokens(inputsCount: Int, tokensCount: Byte): Gen[IndexedSeq[Seq[(TokenId, Long)]]] = {
- val tokensDistribution = mutable.IndexedSeq.fill(inputsCount)(Seq[(TokenId, Long)]())
- (1 to tokensCount).foreach { i =>
- val (id, amt) = Blake2b256(s"$i" + Random.nextString(5)).toTokenId -> (Random.nextInt(Int.MaxValue).toLong + 100)
- val idx = i % tokensDistribution.size
- val s = tokensDistribution(idx)
- tokensDistribution(idx) = s :+ (id -> amt)
- }
- tokensDistribution.ensuring(_.forall(_.forall(_._2 > 0)))
- }
-
- def boxesGenTemplate(minAssets: Int,
- maxAssets: Int,
- minInputs: Int,
- maxInputs: Int,
- propositionGen: Gen[ErgoTree]): Gen[(IndexedSeq[ErgoBox], ErgoTree)] = for {
- inputsCount <- Gen.choose(minInputs, maxInputs)
- tokensCount <- Gen.choose(
- minAssets,
- Math.max(maxAssets, inputsCount))
- tokensDistribution <- disperseTokens(inputsCount, tokensCount.toByte)
- from <- Gen.sequence(tokensDistribution.map(tokens => ergoBoxGenForTokens(tokens, propositionGen)))
- prop <- propositionGen
- } yield from.asScala.toIndexedSeq -> prop
-
- def validErgoTransactionGenTemplate(minAssets: Int,
- maxAssets: Int = -1,
- maxInputs: Int = 100,
- propositionGen: Gen[ErgoTree] = trueLeafGen
- ): Gen[(IndexedSeq[ErgoBox], ErgoTransaction)] = {
- boxesGenTemplate(minAssets, maxAssets, maxInputs, maxInputs, propositionGen).map { case (boxes, prop) =>
- val tx = validTransactionFromBoxes(boxes, outputsProposition = prop)
- boxes -> tx
- }
- }
-
- def validUnsignedErgoTransactionGenTemplate(minAssets: Int,
- maxAssets: Int,
- maxInputs: Int,
- propositionGen: Gen[ErgoTree]): Gen[(IndexedSeq[ErgoBox], UnsignedErgoTransaction)] = {
- boxesGenTemplate(minAssets, maxAssets, maxInputs, maxInputs, propositionGen).map { case (boxes, prop) =>
- val utx = validUnsignedTransactionFromBoxes(boxes, outputsProposition = prop)
- boxes -> utx
- }
- }
-
- def validUnsignedErgoTransactionGen(prop: ErgoTree*): Gen[(IndexedSeq[ErgoBox], UnsignedErgoTransaction)] =
- validUnsignedErgoTransactionGenTemplate(minAssets = 0, maxAssets = 5, maxInputs = 10, propositionGen = Gen.oneOf(prop))
-
- lazy val validUnsignedErgoTransactionGen: Gen[(IndexedSeq[ErgoBox], UnsignedErgoTransaction)] =
- validUnsignedErgoTransactionGenTemplate(minAssets = 0, maxAssets = 5, maxInputs = 10, propositionGen = trueLeafGen)
-
- lazy val validErgoTransactionGen: Gen[(IndexedSeq[ErgoBox], ErgoTransaction)] = validErgoTransactionGenTemplate(minAssets = 0)
- lazy val validErgoTransactionWithAssetsGen: Gen[(IndexedSeq[ErgoBox], ErgoTransaction)] =
- validErgoTransactionGenTemplate(minAssets = 1)
-
- def boxesHolderGenOfSize(numBoxes:Int): Gen[BoxHolder] = Gen.listOfN(numBoxes, ergoBoxGenForTokens(Seq(), trueLeafGen))
- .map(l => BoxHolder(l))
-
- lazy val boxesHolderGen: Gen[BoxHolder] = Gen.listOfN(2000, ergoBoxGenForTokens(Seq(), trueLeafGen))
- .map(l => BoxHolder(l))
-
- lazy val invalidBlockTransactionsGen: Gen[BlockTransactions] = for {
- headerId <- modifierIdGen
- txs <- Gen.nonEmptyListOf(invalidErgoTransactionGen)
- } yield BlockTransactions(headerId, Header.InitialVersion, txs.foldLeft(Seq.empty[ErgoTransaction])((acc, tx) =>
- if ((acc :+ tx).map(_.size).sum < (Parameters.MaxBlockSizeDefault - 150)) acc :+ tx else acc))
-
- def invalidBlockTransactionsGen(prop: ProveDlog, txQty: Int): Gen[BlockTransactions] = for {
- headerId <- modifierIdGen
- txs <- Gen.listOfN(txQty, invalidErgoTransactionGen(prop))
- } yield BlockTransactions(headerId, Header.InitialVersion, txs.foldLeft(Seq.empty[ErgoTransaction])((acc, tx) =>
- if ((acc :+ tx).map(_.size).sum < (Parameters.MaxBlockSizeDefault - 150)) acc :+ tx else acc))
-
- lazy val invalidErgoFullBlockGen: Gen[ErgoFullBlock] = for {
- header <- defaultHeaderGen
- txs <- invalidBlockTransactionsGen
- extension <- extensionGen
- proof <- randomADProofsGen
- } yield ErgoFullBlock(header, txs, extension, Some(proof))
-
- def invalidErgoFullBlockGen(prop: ProveDlog, txQty: Int): Gen[ErgoFullBlock] = for {
- header <- defaultHeaderGen
- txs <- invalidBlockTransactionsGen(prop, txQty)
- extension <- extensionGen
- proof <- randomADProofsGen
- } yield ErgoFullBlock(header, txs, extension, Some(proof))
-
- lazy val paramVoteGen: Gen[Byte] = for {
- paramVote <- Gen.oneOf(Seq(NoParameter, StorageFeeFactorIncrease, MinValuePerByteIncrease))
- } yield paramVote
-
- lazy val paramVotesGen: Gen[Array[Byte]] = for {
- firstVote <- paramVoteGen
- } yield Array(firstVote, NoParameter, NoParameter)
-
- lazy val ergoStateContextGen: Gen[ErgoStateContext] = for {
- size <- Gen.choose(0, Constants.LastHeadersInContext + 3)
- stateRoot <- stateRootGen
- blocks <- Gen.listOfN(size, invalidErgoFullBlockGen)
- votes <- Gen.listOfN(size, paramVotesGen)
- } yield {
- blocks match {
- case _ :: _ =>
- val sc = new ErgoStateContext(Seq(), None, startDigest, parameters, validationSettingsNoIl, VotingData.empty)
- blocks.foldLeft(sc -> 1) { case ((c, h), b) =>
- val block = b.copy(header = b.header.copy(height = h, votes = votes(h - 1)))
- c.appendFullBlock(block).get -> (h + 1)
- }._1
- case _ =>
- ErgoStateContext.empty(stateRoot, settings, parameters)
- }
- }
-
- def transactionSigningRequestGen(includeInputs: Boolean): Gen[TransactionSigningRequest] = for {
- (secret, pubKey) <- dlogSecretWithPublicImageGen
- (secretDh, _) <- dhtSecretWithPublicImageGen
- (inputBoxes, utx) <- validUnsignedErgoTransactionGen(pubKey)
- inputBoxesEncoded = inputBoxes.map(b => Base16.encode(b.bytes))
- secretSeq = Seq(ExternalSecret(DlogSecretKey(secret)), ExternalSecret(DhtSecretKey(secretDh)))
- } yield TransactionSigningRequest(utx, TransactionHintsBag.empty, secretSeq,
- if (includeInputs) Some(inputBoxesEncoded) else None, None)
-
- def transactionSigningRequestGen(utxoSet: WrappedUtxoState): Gen[TransactionSigningRequest] = Gen.const {
- val inputBoxes = utxoSet.takeBoxes(3).toIndexedSeq
-
- val utx = UnsignedErgoTransaction(inputBoxes.map(b => new UnsignedInput(b.id)), inputBoxes)
- val coin = Random.nextBoolean()
- val inputBoxesEncoded = inputBoxes.map(b => Base16.encode(b.bytes))
-
- TransactionSigningRequest(utx, TransactionHintsBag.empty, Seq.empty, if (coin) Some(inputBoxesEncoded) else None, None)
- }
-
-}
-
-object ErgoTransactionGenerators extends ErgoTransactionGenerators
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ValidBlocksGenerators.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ValidBlocksGenerators.scala
deleted file mode 100644
index b579b50cd7..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ValidBlocksGenerators.scala
+++ /dev/null
@@ -1,247 +0,0 @@
-package org.ergoplatform.utils.generators
-
-import org.ergoplatform.ErgoBox
-import org.ergoplatform.mining.CandidateGenerator
-import org.ergoplatform.modifiers.ErgoFullBlock
-import org.ergoplatform.modifiers.history.extension.{Extension, ExtensionCandidate}
-import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.modifiers.history.popow.NipopowAlgos
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.nodeView.state._
-import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
-import org.ergoplatform.settings.{Algos, Constants, ErgoSettings, Parameters}
-import org.ergoplatform.utils.{LoggingUtil, RandomLike, RandomWrapper}
-import org.ergoplatform.wallet.utils.TestFileUtils
-import org.scalatest.matchers.should.Matchers
-import scorex.core.VersionTag
-import scorex.crypto.authds.avltree.batch.Remove
-import scorex.crypto.authds.ADDigest
-import scorex.db.ByteArrayWrapper
-import scorex.testkit.TestkitHelpers
-
-import scala.annotation.tailrec
-import scala.collection.mutable
-import scala.util.{Failure, Random, Success}
-
-trait ValidBlocksGenerators
- extends TestkitHelpers with TestFileUtils with Matchers with ChainGenerator with ErgoTransactionGenerators {
-
- def createUtxoState(settings: ErgoSettings): (UtxoState, BoxHolder) = {
- ErgoState.generateGenesisUtxoState(createTempDir, settings)
- }
-
- def createUtxoState(bh: BoxHolder, parameters: Parameters): UtxoState =
- UtxoState.fromBoxHolder(bh, None, createTempDir, settings, parameters)
-
- def createDigestState(version: VersionTag, digest: ADDigest): DigestState =
- DigestState.create(Some(version), Some(digest), createTempDir, settings)
-
- def validTransactionsFromBoxHolder(boxHolder: BoxHolder): (Seq[ErgoTransaction], BoxHolder) =
- validTransactionsFromBoxHolder(boxHolder, new RandomWrapper)
-
- protected def validTransactionsFromBoxes(sizeLimit: Int,
- stateBoxesIn: Seq[ErgoBox],
- rnd: RandomLike): (Seq[ErgoTransaction], Seq[ErgoBox]) = {
- validTransactionsFromBoxes(sizeLimit, stateBoxesIn, Seq(), rnd)
- }
-
- /** @param sizeLimit maximum transactions size in bytes */
- protected def validTransactionsFromBoxes(sizeLimit: Int,
- stateBoxesIn: Seq[ErgoBox],
- dataBoxesIn: Seq[ErgoBox],
- rnd: RandomLike): (Seq[ErgoTransaction], Seq[ErgoBox]) = {
- var createdEmissionBox: Seq[ErgoBox] = Seq()
-
- @tailrec
- def loop(remainingCost: Long,
- stateBoxes: Seq[ErgoBox],
- selfBoxes: Seq[ErgoBox],
- acc: Seq[ErgoTransaction],
- rnd: RandomLike): (Seq[ErgoTransaction], Seq[ErgoBox]) = {
-
- lazy val dataBoxesToUse: IndexedSeq[ErgoBox] = {
- Random.shuffle(dataBoxesIn ++ stateBoxesIn ++ selfBoxes).take(rnd.nextInt(10)).toIndexedSeq
- }
-
- val currentSize = acc.map(_.size).sum
- val averageSize = if (currentSize > 0) currentSize / acc.length else 1000
- val customTokens = (stateBoxes ++ selfBoxes).flatMap(_.additionalTokens.toArray)
- val customTokensNum = customTokens.map(ct => ByteArrayWrapper(ct._1.toArray)).toSet.size
- val issueNew = customTokensNum == 0
-
- stateBoxes.find(isEmissionBox) match {
- case Some(emissionBox) if currentSize < sizeLimit - averageSize =>
- // Extract money to anyoneCanSpend output and put emission to separate var to avoid it's double usage inside one block
- val currentHeight: Int = emissionBox.creationHeight.toInt
- val rewards = CandidateGenerator.collectRewards(Some(emissionBox), currentHeight, Seq.empty, defaultMinerPk, emptyStateContext)
- val outs = rewards.flatMap(_.outputs)
- val remainedBoxes = stateBoxes.filter(b => !isEmissionBox(b))
- createdEmissionBox = outs.filter(b => isEmissionBox(b))
- val newSelfBoxes = selfBoxes ++ outs.filter(b => !isEmissionBox(b))
- val cost: Long = getTxCost(rewards.head, Seq(emissionBox), Seq())
- loop(remainingCost - cost, remainedBoxes, newSelfBoxes, rewards ++ acc, rnd)
-
- case _ =>
- if (currentSize < sizeLimit - 2 * averageSize && remainingCost > 100000) {
- val (consumedSelfBoxes, remainedSelfBoxes) = selfBoxes.splitAt(rnd.nextInt(2) + 1)
- val (consumedBoxesFromState, remainedBoxes) = stateBoxes.splitAt(rnd.nextInt(2) + 1)
- // disable tokens generation to avoid situation with too many tokens
- val boxesToSpend = (consumedSelfBoxes ++ consumedBoxesFromState).toIndexedSeq
- val tx = validTransactionFromBoxes(boxesToSpend, rnd, issueNew, dataBoxes = dataBoxesToUse)
- tx.statelessValidity() match {
- case Failure(e) =>
- log.warn(s"Failed to generate valid transaction: ${LoggingUtil.getReasonMsg(e)}")
- loop(remainingCost, stateBoxes, selfBoxes, acc, rnd)
- case _ =>
- val cost: Long = getTxCost(tx, boxesToSpend, dataBoxesToUse)
- loop(remainingCost - cost, remainedBoxes, remainedSelfBoxes ++ tx.outputs, tx +: acc, rnd)
- }
- } else {
- // take 2 remaining box from state and return transactions set
- val (consumedSelfBoxes, remainedSelfBoxes) = selfBoxes.splitAt(1)
- val boxesToSpend = if(stateBoxes.nonEmpty) stateBoxes.take(2) else consumedSelfBoxes
-
- val tx = validTransactionFromBoxes(boxesToSpend.toIndexedSeq, rnd, issueNew, dataBoxes = dataBoxesToUse)
- val cost: Long = getTxCost(tx, boxesToSpend, dataBoxesToUse)
- tx.statelessValidity() match {
- case Success(_) if cost <= remainingCost =>
- ((tx +: acc).reverse, remainedSelfBoxes ++ tx.outputs ++ createdEmissionBox)
- case Failure(e) =>
- log.warn(s"Failed to generate valid transaction: ${LoggingUtil.getReasonMsg(e)}")
- loop(remainingCost, stateBoxes, selfBoxes, acc, rnd)
- }
- }
- }
- }
-
- loop(emptyStateContext.currentParameters.maxBlockCost, stateBoxesIn, mutable.WrappedArray.empty, mutable.WrappedArray.empty, rnd)
- }
-
- protected def getTxCost(tx: ErgoTransaction, boxesToSpend: Seq[ErgoBox], dataBoxesToUse: Seq[ErgoBox]): Int = {
- tx.statefulValidity(
- tx.inputs.flatMap(i => boxesToSpend.find(_.id == i.boxId)),
- tx.dataInputs.flatMap(i => dataBoxesToUse.find(_.id == i.boxId)),
- emptyStateContext,
- -2000000)(emptyVerifier).getOrElse(0)
- }
-
- /**
- * Simplified check that box is an emission box
- */
- private def isEmissionBox(box: ErgoBox): Boolean = box.proposition == genesisEmissionBox.proposition
-
- /** @param txSizeLimit maximum transactions size in bytes */
- def validTransactionsFromBoxHolder(boxHolder: BoxHolder,
- rnd: RandomLike,
- txSizeLimit: Int = 10 * 1024): (Seq[ErgoTransaction], BoxHolder) = {
- val (emissionBox, boxHolderWithoutEmission) = boxHolder.take(b => isEmissionBox(b))
- val (_, bhWithoutGenesis) = boxHolderWithoutEmission.take(b => genesisBoxes.contains(b))
- val (regularBoxes, drainedBh) = bhWithoutGenesis.take(rnd.nextInt(txSizeLimit / 100) + 1)
- val boxes = emissionBox ++ regularBoxes
- val dataBoxes: Seq[ErgoBox] = Random.shuffle(boxHolder.boxes.values).take(rnd.nextInt(txSizeLimit / 100)).toSeq
-
- assert(boxes.nonEmpty, s"Was unable to take at least 1 box from box holder $boxHolder")
- val (txs, createdBoxes) = validTransactionsFromBoxes(txSizeLimit, boxes, dataBoxes, rnd)
- txs.foreach(_.statelessValidity().get)
- val bs = new BoxHolder(drainedBh.boxes ++ createdBoxes.map(b => ByteArrayWrapper(b.id) -> b))
- txs -> bs
- }
-
-
- def validTransactionsFromUtxoState(wus: WrappedUtxoState, rnd: RandomLike = new RandomWrapper): Seq[ErgoTransaction] = {
- val num = 1 + rnd.nextInt(3)
-
- val allBoxes = wus.takeBoxes(num + rnd.nextInt(100))
- val anyoneCanSpendBoxes = allBoxes.filter(_.ergoTree == Constants.TrueLeaf)
- val boxes = if (anyoneCanSpendBoxes.nonEmpty) anyoneCanSpendBoxes else allBoxes
-
- validTransactionsFromBoxes(num, boxes, rnd)._1
- }
-
- def validFullBlock(parentOpt: Option[ErgoFullBlock], utxoState: UtxoState, boxHolder: BoxHolder): ErgoFullBlock =
- validFullBlock(parentOpt, utxoState, boxHolder, new RandomWrapper)
-
-
- def validFullBlock(parentOpt: Option[ErgoFullBlock], utxoState: UtxoState, boxHolder: BoxHolder, rnd: RandomLike): ErgoFullBlock = {
- validFullBlock(parentOpt, utxoState, validTransactionsFromBoxHolder(boxHolder, rnd)._1)
- }
-
- def validFullBlockWithBoxHolder(parentOpt: Option[ErgoFullBlock],
- utxoState: UtxoState,
- boxHolder: BoxHolder,
- rnd: RandomLike): (ErgoFullBlock, BoxHolder) = {
- val txsBh = validTransactionsFromBoxHolder(boxHolder, rnd)
- validFullBlock(parentOpt, utxoState, txsBh._1) -> txsBh._2
- }
-
- def validFullBlock(parentOpt: Option[ErgoFullBlock],
- wrappedState: WrappedUtxoState): ErgoFullBlock = {
- validFullBlock(parentOpt, wrappedState, wrappedState.versionedBoxHolder)
- }
-
- def validFullBlock(parentOpt: Option[ErgoFullBlock],
- wrappedState: WrappedUtxoState,
- time: Long): ErgoFullBlock = {
- validFullBlock(
- parentOpt,
- wrappedState,
- validTransactionsFromBoxHolder(wrappedState.versionedBoxHolder, new RandomWrapper)._1,
- Some(time)
- )
- }
-
- def validFullBlock(parentOpt: Option[ErgoFullBlock],
- utxoState: UtxoState,
- transactions: Seq[ErgoTransaction],
- timeOpt: Option[Long] = None): ErgoFullBlock = {
- checkPayload(transactions, utxoState)
-
- val (adProofBytes, updStateDigest) = utxoState.proofsForTransactions(transactions).get
-
- val time = timeOpt.orElse(parentOpt.map(_.header.timestamp + 1)).getOrElse(System.currentTimeMillis())
- val interlinks = parentOpt.toSeq.flatMap { block =>
- nipopowAlgos.updateInterlinks(block.header, NipopowAlgos.unpackInterlinks(block.extension.fields).get)
- }
- val extension: ExtensionCandidate =
- parameters.toExtensionCandidate ++
- nipopowAlgos.interlinksToExtension(interlinks) ++
- utxoState.stateContext.validationSettings.toExtensionCandidate
- val votes = Array.fill(3)(0: Byte)
-
- powScheme.proveBlock(parentOpt.map(_.header), Header.InitialVersion, settings.chainSettings.initialNBits, updStateDigest, adProofBytes,
- transactions, time, extension, votes, defaultMinerSecretNumber).get
- }
-
- /**
- * Full block valid against state only - allows to create blocks form headers and state,
- * does not contain valid interlinks.
- */
- def statefulyValidFullBlock(wrappedState: WrappedUtxoState,
- timeOpt: Option[Long] = None): ErgoFullBlock = {
- val parentOpt: Option[Header] = wrappedState.stateContext.lastHeaderOpt
- val parentExtensionOpt: Option[Extension] = wrappedState.stateContext.lastExtensionOpt
- val bh = wrappedState.versionedBoxHolder
- val transactions = validTransactionsFromBoxHolder(bh, new RandomWrapper)._1
-
- checkPayload(transactions, wrappedState)
-
- val (adProofBytes, updStateDigest) = wrappedState.proofsForTransactions(transactions).get
-
- val time = timeOpt.orElse(parentOpt.map(_.timestamp + 1)).getOrElse(System.currentTimeMillis())
- val interlinksExtension = nipopowAlgos.interlinksToExtension(nipopowAlgos.updateInterlinks(parentOpt, parentExtensionOpt))
- val extension: ExtensionCandidate = parameters.toExtensionCandidate ++ interlinksExtension
- val votes = Array.fill(3)(0: Byte)
-
- powScheme.proveBlock(parentOpt, Header.InitialVersion, settings.chainSettings.initialNBits, updStateDigest,
- adProofBytes, transactions, time, extension, votes, defaultMinerSecretNumber).get
- }
-
- private def checkPayload(transactions: Seq[ErgoTransaction], us: UtxoState): Unit = {
- transactions.foreach(_.statelessValidity() shouldBe 'success)
- transactions.nonEmpty shouldBe true
- ErgoState.boxChanges(transactions).get._1.foreach { case Remove(boxId) =>
- assert(us.boxById(boxId).isDefined, s"Box ${Algos.encode(boxId)} missed")
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/WalletGenerators.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/generators/WalletGenerators.scala
deleted file mode 100644
index 5ec1522c19..0000000000
--- a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/WalletGenerators.scala
+++ /dev/null
@@ -1,159 +0,0 @@
-package org.ergoplatform.utils.generators
-
-import org.ergoplatform._
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.nodeView.wallet.IdUtils._
-import org.ergoplatform.nodeView.wallet.persistence.WalletDigest
-import org.ergoplatform.nodeView.wallet.requests.{AssetIssueRequest, BurnTokensRequest, PaymentRequest}
-import org.ergoplatform.nodeView.wallet.scanning._
-import org.ergoplatform.settings.Constants
-import org.ergoplatform.wallet.Constants.ScanId
-import org.ergoplatform.wallet.boxes.TrackedBox
-import org.ergoplatform.wallet.utils.Generators
-import org.scalacheck.Gen
-import sigmastate.Values.ByteArrayConstant
-
-trait WalletGenerators extends ErgoTransactionGenerators with Generators {
-
- override def trackedBoxGen: Gen[TrackedBox] = {
- Gen.oneOf(
- unspentOffchainBoxGen,
- unspentOnchainBoxGen,
- spentOffchainBoxGen,
- spentPartiallyOffchainBoxGen,
- spentOnchainBoxGen
- )
- }
-
- def unspentOffchainBoxGen: Gen[TrackedBox] = {
- for {
- (boxes, tx) <- validErgoTransactionGen
- outIndex <- outIndexGen(tx)
- ergoBox <- Gen.oneOf(boxes)
- appStatuses <- appStatusesGen
- } yield TrackedBox(tx, outIndex, None, ergoBox, appStatuses)
- }
-
- def unspentOnchainBoxGen: Gen[TrackedBox] = {
- for {
- (boxes, tx) <- validErgoTransactionGen
- outIndex <- outIndexGen(tx)
- height <- heightGen()
- ergoBox <- Gen.oneOf(boxes)
- appStatuses <- appStatusesGen
- } yield TrackedBox(tx, outIndex, Some(height), ergoBox, appStatuses)
- }
-
- def spentOffchainBoxGen: Gen[TrackedBox] = {
- for {
- (boxes, tx) <- validErgoTransactionGen
- (_, spendingTx) <- validErgoTransactionGen
- outIndex <- outIndexGen(tx)
- ergoBox <- Gen.oneOf(boxes)
- appStatuses <- appStatusesGen
- } yield TrackedBox(tx.id, outIndex, None, Some(spendingTx.id), None, ergoBox, appStatuses)
- }
-
- def spentPartiallyOffchainBoxGen: Gen[TrackedBox] = {
- for {
- (boxes, tx) <- validErgoTransactionGen
- (_, spendingTx) <- validErgoTransactionGen
- outIndex <- outIndexGen(tx)
- height <- heightGen()
- ergoBox <- Gen.oneOf(boxes)
- appStatuses <- appStatusesGen
- } yield TrackedBox(tx.id, outIndex, Some(height), Some(spendingTx.id), None, ergoBox, appStatuses)
- }
-
- def spentOnchainBoxGen: Gen[TrackedBox] = {
- for {
- (boxes, tx) <- validErgoTransactionGen
- (_, spendingTx) <- validErgoTransactionGen
- outIndex <- outIndexGen(tx)
- height <- heightGen()
- spendingHeight <- heightGen(height)
- ergoBox <- Gen.oneOf(boxes)
- appStatuses <- appStatusesGen
- } yield TrackedBox(
- tx.id, outIndex, Some(height), Some(spendingTx.id), Some(spendingHeight), ergoBox, appStatuses)
- }
-
- def paymentRequestGen: Gen[PaymentRequest] = {
- for {
- value <- Gen.choose(1L, 100000L)
- assets <- additionalTokensGen
- registers <- additionalRegistersGen
- } yield PaymentRequest(Pay2SAddress(Constants.FalseLeaf), value, assets, registers)
- }
-
- def burnTokensRequestGen: Gen[BurnTokensRequest] = {
- for {
- assets <- additionalTokensGen
- } yield BurnTokensRequest(assets)
- }
-
- def assetIssueRequestGen: Gen[AssetIssueRequest] = {
- for {
- amount <- Gen.choose(1L, 100000L)
- name <- Gen.alphaUpperStr
- description <- Gen.alphaLowerStr
- decimals <- Gen.choose(4, 16)
- } yield AssetIssueRequest(Pay2SAddress(Constants.FalseLeaf), None, amount, name, description, decimals)
- }
-
- def registrySummaryGen: Gen[WalletDigest] = {
- for {
- height <- Gen.posNum[Int]
- amount <- Gen.choose(1L, 100000L)
- balances <- additionalTokensGen
- } yield {
- val encodedBalances = balances.map { case (x1, x2) => encodedTokenId(x1) -> x2 }
- WalletDigest(height, amount, encodedBalances)
- }
- }
-
- def registerIdGen: Gen[ErgoBox.RegisterId] = Gen.oneOf(ErgoBox.allRegisters)
-
- def containsScanningPredicateGen: Gen[ContainsScanningPredicate] = for {
- regId <- registerIdGen
- bs <- nonEmptyBytesGen
- } yield ContainsScanningPredicate(regId, ByteArrayConstant(bs))
-
- def equalsScanningPredicateGen: Gen[EqualsScanningPredicate] = for {
- regId <- registerIdGen
- bs <- nonEmptyBytesGen
- } yield EqualsScanningPredicate(regId, ByteArrayConstant(bs))
-
- def containsAssetPredicateGen: Gen[ContainsAssetPredicate] = for {
- asset <- assetGen
- } yield ContainsAssetPredicate(asset._1)
-
- def orScanningPredicateGen: Gen[OrScanningPredicate] = for {
- args <- Gen.nonEmptyListOf(Gen.oneOf(containsScanningPredicateGen, equalsScanningPredicateGen,
- containsAssetPredicateGen))
- } yield OrScanningPredicate(args: _*)
-
- def andScanningPredicateGen: Gen[AndScanningPredicate] = for {
- args <- Gen.nonEmptyListOf(Gen.oneOf(containsScanningPredicateGen, equalsScanningPredicateGen,
- containsAssetPredicateGen, orScanningPredicateGen))
- } yield AndScanningPredicate(args: _*)
-
- def scanningPredicateGen: Gen[ScanningPredicate] = for {
- predicate <- Gen.oneOf(andScanningPredicateGen, orScanningPredicateGen)
- } yield predicate
-
- def externalScanReqGen: Gen[ScanRequest] = for {
- appName <- Gen.alphaNumStr
- pred <- scanningPredicateGen
- } yield ScanRequest(appName, pred, Some(ScanWalletInteraction.Off), Some(true))
-
- def externalAppGen: Gen[Scan] = for {
- scanId <- Gen.posNum[Short]
- req <- externalScanReqGen
- } yield req.toScan(ScanId @@ scanId).get
-
- private def outIndexGen(tx: ErgoTransaction) = Gen.choose(0: Short, tx.outputCandidates.length.toShort)
-
- private def heightGen(min: Int = 0) = Gen.choose(min + 1, Integer.MAX_VALUE / 2 + min)
-
-}
diff --git a/ergo-core/src/test/scala/scorex/core/network/DeliveryTrackerSpec.scala b/ergo-core/src/test/scala/scorex/core/network/DeliveryTrackerSpec.scala
deleted file mode 100644
index 4c7e5ad532..0000000000
--- a/ergo-core/src/test/scala/scorex/core/network/DeliveryTrackerSpec.scala
+++ /dev/null
@@ -1,71 +0,0 @@
-package scorex.core.network
-
-import akka.actor.{ActorRef, Cancellable}
-import io.circe._
-import io.circe.syntax._
-import org.ergoplatform.modifiers.NetworkObjectTypeId
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.core.network.ModifiersStatus.Received
-import scorex.testkit.generators.ObjectGenerators
-import scorex.util.ModifierId
-
-class DeliveryTrackerSpec extends ErgoPropertyTest with ObjectGenerators {
-
- property("tracker should accept requested modifiers, turn them into received and clear them") {
- forAll(connectedPeerGen(ActorRef.noSender)) { peer =>
- val tracker = DeliveryTracker.empty(settings)
- val mid: ModifierId = ModifierId @@ "foo"
- val mTypeId: NetworkObjectTypeId.Value = NetworkObjectTypeId.fromByte(104)
- tracker.setRequested(mTypeId, mid, peer) { _ => Cancellable.alreadyCancelled}
- val infoFields =
- Seq(
- "address" -> peer.connectionId.remoteAddress.toString.asJson,
- "checks" -> 0.asJson
- ) ++ peer.peerInfo.map(_.peerSpec.protocolVersion.toString.asJson).map("version" -> _)
- tracker.fullInfo.asJson shouldBe Json.obj(
- "invalidModifierApproxSize" -> 0.asJson,
- "requested" -> Json.obj(
- "104" -> Json.obj(
- "foo" -> Json.obj(infoFields:_*)
- )
- ),
- "received" -> Json.obj()
- )
-
- tracker.setReceived(mid, mTypeId, peer)
- val infoFields2 =
- Seq(
- "address" -> peer.connectionId.remoteAddress.toString.asJson
- ) ++ peer.peerInfo.map(_.peerSpec.protocolVersion.toString.asJson).map("version" -> _)
-
- tracker.fullInfo.asJson shouldBe Json.obj(
- "invalidModifierApproxSize" -> 0.asJson,
- "requested" -> Json.obj(
- "104" -> Json.obj(),
- ),
- "received" -> Json.obj(
- "104" -> Json.obj(
- "foo" -> Json.obj(infoFields2:_*)
- ),
- )
- )
- tracker.clearStatusForModifier(mid, mTypeId, Received)
- tracker.fullInfo.asJson shouldBe Json.obj(
- "invalidModifierApproxSize" -> 0.asJson,
- "requested" -> Json.obj(
- "104" -> Json.obj(),
- ),
- "received" -> Json.obj(
- "104" -> Json.obj()
- )
- )
-
- tracker.reset()
- val fullInfoAfterReset = tracker.fullInfo
- fullInfoAfterReset.invalidModifierApproxSize shouldBe 0
- fullInfoAfterReset.requested.size shouldBe 0
- fullInfoAfterReset.received.size shouldBe 0
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/scorex/core/network/PeerSpecSerializerSpec.scala b/ergo-core/src/test/scala/scorex/core/network/PeerSpecSerializerSpec.scala
deleted file mode 100644
index 13b8c3d0be..0000000000
--- a/ergo-core/src/test/scala/scorex/core/network/PeerSpecSerializerSpec.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-package scorex.core.network
-
-import org.ergoplatform.utils.ErgoPropertyTest
-import scorex.testkit.generators.ObjectGenerators
-import scorex.util.ByteArrayBuilder
-import scorex.util.serialization.{VLQByteBufferReader, VLQByteBufferWriter}
-
-import java.nio.ByteBuffer
-
-class PeerSpecSerializerSpec extends ErgoPropertyTest with ObjectGenerators {
-
- property("All variants of peer spec should be serialized and deserialized successfully") {
- forAll(peerSpecGen) { peerSpec =>
- val writer = new VLQByteBufferWriter(new ByteArrayBuilder())
- PeerSpecSerializer.serialize(peerSpec, writer)
- val reader = new VLQByteBufferReader(ByteBuffer.wrap(writer.result().toBytes))
- val actualPeerSpec = PeerSpecSerializer.parse(reader)
- peerSpec shouldBe actualPeerSpec
- }
- }
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/SerializationTests.scala b/ergo-core/src/test/scala/scorex/testkit/SerializationTests.scala
deleted file mode 100644
index b4ed96389e..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/SerializationTests.scala
+++ /dev/null
@@ -1,16 +0,0 @@
-package scorex.testkit
-
-import org.scalacheck.Gen
-import org.scalatest.Assertion
-import org.scalatest.matchers.should.Matchers
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-import scorex.core.serialization.ErgoSerializer
-
-trait SerializationTests extends ScalaCheckPropertyChecks with Matchers {
- def checkSerializationRoundtrip[A](generator: Gen[A], serializer: ErgoSerializer[A]): Assertion = {
- forAll(generator) { b: A =>
- val recovered = serializer.parseBytes(serializer.toBytes(b))
- serializer.toBytes(b) shouldEqual serializer.toBytes(recovered)
- }
- }
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/TestkitHelpers.scala b/ergo-core/src/test/scala/scorex/testkit/TestkitHelpers.scala
deleted file mode 100644
index a6d1654a63..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/TestkitHelpers.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-package scorex.testkit
-
-trait TestkitHelpers {
-
- val MinTestsOk = 100
-
- def check(minTestsOk:Int)(f: Int => Unit): Unit = (0 until minTestsOk) foreach (i => f(i))
-
- def check(f: Int => Unit): Unit = check(MinTestsOk)(f)
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/generators/AllModifierProducers.scala b/ergo-core/src/test/scala/scorex/testkit/generators/AllModifierProducers.scala
deleted file mode 100644
index 857fd49393..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/generators/AllModifierProducers.scala
+++ /dev/null
@@ -1,11 +0,0 @@
-package scorex.testkit.generators
-
-import org.ergoplatform.nodeView.state.ErgoState
-
-
-trait AllModifierProducers[ST <: ErgoState[ST]]
- extends SemanticallyValidModifierProducer[ST]
- with SyntacticallyTargetedModifierProducer
- with ArbitraryTransactionsCarryingModifierProducer
- with TotallyValidModifierProducer[ST]
- with SemanticallyValidTransactionsCarryingModifier[ST]
diff --git a/ergo-core/src/test/scala/scorex/testkit/generators/ArbitraryTransactionsCarryingModifierProducer.scala b/ergo-core/src/test/scala/scorex/testkit/generators/ArbitraryTransactionsCarryingModifierProducer.scala
deleted file mode 100644
index 4bbed68c85..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/generators/ArbitraryTransactionsCarryingModifierProducer.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-package scorex.testkit.generators
-
-import org.ergoplatform.modifiers.history.BlockTransactions
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-/**
- * Produces a modifier with transactions, not necessary syntatically or semantically valid
- */
-trait ArbitraryTransactionsCarryingModifierProducer{
-
-def modifierWithTransactions(memoryPoolOpt: Option[ErgoMemPool], customTransactionsOpt: Option[Seq[ErgoTransaction]]): BlockTransactions
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/generators/CoreGenerators.scala b/ergo-core/src/test/scala/scorex/testkit/generators/CoreGenerators.scala
deleted file mode 100644
index 54c6c3d752..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/generators/CoreGenerators.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package scorex.testkit.generators
-
-import org.scalacheck.Gen
-import scorex.core.{VersionTag, idToVersion}
-
-//Generators of objects from scorex-core
-trait CoreGenerators extends ObjectGenerators {
- lazy val versionTagGen: Gen[VersionTag] = modifierIdGen.map(id => idToVersion(id))
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/generators/CustomModifierProducer.scala b/ergo-core/src/test/scala/scorex/testkit/generators/CustomModifierProducer.scala
deleted file mode 100644
index 42d4278fe2..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/generators/CustomModifierProducer.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-package scorex.testkit.generators
-
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.state.ErgoState
-
-sealed trait ModifierProducerTemplateItem
-
-case object SynInvalid extends ModifierProducerTemplateItem
-case object Valid extends ModifierProducerTemplateItem
-
-trait CustomModifierProducer[ST <: ErgoState[ST]] {
-
- def customModifiers(history: ErgoHistory,
- state: ST,
- template: Seq[ModifierProducerTemplateItem]): Seq[BlockSection]
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/generators/ObjectGenerators.scala b/ergo-core/src/test/scala/scorex/testkit/generators/ObjectGenerators.scala
deleted file mode 100644
index f99112fab7..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/generators/ObjectGenerators.scala
+++ /dev/null
@@ -1,115 +0,0 @@
-package scorex.testkit.generators
-
-import java.net.{InetAddress, InetSocketAddress, URL}
-import akka.actor.ActorRef
-import akka.util.ByteString
-import org.ergoplatform.modifiers.NetworkObjectTypeId
-import org.ergoplatform.network.ModePeerFeature
-import org.ergoplatform.nodeView.state.StateType
-import org.scalacheck.Gen.{const, some}
-import org.scalacheck.{Arbitrary, Gen}
-import scorex.core.app.Version
-import scorex.core.network.message.{InvData, ModifiersData}
-import scorex.core.network._
-import scorex.core.network.peer.{PeerInfo, RestApiUrlPeerFeature}
-import scorex.core.NodeViewModifier
-import scorex.util.{ModifierId, bytesToId}
-
-trait ObjectGenerators {
-
- val MaxVersion = 999
- val MaxIp = 255
- val MaxPort = 65535
-
- val modePeerFeatureGen = for {
- utxo <- Gen.oneOf(true, false)
- stateType <- if(utxo) StateType.Utxo else StateType.Digest
- verifyingTransactions <- Gen.oneOf(true, false)
- popowSuffix <- Gen.option(smallInt)
- blocksToKeep <- smallInt
- } yield ModePeerFeature(stateType, verifyingTransactions, popowSuffix, blocksToKeep)
-
- lazy val smallInt: Gen[Int] = Gen.choose(0, 20)
-
- lazy val nonEmptyBytesGen: Gen[Array[Byte]] = Gen.nonEmptyListOf(Arbitrary.arbitrary[Byte])
- .map(_.toArray).suchThat(_.length > 0)
-
- lazy val nonEmptyByteStringGen: Gen[ByteString] = nonEmptyBytesGen.map(ByteString(_))
-
- def genBoundedBytes(minSize: Int, maxSize: Int): Gen[Array[Byte]] = {
- Gen.choose(minSize, maxSize) flatMap { sz => Gen.listOfN(sz, Arbitrary.arbitrary[Byte]).map(_.toArray) }
- }
-
- def genBytes(size: Int): Gen[Array[Byte]] = genBoundedBytes(size, size)
-
- lazy val positiveLongGen: Gen[Long] = Gen.choose(1, Long.MaxValue)
-
- lazy val positiveByteGen: Gen[Byte] = Gen.choose(1, Byte.MaxValue)
-
-
- lazy val modifierIdGen: Gen[ModifierId] = Gen.listOfN(NodeViewModifier.ModifierIdSize, Arbitrary.arbitrary[Byte])
- .map(id => bytesToId(id.toArray))
-
- lazy val modifierTypeIdGen: Gen[NetworkObjectTypeId.Value] = Arbitrary.arbitrary[Byte].map(t => NetworkObjectTypeId.fromByte(t))
-
- lazy val invDataGen: Gen[InvData] = for {
- modifierTypeId: NetworkObjectTypeId.Value <- modifierTypeIdGen
- modifierIds: Seq[ModifierId] <- Gen.nonEmptyListOf(modifierIdGen) if modifierIds.nonEmpty
- } yield InvData(modifierTypeId, modifierIds)
-
- lazy val modifierWithIdGen: Gen[(ModifierId, Array[Byte])] = for {
- id <- modifierIdGen
- mod <- nonEmptyBytesGen
- } yield id -> mod
-
- lazy val modifiersGen: Gen[ModifiersData] = for {
- modifierTypeId: NetworkObjectTypeId.Value <- modifierTypeIdGen
- modifiers: Map[ModifierId, Array[Byte]] <- Gen.nonEmptyMap(modifierWithIdGen).suchThat(_.nonEmpty)
- } yield ModifiersData(modifierTypeId, modifiers)
-
- lazy val appVersionGen: Gen[Version] = for {
- fd <- Gen.choose(0: Byte, Byte.MaxValue)
- sd <- Gen.choose(0: Byte, Byte.MaxValue)
- td <- Gen.choose(0: Byte, Byte.MaxValue)
- } yield Version(fd, sd, td)
-
- lazy val inetSocketAddressGen: Gen[InetSocketAddress] = for {
- ip1 <- Gen.choose(0, MaxIp)
- ip2 <- Gen.choose(0, MaxIp)
- ip3 <- Gen.choose(0, MaxIp)
- ip4 <- Gen.choose(0, MaxIp)
- port <- Gen.choose(0, MaxPort)
- } yield new InetSocketAddress(InetAddress.getByName(s"$ip1.$ip2.$ip3.$ip4"), port)
-
- lazy val urlGen: Gen[URL] = for {
- protocol <- Gen.frequency(5 -> const("http://"), 5 -> const("https://"))
- ip1 <- Gen.choose(0, MaxIp)
- ip2 <- Gen.choose(0, MaxIp)
- ip3 <- Gen.choose(0, MaxIp)
- ip4 <- Gen.choose(0, MaxIp)
- host <- Gen.frequency(5 -> const(s"$ip1.$ip2.$ip3.$ip4"), 5 -> const("example.com"))
- port <- Gen.choose(0, MaxPort)
- suffix <- Gen.frequency(5 -> const("/"), 5 -> const(""))
- } yield new URL(s"$protocol$host:$port$suffix")
-
- lazy val connectionIdGen: Gen[ConnectionId] = for {
- ip1 <- inetSocketAddressGen
- ip2 <- inetSocketAddressGen
- direction <- Gen.oneOf[ConnectionDirection](Seq[ConnectionDirection](Incoming, Outgoing))
- } yield ConnectionId(ip1, ip2, direction)
-
- def peerInfoGen: Gen[PeerInfo] = for {
- peerSpec <- peerSpecGen
- } yield PeerInfo(peerSpec, 0L, Some(Incoming), 0L)
-
- def connectedPeerGen(peerRef: ActorRef): Gen[ConnectedPeer] = for {
- connectionId <- connectionIdGen
- peerInfo <- peerInfoGen
- } yield ConnectedPeer(connectionId, peerRef, Some(peerInfo))
-
- def peerSpecGen: Gen[PeerSpec] = for {
- declaredAddress <- Gen.frequency(5 -> const(None), 5 -> some(inetSocketAddressGen))
- features: Seq[PeerFeature] <- Gen.someOf(modePeerFeatureGen, urlGen.flatMap(url => RestApiUrlPeerFeature(url)))
- version <- appVersionGen
- } yield PeerSpec("ergoref", version, "ergo-node", declaredAddress, features)
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/generators/SemanticallyInvalidModifierProducer.scala b/ergo-core/src/test/scala/scorex/testkit/generators/SemanticallyInvalidModifierProducer.scala
deleted file mode 100644
index 015456a936..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/generators/SemanticallyInvalidModifierProducer.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package scorex.testkit.generators
-
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.nodeView.state.ErgoState
-
-
-trait SemanticallyInvalidModifierProducer[ST <: ErgoState[ST]] {
- def semanticallyInvalidModifier(state: ST): BlockSection
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/generators/SemanticallyValidModifierProducer.scala b/ergo-core/src/test/scala/scorex/testkit/generators/SemanticallyValidModifierProducer.scala
deleted file mode 100644
index 33a4e9188b..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/generators/SemanticallyValidModifierProducer.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-package scorex.testkit.generators
-
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.nodeView.state.ErgoState
-
-trait SemanticallyValidModifierProducer[ST <: ErgoState[ST]] {
- def semanticallyValidModifier(state: ST): BlockSection
-}
-
-
diff --git a/ergo-core/src/test/scala/scorex/testkit/generators/SemanticallyValidTransactionsCarryingModifier.scala b/ergo-core/src/test/scala/scorex/testkit/generators/SemanticallyValidTransactionsCarryingModifier.scala
deleted file mode 100644
index bc43d23eea..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/generators/SemanticallyValidTransactionsCarryingModifier.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-package scorex.testkit.generators
-
-import org.ergoplatform.modifiers.history.BlockTransactions
-import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.nodeView.state.ErgoState
-
-trait SemanticallyValidTransactionsCarryingModifier[ST <: ErgoState[ST]] {
-
- def semanticallyValidModifier(state: ST): BlockTransactions
- def genValidTransactionPair(state: ST): Seq[ErgoTransaction]
- def semanticallyValidModifierWithCustomTransactions(state: ST, transactions: Seq[ErgoTransaction]): BlockTransactions
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/generators/SyntacticallyTargetedModifierProducer.scala b/ergo-core/src/test/scala/scorex/testkit/generators/SyntacticallyTargetedModifierProducer.scala
deleted file mode 100644
index c7964259e9..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/generators/SyntacticallyTargetedModifierProducer.scala
+++ /dev/null
@@ -1,11 +0,0 @@
-package scorex.testkit.generators
-
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.nodeView.history.ErgoHistory
-
-
-trait SyntacticallyTargetedModifierProducer {
- def syntacticallyValidModifier(history: ErgoHistory): BlockSection
-
- def syntacticallyInvalidModifier(history: ErgoHistory): BlockSection
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/generators/TotallyValidModifierProducer.scala b/ergo-core/src/test/scala/scorex/testkit/generators/TotallyValidModifierProducer.scala
deleted file mode 100644
index 4373af4332..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/generators/TotallyValidModifierProducer.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-package scorex.testkit.generators
-
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.state.ErgoState
-
-
-trait TotallyValidModifierProducer[ST <: ErgoState[ST]] {
-
- def totallyValidModifier(history: ErgoHistory, state: ST): BlockSection
-
- def totallyValidModifiers(history: ErgoHistory, state: ST, count: Int): Seq[BlockSection]
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/properties/HistoryTests.scala b/ergo-core/src/test/scala/scorex/testkit/properties/HistoryTests.scala
deleted file mode 100644
index 31e2d726e8..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/properties/HistoryTests.scala
+++ /dev/null
@@ -1,86 +0,0 @@
-package scorex.testkit.properties
-
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.scalacheck.Gen
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-import scorex.core.consensus.ModifierSemanticValidity.Valid
-import scorex.testkit.TestkitHelpers
-import scorex.testkit.generators.SyntacticallyTargetedModifierProducer
-import scorex.util.ScorexLogging
-
-
-trait HistoryTests
- extends AnyPropSpec
- with ScalaCheckPropertyChecks
- with Matchers
- with ScorexLogging
- with TestkitHelpers
- with SyntacticallyTargetedModifierProducer {
-
- val historyGen: Gen[ErgoHistory]
-
- lazy val generatorWithValidModifier: Gen[(ErgoHistory, BlockSection)] = {
- historyGen.map { h => (h, syntacticallyValidModifier(h))}
- }
-
- lazy val generatorWithInvalidModifier: Gen[(ErgoHistory, BlockSection)] = {
- historyGen.map { h => (h, syntacticallyInvalidModifier(h))}
- }
-
- private def propertyNameGenerator(propName: String): String = s"HistoryTests: $propName"
-
- property(propertyNameGenerator("applicable with valid modifier")) {
- forAll(generatorWithValidModifier) { case (h, m) => h.applicableTry(m) shouldBe 'success}
- }
-
- property(propertyNameGenerator("append valid modifier")) {
- forAll(generatorWithValidModifier) { case (h, m) => h.append(m).isSuccess shouldBe true }
- }
-
- property(propertyNameGenerator("contain valid modifier after appending")) {
- forAll(generatorWithValidModifier) { case (h, m) =>
- h.append(m)
- h.contains(m) shouldBe true
- }
- }
-
- property(propertyNameGenerator("find valid modifier after appending by modifierId")) {
- forAll(generatorWithValidModifier) { case (h, m) =>
- h.append(m)
- h.modifierById(m.id) shouldBe defined
- }
- }
-
- property(propertyNameGenerator("report semantically validation after appending valid modifier")) {
- forAll(generatorWithValidModifier) { case (h, m) =>
- h.append(m)
- h.reportModifierIsValid(m).get
- h.isSemanticallyValid(m.id) shouldBe Valid
- }
- }
-
- property(propertyNameGenerator("not applicable with invalid modifier")) {
- forAll(generatorWithInvalidModifier) { case (h, m) => h.applicableTry(m) shouldBe 'failure}
- }
-
- property(propertyNameGenerator("not append invalid modifier")) {
- forAll(generatorWithInvalidModifier) { case (h, m) => h.append(m).isSuccess shouldBe false }
- }
-
- property(propertyNameGenerator("not contain invalid modifier after appending")) {
- forAll(generatorWithInvalidModifier) { case (h, m) =>
- h.append(m)
- h.contains(m) shouldBe false
- }
- }
-
- property(propertyNameGenerator("not finds valid modifier after appending by modifierId")) {
- forAll(generatorWithInvalidModifier) { case (h, m) =>
- h.append(m)
- h.modifierById(m.id) shouldBe None
- }
- }
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/properties/NodeViewHolderTests.scala b/ergo-core/src/test/scala/scorex/testkit/properties/NodeViewHolderTests.scala
deleted file mode 100644
index 775b58d8d0..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/properties/NodeViewHolderTests.scala
+++ /dev/null
@@ -1,337 +0,0 @@
-package scorex.testkit.properties
-
-import akka.actor._
-import akka.testkit.TestProbe
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.CurrentView
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.{GetDataFromCurrentView, LocallyGeneratedModifier}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages._
-import org.ergoplatform.nodeView.state.ErgoState
-import scorex.testkit.generators._
-import scorex.testkit.utils.AkkaFixture
-import scorex.util.ScorexLogging
-
-import scala.concurrent.Await
-import scala.concurrent.duration._
-
-@SuppressWarnings(Array("org.wartremover.warts.TraversableOps"))
-trait NodeViewHolderTests[ST <: ErgoState[ST]]
- extends AnyPropSpec
- with Matchers
- with ScorexLogging
- with SyntacticallyTargetedModifierProducer
- with TotallyValidModifierProducer[ST]
- with SemanticallyInvalidModifierProducer[ST]
- with CustomModifierProducer[ST]
- with ObjectGenerators {
-
- def nodeViewHolder(implicit system: ActorSystem): (ActorRef, TestProbe, BlockSection, ST, ErgoHistory)
-
- class HolderFixture extends AkkaFixture {
- @SuppressWarnings(Array("org.wartremover.warts.PublicInference"))
- val (node, eventListener, mod, s, h) = nodeViewHolder
- }
-
- private def withFixture(testCode: HolderFixture => Any): Unit = {
- val fixture = new HolderFixture
- try {
- testCode(fixture)
- } finally {
- Await.result(fixture.system.terminate(), Duration.Inf)
- }
- }
-
- private type CurrentViewType = CurrentView[ST]
-
- private def withView[T](node: ActorRef)(f: CurrentViewType => T)
- (implicit system: ActorSystem): T = {
- val probe = TestProbe()
- probe.send(node,
- GetDataFromCurrentView[ST, CurrentViewType] { view => view })
- val view = probe.expectMsgClass(10.seconds, classOf[CurrentViewType])
- f(view)
- }
-/* todo: fix
- property("NodeViewHolder: modifiers from remote") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- system.eventStream.subscribe(eventListener.ref, classOf[ModifiersRemovedFromCache])
- p.send(node, ModifiersFromRemote(Seq(mod)))
- eventListener.expectMsgType[ModifiersRemovedFromCache]
- }
- }*/
-
- property("NodeViewHolder syntactically valid modifier subscription") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- system.eventStream.subscribe(eventListener.ref, classOf[SyntacticallySuccessfulModifier])
- p.send(node, GetDataFromCurrentView[ST, BlockSection] { v => totallyValidModifiers(v.history, v.state, 2).head })
- val mod = p.expectMsgClass(classOf[BlockSection])
- p.send(node, LocallyGeneratedModifier(mod))
- eventListener.expectMsgType[SyntacticallySuccessfulModifier]
- }
- }
-
- property("NodeViewHolder: syntactically failed modifier subscription") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- system.eventStream.subscribe(eventListener.ref, classOf[SyntacticallyFailedModification])
- val invalid = syntacticallyInvalidModifier(h)
- p.send(node, LocallyGeneratedModifier(invalid))
- eventListener.expectMsgType[SyntacticallyFailedModification]
- }
- }
-
- property("NodeViewHolder: semantically valid modifier subscription") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- system.eventStream.subscribe(eventListener.ref, classOf[SyntacticallySuccessfulModifier])
- system.eventStream.subscribe(eventListener.ref, classOf[FullBlockApplied])
- p.send(node, GetDataFromCurrentView[ST, BlockSection] { v => totallyValidModifiers(v.history, v.state, 2).head })
- val mod = p.expectMsgClass(classOf[BlockSection])
- p.send(node, LocallyGeneratedModifier(mod))
- eventListener.expectMsgType[SyntacticallySuccessfulModifier]
- eventListener.expectMsgType[FullBlockApplied]
- }
- }
-
- property("NodeViewHolder: semantically failed modifier subscription") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- system.eventStream.subscribe(eventListener.ref, classOf[SyntacticallySuccessfulModifier])
- system.eventStream.subscribe(eventListener.ref, classOf[SemanticallyFailedModification])
- p.send(node, GetDataFromCurrentView[ST, BlockSection] { v => semanticallyInvalidModifier(v.state) })
- val invalid = p.expectMsgClass(classOf[BlockSection])
- p.send(node, LocallyGeneratedModifier(invalid))
- eventListener.expectMsgType[SyntacticallySuccessfulModifier]
- eventListener.expectMsgType[SemanticallyFailedModification]
- }
- }
-
- property("NodeViewHolder: syntactically/semantically valid modifier subscription") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- system.eventStream.subscribe(eventListener.ref, classOf[SyntacticallySuccessfulModifier])
- system.eventStream.subscribe(eventListener.ref, classOf[FullBlockApplied])
- p.send(node, GetDataFromCurrentView[ST, BlockSection] { v => totallyValidModifiers(v.history, v.state, 2).head })
- val mod = p.expectMsgClass(classOf[BlockSection])
- p.send(node, LocallyGeneratedModifier(mod))
- eventListener.expectMsgType[SyntacticallySuccessfulModifier]
- eventListener.expectMsgType[FullBlockApplied]
- }
- }
-
- property("NodeViewHolder: check state after creation") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- p.send(node, GetDataFromCurrentView[ST, Boolean] { v =>
- v.state.version == s.version
- })
- p.expectMsg(true)
- }
- }
-
- property("NodeViewHolder: check that a valid modifier is applicable") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- p.send(node, GetDataFromCurrentView[ST, Boolean] { v =>
- v.history.applicableTry(mod).isSuccess
- })
- p.expectMsg(true)
- }
- }
-
- property("NodeViewHolder: check that valid modifiers are applicable") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- system.eventStream.subscribe(eventListener.ref, classOf[SyntacticallySuccessfulModifier])
- system.eventStream.subscribe(eventListener.ref, classOf[SyntacticallyFailedModification])
- p.send(node, GetDataFromCurrentView[ST, Seq[BlockSection]] { v =>
- totallyValidModifiers(v.history, v.state, 10) //todo: fix magic number
- })
- val mods = p.expectMsgClass(classOf[Seq[BlockSection]])
-
- mods.foreach { mod =>
- p.send(node, LocallyGeneratedModifier(mod))
- }
-
- (1 to mods.size).foreach(_ => eventListener.expectMsgType[SyntacticallySuccessfulModifier])
- }
- }
-
- property("NodeViewHolder: apply locally generated mod") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- system.eventStream.subscribe(eventListener.ref, classOf[SyntacticallySuccessfulModifier])
- system.eventStream.subscribe(eventListener.ref, classOf[SyntacticallyFailedModification])
-
- val invalid = syntacticallyInvalidModifier(h)
-
- p.send(node, LocallyGeneratedModifier(invalid))
-
- eventListener.expectMsgType[SyntacticallyFailedModification]
-
- p.send(node, LocallyGeneratedModifier(mod))
-
- eventListener.expectMsgType[SyntacticallySuccessfulModifier]
-
- p.send(node, GetDataFromCurrentView[ST, Boolean] { v =>
- v.state.version == s.version && v.history.contains(mod.id)
- })
-
- p.expectMsg(true)
- }
- }
-
- property("NodeViewHolder: simple forking") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- val waitDuration = 5.seconds
-
- system.eventStream.subscribe(eventListener.ref, classOf[SyntacticallySuccessfulModifier])
- system.eventStream.subscribe(eventListener.ref, classOf[SyntacticallyFailedModification])
-
- p.send(node, GetDataFromCurrentView[ST, Seq[BlockSection]] { v => totallyValidModifiers(v.history, v.state, 2) })
- val initMods = p.expectMsgClass(waitDuration, classOf[Seq[BlockSection]])
- initMods.foreach { mod =>
- p.send(node, LocallyGeneratedModifier(mod))
- eventListener.expectMsgType[SyntacticallySuccessfulModifier]
- }
-
- p.send(node, GetDataFromCurrentView[ST, BlockSection] { v =>
- totallyValidModifiers(v.history, v.state, 2).head
- })
- val fork1Mod = p.expectMsgClass(waitDuration, classOf[BlockSection])
-
- p.send(node, GetDataFromCurrentView[ST, BlockSection] { v =>
- totallyValidModifiers(v.history, v.state, 2).head
- })
- val fork2Mod = p.expectMsgClass(waitDuration, classOf[BlockSection])
-
- p.send(node, LocallyGeneratedModifier(fork1Mod))
- p.send(node, LocallyGeneratedModifier(fork2Mod))
- eventListener.expectMsgType[SyntacticallySuccessfulModifier]
- eventListener.expectMsgType[SyntacticallySuccessfulModifier]
-
- p.send(node, GetDataFromCurrentView[ST, Boolean] { v =>
- v.history.contains(fork1Mod.id) || v.history.contains(fork2Mod.id)
- })
-
- p.expectMsg(10.seconds, true)
- }
- }
-
- /**
- * In this test we apply first a chain of 2 blocks and then a chain of 4 blocks, both started with the same
- * common block. We are expecting to observe "switching" here, though with non-chain structures there could be no
- * notion of switching, so what we check finally is that last block from the second chain is in "open surface"
- * (list of open blocks which do not have successors yet, size of the list is 1 in case of blockchain)
- */
- property("NodeViewHolder: forking - switching") {
- withFixture { ctx =>
- import ctx._
- val p = TestProbe()
-
- val opCountBeforeFork = 10
- val fork1OpCount = 2
- val fork2OpCount = 4
-
- val waitDuration = 10.seconds
-
- //some base operations, we don't wanna have fork right from genesis
- p.send(node, GetDataFromCurrentView[ST, Seq[BlockSection]] { v =>
- totallyValidModifiers(v.history, v.state, opCountBeforeFork)
- })
- val plainMods = p.expectMsgClass(waitDuration, classOf[Seq[BlockSection]])
- plainMods.foreach { mod => p.send(node, LocallyGeneratedModifier(mod)) }
-
- p.send(node, GetDataFromCurrentView[ST, Seq[BlockSection]] { v =>
- val mods = totallyValidModifiers(v.history, v.state, fork1OpCount)
- assert(mods.head.parentId == v.history.bestFullBlockIdOpt.orElse(v.history.bestHeaderIdOpt).get)
- mods
- })
- val fork1Mods = p.expectMsgClass(waitDuration, classOf[Seq[BlockSection]])
-
- p.send(node, GetDataFromCurrentView[ST, Seq[BlockSection]] { v =>
- totallyValidModifiers(v.history, v.state, fork2OpCount)
- })
- val fork2Mods = p.expectMsgClass(waitDuration, classOf[Seq[BlockSection]])
-
- fork1Mods.foreach { mod => p.send(node, LocallyGeneratedModifier(mod)) }
- fork2Mods.foreach { mod => p.send(node, LocallyGeneratedModifier(mod)) }
-
- p.send(node, GetDataFromCurrentView[ST, Boolean] { v =>
- v.history.bestFullBlockIdOpt.orElse(v.history.bestHeaderIdOpt).contains(fork2Mods.last.id)
- })
- p.expectMsg(true)
- }
- }
-
- property("NodeViewHolder: forking - switching with an invalid block") {
- withFixture { ctx =>
- import ctx._
-
- val opCountBeforeFork = 10
- val fork1OpCount = 4
-
- //some base operations, we don't wanna have fork right from genesis
- withView(node) { v =>
- totallyValidModifiers(v.history, v.state, opCountBeforeFork)
- }.foreach {
- mod => node ! LocallyGeneratedModifier(mod)
- }
- // generate the first fork with valid blocks
- val fork1Mods = withView(node) { v =>
- val mods = totallyValidModifiers(v.history, v.state, fork1OpCount)
- assert(mods.head.parentId == v.history.bestFullBlockIdOpt.orElse(v.history.bestHeaderIdOpt).get)
- mods
- }
- // generate the second fork with the invalid block
- val fork2Mods = withView(node) { v =>
- customModifiers(v.history, v.state,
- Seq[ModifierProducerTemplateItem](Valid,
- SynInvalid, // invalid modifier
- Valid, Valid, Valid, Valid, Valid, Valid))
- }
- // apply the first fork with valid blocks
- fork1Mods.foreach { mod => node ! LocallyGeneratedModifier(mod) }
- // apply the second fork with invalid block
- fork2Mods.foreach { mod => node ! LocallyGeneratedModifier(mod) }
- // verify that open surface consist of last block of the first chain,
- // or first block of the second chain, or both, but no any other option
- withView(node) { v =>
- v.history.bestFullBlockIdOpt.orElse(v.history.bestHeaderIdOpt).toSeq should (
- contain only fork1Mods.last.id
- or contain only fork2Mods.head.id
- or contain only(fork1Mods.last.id, fork2Mods.head.id)
- )
- }
- }
- }
-
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MemoryPoolTest.scala b/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MemoryPoolTest.scala
deleted file mode 100644
index 3ee1108614..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MemoryPoolTest.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-package scorex.testkit.properties.mempool
-
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.scalacheck.Gen
-
-
-trait MemoryPoolTest {
- val memPool: ErgoMemPool
- val memPoolGenerator: Gen[ErgoMemPool]
- val transactionGenerator: Gen[ErgoTransaction]
- val unconfirmedTxGenerator: Gen[UnconfirmedTransaction]
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MempoolFilterPerformanceTest.scala b/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MempoolFilterPerformanceTest.scala
deleted file mode 100644
index 0d482a790a..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MempoolFilterPerformanceTest.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-package scorex.testkit.properties.mempool
-
-import java.security.MessageDigest
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-
-trait MempoolFilterPerformanceTest
- extends AnyPropSpec
- with ScalaCheckPropertyChecks
- with Matchers
- with MemoryPoolTest {
-
- var initializedMempool: Option[ErgoMemPool] = None
-
- val thresholdInHashes = 500000
-
- private val HeatJVMHashesCount = 1000000 //to heat up JVM, just in case it is cold
-
- val thresholdSecs: Double = {
- //heat up
- (1 to HeatJVMHashesCount).foreach(i => MessageDigest.getInstance("SHA-256").digest(("dummy" + i).getBytes()))
-
- val t0 = System.currentTimeMillis()
- (1 to thresholdInHashes).foreach(i => MessageDigest.getInstance("SHA-256").digest(("dummy" + i).getBytes()))
- val t = System.currentTimeMillis()
- (t - t0) / 1000.0
- }
-
- property("Mempool should be able to store a lot of transactions") {
- var m: ErgoMemPool = memPool
- (0 until 1000) foreach { _ =>
- forAll(transactionGenerator) { tx: ErgoTransaction =>
- m = m.put(UnconfirmedTransaction(tx, None))
- }
- }
- m.size should be > 1000
- initializedMempool = Some(m)
- }
-
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MempoolRemovalTest.scala b/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MempoolRemovalTest.scala
deleted file mode 100644
index 5506e6ac35..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MempoolRemovalTest.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-package scorex.testkit.properties.mempool
-
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.scalacheck.Gen
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-import scorex.testkit.TestkitHelpers
-import scorex.testkit.generators.ArbitraryTransactionsCarryingModifierProducer
-import scorex.util.ScorexLogging
-
-trait MempoolRemovalTest extends AnyPropSpec
- with ScalaCheckPropertyChecks
- with Matchers
- with ScorexLogging
- with TestkitHelpers
- with MemoryPoolTest
- with ArbitraryTransactionsCarryingModifierProducer {
-
- val historyGen: Gen[ErgoHistory]
-
- //todo: this test doesn't check anything. It should be reworked as a test for node view holder
- property("Transactions once added to block should be removed from Mempool") {
- val min = 1
- val max = 10
- forAll(Gen.choose(min, max)) { _ =>
- var m: ErgoMemPool = memPool
- // var h: ErgoHistory = historyGen.sample.get
- forAll(transactionGenerator) { tx: ErgoTransaction =>
- m = m.put(UnconfirmedTransaction(tx, None))
- }
- // var prevMempoolSize = m.size
- // val b = modifierWithTransactions(Some(m), None)
- //todo: fix (m.size + b.transactions.get.size) shouldEqual prevMempoolSize
- }
- }
-}
-
-
diff --git a/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MempoolTransactionsTest.scala b/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MempoolTransactionsTest.scala
deleted file mode 100644
index 891c854c7e..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/properties/mempool/MempoolTransactionsTest.scala
+++ /dev/null
@@ -1,155 +0,0 @@
-package scorex.testkit.properties.mempool
-
-import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.scalacheck.Gen
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-
-@SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
-trait MempoolTransactionsTest
- extends AnyPropSpec
- with ScalaCheckPropertyChecks
- with Matchers
- with MemoryPoolTest {
-
- val transactionSeqGenerator: Gen[Seq[ErgoTransaction]] = Gen.nonEmptyContainerOf[Seq, ErgoTransaction](transactionGenerator)
- val unconfirmedTxSeqGenerator: Gen[Seq[UnconfirmedTransaction]] =
- transactionSeqGenerator.map(txs => txs.map(tx => UnconfirmedTransaction(tx, None)))
-
- property("Size of mempool should increase when adding a non-present transaction") {
- forAll(memPoolGenerator, unconfirmedTxGenerator) { (mp: ErgoMemPool, unconfirmedTx: UnconfirmedTransaction) =>
- val m: ErgoMemPool = mp.put(unconfirmedTx)
- m.size shouldEqual 1
- }
- }
-
- property("Size of mempool should not increase when adding a present transaction") {
- forAll(memPoolGenerator, unconfirmedTxGenerator) { (mp: ErgoMemPool, unconfirmedTx: UnconfirmedTransaction) =>
- val m: ErgoMemPool = mp.put(unconfirmedTx)
- val m2: ErgoMemPool = m.put(unconfirmedTx)
- m2.size shouldEqual 1
- }
- }
-
- property("Size of mempool should increase when adding a collection of non-present transactions " +
- "without duplicates (with check)") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction]) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs)
- m.size shouldEqual unconfirmedTxs.size
- }
- }
-
- property("Size of mempool should increase for a number of unique non-present transactions " +
- "when adding a collection of non-present txs with duplicates (with check)") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction]) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs ++ unconfirmedTxs)
- m.size shouldEqual unconfirmedTxs.size
- }
- }
-
- property("Size of mempool should not increase when adding a collection of present transactions (with check)") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction]) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs)
- val m2: ErgoMemPool = m.put(unconfirmedTxs)
- m2.size shouldEqual unconfirmedTxs.size
- }
- }
-
- property("Size of mempool should increase when adding a collection of non-present transactions " +
- "without duplicates (without check)") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction]) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs)
- m.size shouldEqual unconfirmedTxs.size
- }
- }
-
- property("Size of mempool should increase for a number of unique non-present transactions " +
- "when adding a collection of non-present transactions with duplicates (without check)") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction]) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs ++ unconfirmedTxs)
- m.size shouldEqual unconfirmedTxs.size
- }
- }
-
- property("Size of mempool should not increase when adding a collection of present transactions (without check)") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction]) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs)
- val m2: ErgoMemPool = m.put(unconfirmedTxs)
- m2.size shouldEqual unconfirmedTxs.size
- }
- }
-
- property("Size of mempool should decrease when removing a present transaction") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction]) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs)
- val m2: ErgoMemPool = m.remove(unconfirmedTxs.headOption.get.transaction)
- m2.size shouldBe unconfirmedTxs.size - 1
- }
- }
-
- property("Size of mempool should not decrease when removing a non-present transaction") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator, unconfirmedTxGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction], unconfirmedTx: UnconfirmedTransaction) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs)
- val m2: ErgoMemPool = m.remove(unconfirmedTx.transaction)
- m2.size shouldBe unconfirmedTxs.size
- }
- }
-
- property("Present transactions should be available by id") {
- forAll(memPoolGenerator, unconfirmedTxGenerator) { (mp: ErgoMemPool, unconfirmedTx: UnconfirmedTransaction) =>
- val m: ErgoMemPool = mp.put(unconfirmedTx)
- m.modifierById(unconfirmedTx.transaction.id).isDefined shouldBe true
- }
- }
-
- property("Non-present transactions should not be available by id") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator, unconfirmedTxGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction], unconfirmedTx: UnconfirmedTransaction) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs)
- m.modifierById(unconfirmedTx.transaction.id).isDefined shouldBe false
- }
- }
-
- property("Mempool should contain present transactions") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction]) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs)
- m.contains(unconfirmedTxs.headOption.get.transaction.id) shouldBe true
- }
- }
-
- property("Mempool should not contain non-present transactions") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator, unconfirmedTxGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction], unconfirmedTx: UnconfirmedTransaction) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs)
- m.contains(unconfirmedTx.transaction.id) shouldBe false
- }
- }
-
- property("Present transactions should be obtained by their ids") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator, unconfirmedTxGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction], unconfirmedTx: UnconfirmedTransaction) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs :+ unconfirmedTx)
- m.getAll(unconfirmedTxs.map(_.transaction.id)) sameElements unconfirmedTxs
- }
- }
-
- property("Non-present transactions should not be obtained by their ids") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator, unconfirmedTxGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction], unconfirmedTx: UnconfirmedTransaction) =>
- val m: ErgoMemPool = mp.put(unconfirmedTx)
- m.getAll(unconfirmedTxs.map(_.transaction.id)).size shouldBe 0
- }
- }
-
- property("Required number of transactions should be taken from mempool") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator, unconfirmedTxGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction], tx: UnconfirmedTransaction) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs :+ tx)
- m.take(unconfirmedTxs.size).size shouldBe unconfirmedTxs.size
- }
- }
-
- property("Maximum number of transactions that can be taken should equals mempool size") {
- forAll(memPoolGenerator, unconfirmedTxSeqGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction]) =>
- val m: ErgoMemPool = mp.put(unconfirmedTxs)
- m.take(unconfirmedTxs.size + 1).size shouldBe m.size
- }
- }
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/properties/state/StateApplicationTest.scala b/ergo-core/src/test/scala/scorex/testkit/properties/state/StateApplicationTest.scala
deleted file mode 100644
index 805550fffe..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/properties/state/StateApplicationTest.scala
+++ /dev/null
@@ -1,106 +0,0 @@
-package scorex.testkit.properties.state
-
-import org.ergoplatform.modifiers.BlockSection
-import org.ergoplatform.nodeView.state.{DigestState, ErgoState}
-import org.scalacheck.Gen
-import scala.collection.mutable.ListBuffer
-
-
-trait StateApplicationTest[ST <: ErgoState[ST]] extends StateTests[ST] {
-
- lazy val stateGenWithValidModifier: Gen[(ST, BlockSection)] = {
- stateGen.map { s => (s, semanticallyValidModifier(s)) }
- }
-
- lazy val stateGenWithInvalidModifier: Gen[(ST, BlockSection)] = {
- stateGen.map { s => (s, semanticallyInvalidModifier(s))}
- }
-
- private def propertyNameGenerator(propName: String): String = s"StateTests: $propName"
-
- property(propertyNameGenerator("apply modifier")) {
- forAll(stateGenWithValidModifier) { case (s, m) =>
- val ver = s.version
- val sTry = s.applyModifier(m, None)(_ => ())
- sTry.isSuccess shouldBe true
- sTry.get.version == ver shouldBe false
- }
- }
-
- property(propertyNameGenerator("do not apply same valid modifier twice")) {
- forAll(stateGenWithValidModifier) { case (s, m) =>
- val ver = s.version
- val sTry = s.applyModifier(m, None)(_ => ())
- sTry.isSuccess shouldBe true
- val s2 = sTry.get
- s2.version == ver shouldBe false
- s2.applyModifier(m, None)(_ => ()).isSuccess shouldBe false
- }
- }
-
- property(propertyNameGenerator("do not apply invalid modifier")) {
- forAll(stateGenWithInvalidModifier) { case (s, m) =>
- val sTry = s.applyModifier(m, None)(_ => ())
- sTry.isSuccess shouldBe false
- }
- }
-
- property(propertyNameGenerator("apply valid modifier after rollback")) {
- forAll(stateGenWithValidModifier) { case (s, m) =>
- val ver = s.version
- s.store.setKeepVersions(10)
- val sTry = s.applyModifier(m, Some(0))(_ => ())
- sTry.isSuccess shouldBe true
- val s2 = sTry.get
- s2.version == ver shouldBe false
- val ver2 = s2.version
-
- val s3 = s2.rollbackTo(ver).get
- s3.version == ver shouldBe true
-
- val sTry2 = s3.applyModifier(m, None)(_ => ())
- sTry2.isSuccess shouldBe true
- val s4 = sTry2.get
- s4.version == ver shouldBe false
- s4.version == ver2 shouldBe true
- }
- }
-
- property(propertyNameGenerator("application after rollback is possible")) {
- forAll(stateGen) { s =>
- s.store.setKeepVersions(10)
- val maxRollbackDepth = s match {
- case ds: DigestState =>
- ds.store.rollbackVersions().size
- case _ =>
- 10
- }
- @SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
- val rollbackDepth = Gen.chooseNum(1, maxRollbackDepth).sample.get
- val buf = new ListBuffer[BlockSection]()
- val ver = s.version
-
- val s2 = (0 until rollbackDepth).foldLeft(s) { case (state, _) =>
- val modifier = semanticallyValidModifier(state)
- buf += modifier
- val sTry = state.applyModifier(modifier, Some(rollbackDepth))(_ => ())
- sTry shouldBe 'success
- sTry.get
- }
-
- val lastVersion = s2.version
- val rollbackTry = s2.rollbackTo(ver)
- rollbackTry.toOption shouldBe defined
- val s3 = rollbackTry.get
- s3.version == ver shouldBe true
-
- val s4 = buf.foldLeft(s3) { case (state, m) =>
- val sTry = state.applyModifier(m, Some(0))(_ => ())
- sTry shouldBe 'success
- sTry.get
- }
-
- s4.version == lastVersion shouldBe true
- }
- }
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/properties/state/StateTests.scala b/ergo-core/src/test/scala/scorex/testkit/properties/state/StateTests.scala
deleted file mode 100644
index 78c1452c8f..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/properties/state/StateTests.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-package scorex.testkit.properties.state
-
-import org.ergoplatform.nodeView.state.ErgoState
-import org.scalacheck.Gen
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.propspec.AnyPropSpec
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-import scorex.testkit.TestkitHelpers
-import scorex.testkit.generators.{CoreGenerators, SemanticallyInvalidModifierProducer, SemanticallyValidModifierProducer}
-
-trait StateTests[ST <: ErgoState[ST]]
- extends AnyPropSpec
- with ScalaCheckPropertyChecks
- with Matchers
- with CoreGenerators
- with TestkitHelpers
- with SemanticallyValidModifierProducer[ST]
- with SemanticallyInvalidModifierProducer[ST] {
-
- val checksToMake = 10
-
- val stateGen: Gen[ST]
-}
diff --git a/ergo-core/src/test/scala/scorex/testkit/utils/AkkaFixture.scala b/ergo-core/src/test/scala/scorex/testkit/utils/AkkaFixture.scala
deleted file mode 100644
index c3aa3b978e..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/utils/AkkaFixture.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package scorex.testkit.utils
-
-import java.util.concurrent.atomic.AtomicInteger
-
-import akka.actor.ActorSystem
-import akka.testkit.{ImplicitSender, TestKit}
-
-object SysId {
- private val i = new AtomicInteger()
- def incrementAndGet(): Int = i.incrementAndGet()
-}
-
-class AkkaFixture
- extends TestKit(ActorSystem("WithIsoFix-%d".format(SysId.incrementAndGet())))
- with ImplicitSender
diff --git a/ergo-core/src/test/scala/scorex/testkit/utils/NoShrink.scala b/ergo-core/src/test/scala/scorex/testkit/utils/NoShrink.scala
deleted file mode 100644
index 4653280842..0000000000
--- a/ergo-core/src/test/scala/scorex/testkit/utils/NoShrink.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-package scorex.testkit.utils
-
-import org.scalacheck.Shrink
-
-trait NoShrink {
- protected implicit def noShrink[A]: Shrink[A] = Shrink(_ => Stream.empty)
-}
diff --git a/src/test/scala/org/ergoplatform/http/routes/EmissionApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/EmissionApiRouteSpec.scala
index 7d89b239a5..c48d4a6dbe 100644
--- a/src/test/scala/org/ergoplatform/http/routes/EmissionApiRouteSpec.scala
+++ b/src/test/scala/org/ergoplatform/http/routes/EmissionApiRouteSpec.scala
@@ -9,7 +9,7 @@ import io.circe.Json
import io.circe.syntax._
import org.ergoplatform.http.api.EmissionApiRoute
import org.ergoplatform.mining.emission.EmissionRules
-import org.ergoplatform.settings.{ErgoSettings, ReemissionSettings}
+import org.ergoplatform.settings.{ErgoSettings, ErgoSettingsReader, ReemissionSettings}
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
@@ -24,7 +24,7 @@ class EmissionApiRouteSpec extends AnyFlatSpec
implicit val timeout: RouteTestTimeout = RouteTestTimeout(15.seconds.dilated)
- val ergoSettings: ErgoSettings = ErgoSettings.read()
+ val ergoSettings: ErgoSettings = ErgoSettingsReader.read()
val coinEmission: EmissionRules = ergoSettings.chainSettings.emissionRules
val reemissionSettings: ReemissionSettings = ergoSettings.chainSettings.reemission
diff --git a/src/test/scala/org/ergoplatform/http/routes/InfoApiRoutesSpec.scala b/src/test/scala/org/ergoplatform/http/routes/InfoApiRoutesSpec.scala
index 706ff37ddd..31fc10fa3b 100644
--- a/src/test/scala/org/ergoplatform/http/routes/InfoApiRoutesSpec.scala
+++ b/src/test/scala/org/ergoplatform/http/routes/InfoApiRoutesSpec.scala
@@ -16,8 +16,8 @@ import org.ergoplatform.local.ErgoStatsCollector.{GetNodeInfo, NodeInfo}
import org.ergoplatform.local.ErgoStatsCollectorRef
import org.ergoplatform.mining.difficulty.DifficultySerializer
import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.ChangedHistory
-import org.ergoplatform.nodeView.history.ErgoHistory.Difficulty
+import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages.ChangedHistory
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants.Difficulty
import org.ergoplatform.utils.Stubs
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
diff --git a/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala
index fb4956190f..c3a1c33851 100644
--- a/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala
+++ b/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala
@@ -10,7 +10,7 @@ import org.ergoplatform.ErgoBox
import org.ergoplatform.http.api.ScanEntities.{ScanIdBoxId, ScanIdWrapper}
import org.ergoplatform.http.api.{ApiCodecs, ScanApiRoute}
import org.ergoplatform.nodeView.wallet.scanning._
-import org.ergoplatform.settings.{Args, ErgoSettings}
+import org.ergoplatform.settings.{Args, ErgoSettings, ErgoSettingsReader}
import org.ergoplatform.utils.Stubs
import org.ergoplatform.wallet.Constants.ScanId
import org.scalatest.flatspec.AnyFlatSpec
@@ -36,7 +36,7 @@ class ScanApiRouteSpec extends AnyFlatSpec
val prefix = "/scan"
- val ergoSettings: ErgoSettings = ErgoSettings.read(
+ val ergoSettings: ErgoSettings = ErgoSettingsReader.read(
Args(userConfigPathOpt = Some("src/test/resources/application.conf"), networkTypeOpt = None))
val route: Route = ScanApiRoute(utxoReadersRef, ergoSettings).route
diff --git a/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala
index acd2fd8de5..ff4b372c56 100644
--- a/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala
+++ b/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala
@@ -6,7 +6,7 @@ import akka.http.scaladsl.testkit.ScalatestRouteTest
import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
import io.circe.Json
import org.ergoplatform.{Pay2SAddress, Pay2SHAddress}
-import org.ergoplatform.settings.{Args, ErgoSettings}
+import org.ergoplatform.settings.{Args, ErgoSettings, ErgoSettingsReader}
import org.ergoplatform.utils.Stubs
import io.circe.syntax._
import org.ergoplatform.http.api.ScriptApiRoute
@@ -26,7 +26,7 @@ class ScriptApiRouteSpec extends AnyFlatSpec
val prefix = "/script"
- val ergoSettings: ErgoSettings = ErgoSettings.read(
+ val ergoSettings: ErgoSettings = ErgoSettingsReader.read(
Args(userConfigPathOpt = Some("src/test/resources/application.conf"), networkTypeOpt = None))
val route: Route = ScriptApiRoute(digestReadersRef, settings).route
diff --git a/src/test/scala/org/ergoplatform/http/routes/WalletApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/WalletApiRouteSpec.scala
index 3aa73d9dc1..f904eb5fff 100644
--- a/src/test/scala/org/ergoplatform/http/routes/WalletApiRouteSpec.scala
+++ b/src/test/scala/org/ergoplatform/http/routes/WalletApiRouteSpec.scala
@@ -6,11 +6,11 @@ import akka.http.scaladsl.testkit.{RouteTestTimeout, ScalatestRouteTest}
import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
import io.circe.syntax._
import io.circe.{Decoder, Json}
-import org.ergoplatform.http.api.{ApiCodecs, WalletApiRoute}
+import org.ergoplatform.http.api.{ApiCodecs, ApiNodeViewCodecs, WalletApiRoute}
import org.ergoplatform.modifiers.mempool.ErgoTransaction
import org.ergoplatform.nodeView.wallet.requests.{AssetIssueRequestEncoder, PaymentRequest, PaymentRequestEncoder, _}
import org.ergoplatform.nodeView.wallet.{AugWalletTransaction, ErgoAddressJsonEncoder}
-import org.ergoplatform.settings.{Args, Constants, ErgoSettings}
+import org.ergoplatform.settings.{Args, Constants, ErgoSettings, ErgoSettingsReader}
import org.ergoplatform.utils.Stubs
import org.ergoplatform.utils.generators.ErgoTransactionGenerators
import org.ergoplatform.{ErgoAddress, Pay2SAddress}
@@ -27,13 +27,14 @@ class WalletApiRouteSpec extends AnyFlatSpec
with ScalatestRouteTest
with Stubs
with FailFastCirceSupport
- with ApiCodecs {
+ with ApiCodecs
+ with ApiNodeViewCodecs {
implicit val timeout: RouteTestTimeout = RouteTestTimeout(145.seconds)
val prefix = "/wallet"
- val ergoSettings: ErgoSettings = ErgoSettings.read(
+ val ergoSettings: ErgoSettings = ErgoSettingsReader.read(
Args(userConfigPathOpt = Some("src/test/resources/application.conf"), networkTypeOpt = None))
val route: Route = WalletApiRoute(digestReadersRef, nodeViewRef, settings).route
val failingNodeViewRef = system.actorOf(NodeViewStub.failingProps())
@@ -44,7 +45,7 @@ class WalletApiRouteSpec extends AnyFlatSpec
implicit val paymentRequestEncoder: PaymentRequestEncoder = new PaymentRequestEncoder(ergoSettings)
implicit val assetIssueRequestEncoder: AssetIssueRequestEncoder = new AssetIssueRequestEncoder(ergoSettings)
implicit val requestsHolderEncoder: RequestsHolderEncoder = new RequestsHolderEncoder(ergoSettings)
- implicit val addressJsonDecoder: Decoder[ErgoAddress] = ErgoAddressJsonEncoder(settings).decoder
+ implicit val addressJsonDecoder: Decoder[ErgoAddress] = ErgoAddressJsonEncoder(settings.chainSettings).decoder
val paymentRequest = PaymentRequest(Pay2SAddress(Constants.FalseLeaf)(addressEncoder), 100L, Seq.empty, Map.empty)
val assetIssueRequest = AssetIssueRequest(Pay2SAddress(Constants.FalseLeaf)(addressEncoder), None, 100L, "TEST", "Test", 8)
diff --git a/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala b/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala
index f018569c5e..0b0022b5c9 100644
--- a/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala
+++ b/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala
@@ -4,9 +4,9 @@ import akka.actor.{ActorRef, ActorSystem}
import akka.testkit.{TestActorRef, TestProbe}
import org.ergoplatform.ErgoAddressEncoder
import org.ergoplatform.modifiers.mempool.UnconfirmedTransaction
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.{FailedTransaction, RecheckMempool, SuccessfulTransaction}
+import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages.{FailedTransaction, RecheckMempool, SuccessfulTransaction}
import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.{LocallyGeneratedTransaction, RecheckedTransactions}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.ProcessingOutcome
+import org.ergoplatform.nodeView.mempool.ErgoMemPoolTypes.ProcessingOutcome
import org.ergoplatform.nodeView.state.ErgoState
import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
import org.ergoplatform.settings.{Algos, Constants, ErgoSettings}
diff --git a/src/test/scala/org/ergoplatform/mining/CandidateGeneratorPropSpec.scala b/src/test/scala/org/ergoplatform/mining/CandidateGeneratorPropSpec.scala
index 0b4f9cd0a7..9fb5a6df9f 100644
--- a/src/test/scala/org/ergoplatform/mining/CandidateGeneratorPropSpec.scala
+++ b/src/test/scala/org/ergoplatform/mining/CandidateGeneratorPropSpec.scala
@@ -1,7 +1,7 @@
package org.ergoplatform.mining
import org.ergoplatform.ErgoTreePredef
-import org.ergoplatform.nodeView.history.ErgoHistory
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.nodeView.state.ErgoStateContext
import org.ergoplatform.settings.MonetarySettings
import org.ergoplatform.utils.{ErgoPropertyTest, RandomWrapper}
@@ -199,7 +199,7 @@ class CandidateGeneratorPropSpec extends ErgoPropertyTest {
val bh = boxesHolderGen.sample.get
var us = createUtxoState(bh, parameters)
- val height = ErgoHistory.EmptyHistoryHeight
+ val height = EmptyHistoryHeight
val ms = MonetarySettings(minerRewardDelay = delta)
val st = settings.copy(chainSettings = settings.chainSettings.copy(monetary = ms))
@@ -248,7 +248,7 @@ class CandidateGeneratorPropSpec extends ErgoPropertyTest {
Gen.nonEmptyListOf(validErgoTransactionGenTemplate(minAssets = 0, propositionGen = feeProp))
) { btxs =>
val blockTxs = btxs.map(_._2)
- val height = ErgoHistory.EmptyHistoryHeight
+ val height = EmptyHistoryHeight
val txs = CandidateGenerator.collectRewards(
us.emissionBoxOpt,
height,
diff --git a/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala b/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala
index 148d5ebffb..d94938f591 100644
--- a/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala
+++ b/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala
@@ -9,12 +9,12 @@ import org.ergoplatform.mining.CandidateGenerator.{Candidate, GenerateCandidate}
import org.ergoplatform.modifiers.ErgoFullBlock
import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.FullBlockApplied
+import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages.FullBlockApplied
import org.ergoplatform.nodeView.ErgoReadersHolder.{GetReaders, Readers}
import org.ergoplatform.nodeView.history.ErgoHistoryReader
import org.ergoplatform.nodeView.state.StateType
import org.ergoplatform.nodeView.{ErgoNodeViewRef, ErgoReadersHolderRef}
-import org.ergoplatform.settings.ErgoSettings
+import org.ergoplatform.settings.{ErgoSettings, ErgoSettingsReader}
import org.ergoplatform.utils.ErgoTestHelpers
import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, ErgoTreePredef, Input}
import org.scalatest.concurrent.Eventually
@@ -34,7 +34,7 @@ class CandidateGeneratorSpec extends AnyFlatSpec with ErgoTestHelpers with Event
private val blockValidationDelay: FiniteDuration = 2.seconds
val defaultSettings: ErgoSettings = {
- val empty = ErgoSettings.read()
+ val empty = ErgoSettingsReader.read()
val nodeSettings = empty.nodeSettings.copy(
mining = true,
stateType = StateType.Utxo,
diff --git a/src/test/scala/org/ergoplatform/mining/ErgoMinerSpec.scala b/src/test/scala/org/ergoplatform/mining/ErgoMinerSpec.scala
index 25258277e3..dcfb805a23 100644
--- a/src/test/scala/org/ergoplatform/mining/ErgoMinerSpec.scala
+++ b/src/test/scala/org/ergoplatform/mining/ErgoMinerSpec.scala
@@ -10,14 +10,14 @@ import org.ergoplatform.mining.ErgoMiner.StartMining
import org.ergoplatform.modifiers.ErgoFullBlock
import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction, UnsignedErgoTransaction}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.FullBlockApplied
+import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages.FullBlockApplied
import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedTransaction
import org.ergoplatform.nodeView.ErgoReadersHolder.{GetReaders, Readers}
import org.ergoplatform.nodeView.history.ErgoHistoryReader
import org.ergoplatform.nodeView.state._
import org.ergoplatform.nodeView.wallet._
import org.ergoplatform.nodeView.{ErgoNodeViewRef, ErgoReadersHolderRef}
-import org.ergoplatform.settings.ErgoSettings
+import org.ergoplatform.settings.{ErgoSettings, ErgoSettingsReader}
import org.ergoplatform.utils.ErgoTestHelpers
import org.ergoplatform.utils.generators.ValidBlocksGenerators
import org.ergoplatform.wallet.interpreter.ErgoInterpreter
@@ -47,7 +47,7 @@ class ErgoMinerSpec extends AnyFlatSpec with ErgoTestHelpers with ValidBlocksGen
await(minerRef.askWithStatus(GenerateCandidate(mandatoryTransactions, reply = true)).mapTo[Candidate].map(_.externalVersion))
val defaultSettings: ErgoSettings = {
- val empty = ErgoSettings.read()
+ val empty = ErgoSettingsReader.read()
val nodeSettings = empty.nodeSettings.copy(mining = true,
stateType = StateType.Utxo,
@@ -376,7 +376,7 @@ class ErgoMinerSpec extends AnyFlatSpec with ErgoTestHelpers with ValidBlocksGen
system.eventStream.subscribe(testProbe.ref, newBlockSignal)
val forkSettings: ErgoSettings = {
- val empty = ErgoSettings.read()
+ val empty = ErgoSettingsReader.read()
val nodeSettings = empty.nodeSettings.copy(mining = true,
stateType = StateType.Utxo,
diff --git a/src/test/scala/org/ergoplatform/modifiers/history/PoPowAlgosSpec.scala b/src/test/scala/org/ergoplatform/modifiers/history/PoPowAlgosSpec.scala
index ea2a976724..6eabd252ad 100644
--- a/src/test/scala/org/ergoplatform/modifiers/history/PoPowAlgosSpec.scala
+++ b/src/test/scala/org/ergoplatform/modifiers/history/PoPowAlgosSpec.scala
@@ -1,6 +1,6 @@
package org.ergoplatform.modifiers.history
-import org.ergoplatform.modifiers.history.popow.{NipopowAlgos, NipopowProof, PoPowHeader, PoPowParams}
+import org.ergoplatform.modifiers.history.popow.{NipopowAlgos, NipopowErgoAlgos, NipopowProof, PoPowHeader, PoPowParams}
import org.ergoplatform.modifiers.ErgoFullBlock
import org.ergoplatform.nodeView.state.StateType
import org.ergoplatform.utils.generators.ChainGenerator
@@ -127,7 +127,7 @@ class PoPowAlgosSpec extends AnyPropSpec with Matchers with HistoryTestHelpers w
val h = generateHistory(true, StateType.Digest, false,
10000, 10000, 10, None)
val hr = applyChain(h, blocksChain)
- val proof1 = nipopowAlgos.prove(hr)(poPowParams).get
+ val proof1 = NipopowErgoAlgos.prove(hr, chainSettings = settings.chainSettings)(poPowParams).get
proof0.suffixHead.id shouldBe proof1.suffixHead.id
proof0.suffixTail.map(_.id) shouldBe proof1.suffixTail.map(_.id)
@@ -145,12 +145,12 @@ class PoPowAlgosSpec extends AnyPropSpec with Matchers with HistoryTestHelpers w
val h = generateHistory(true, StateType.Digest, false,
10000, 10000, 10, None)
val hr = applyChain(h, blocksChain.take(at))
- val proof0 = nipopowAlgos.prove(hr, None)(poPowParams).get
+ val proof0 = NipopowErgoAlgos.prove(hr, None, chainSettings = settings.chainSettings)(poPowParams).get
val id = proof0.suffixHead.header.id
val hrf = applyChain(hr, blocksChain.drop(at))
- val proof1 = nipopowAlgos.prove(hrf, Some(id))(poPowParams).get
+ val proof1 = NipopowErgoAlgos.prove(hrf, Some(id), chainSettings = settings.chainSettings)(poPowParams).get
proof0.suffixHead.id shouldBe proof1.suffixHead.id
proof0.suffixTail.map(_.id) shouldBe proof1.suffixTail.map(_.id)
diff --git a/src/test/scala/org/ergoplatform/network/ErgoNodeViewSynchronizerSpecification.scala b/src/test/scala/org/ergoplatform/network/ErgoNodeViewSynchronizerSpecification.scala
index 2430aa7728..efb8d45762 100644
--- a/src/test/scala/org/ergoplatform/network/ErgoNodeViewSynchronizerSpecification.scala
+++ b/src/test/scala/org/ergoplatform/network/ErgoNodeViewSynchronizerSpecification.scala
@@ -4,14 +4,14 @@ import akka.actor.{ActorRef, ActorSystem, Cancellable, Props}
import akka.testkit.TestProbe
import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer}
import org.ergoplatform.modifiers.{BlockSection, ErgoFullBlock}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages._
+import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages._
import org.ergoplatform.nodeView.ErgoNodeViewHolder
import org.ergoplatform.nodeView.history.{ErgoHistory, ErgoHistoryReader, ErgoSyncInfoMessageSpec, ErgoSyncInfoV2}
import org.ergoplatform.nodeView.mempool.ErgoMemPool
import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
import org.ergoplatform.nodeView.state.{StateType, UtxoState}
import org.ergoplatform.sanity.ErgoSanity._
-import org.ergoplatform.settings.ErgoSettings
+import org.ergoplatform.settings.{ErgoSettings, ErgoSettingsReader}
import org.ergoplatform.utils.HistoryTestHelpers
import org.ergoplatform.wallet.utils.FileUtils
import org.scalacheck.Gen
@@ -126,7 +126,7 @@ class ErgoNodeViewSynchronizerSpecification extends HistoryTestHelpers with Matc
val h = localHistoryGen.sample.get
@SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
val s = localStateGen.sample.get
- val settings = ErgoSettings.read()
+ val settings = ErgoSettingsReader.read()
val pool = ErgoMemPool.empty(settings)
implicit val ec: ExecutionContextExecutor = system.dispatcher
val ncProbe = TestProbe("NetworkControllerProbe")
diff --git a/src/test/scala/org/ergoplatform/nodeView/ErgoModifiersCacheSpec.scala b/src/test/scala/org/ergoplatform/nodeView/ErgoModifiersCacheSpec.scala
index 29e67176bd..673ad6b6ed 100644
--- a/src/test/scala/org/ergoplatform/nodeView/ErgoModifiersCacheSpec.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/ErgoModifiersCacheSpec.scala
@@ -2,7 +2,7 @@ package org.ergoplatform.nodeView
import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.history.{ADProofs, BlockTransactions}
-import org.ergoplatform.nodeView.history.ErgoHistory
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.nodeView.state.StateType
import org.ergoplatform.utils.{ErgoPropertyTest, HistoryTestHelpers}
import scorex.crypto.hash.Blake2b256
@@ -64,7 +64,7 @@ class ErgoModifiersCacheSpec extends ErgoPropertyTest with HistoryTestHelpers {
val c1 = modifiersCache.popCandidate(history0).value
c1.isInstanceOf[Header] shouldBe true
val h1 = c1.asInstanceOf[Header]
- h1.height shouldBe ErgoHistory.GenesisHeight
+ h1.height shouldBe GenesisHeight
val history1 = history0.append(c1).get._1
diff --git a/src/test/scala/org/ergoplatform/nodeView/NodeViewSynchronizerTests.scala b/src/test/scala/org/ergoplatform/nodeView/NodeViewSynchronizerTests.scala
index 9311d13c78..829084d463 100644
--- a/src/test/scala/org/ergoplatform/nodeView/NodeViewSynchronizerTests.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/NodeViewSynchronizerTests.scala
@@ -5,7 +5,7 @@ import akka.testkit.TestProbe
import org.ergoplatform.modifiers.BlockSection
import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages._
+import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages._
import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.{GetNodeViewChanges, ModifiersFromRemote}
import org.ergoplatform.nodeView.history.{ErgoHistory, ErgoSyncInfo, ErgoSyncInfoMessageSpec}
import org.ergoplatform.nodeView.mempool.ErgoMemPool
diff --git a/src/test/scala/org/ergoplatform/nodeView/history/BlockSectionValidationSpecification.scala b/src/test/scala/org/ergoplatform/nodeView/history/BlockSectionValidationSpecification.scala
index 40feb58cef..f8df13aab8 100644
--- a/src/test/scala/org/ergoplatform/nodeView/history/BlockSectionValidationSpecification.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/history/BlockSectionValidationSpecification.scala
@@ -5,6 +5,7 @@ import org.ergoplatform.modifiers.history._
import org.ergoplatform.modifiers.history.extension.Extension
import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.nodeView.state.StateType
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.utils.HistoryTestHelpers
import scorex.core.consensus.ModifierSemanticValidity
import scorex.crypto.hash.Blake2b256
@@ -75,7 +76,7 @@ class BlockSectionValidationSpecification extends HistoryTestHelpers {
history.writeMinimalFullBlockHeight(history.bestHeaderOpt.get.height + 1)
history.isHeadersChainSyncedVar = true
history.applicableTry(section) shouldBe 'failure
- history.writeMinimalFullBlockHeight(ErgoHistory.GenesisHeight)
+ history.writeMinimalFullBlockHeight(GenesisHeight)
// should not be able to apply if corresponding header is marked as invalid
history.applicableTry(section) shouldBe 'success
diff --git a/src/test/scala/org/ergoplatform/nodeView/history/NonVerifyADHistorySpecification.scala b/src/test/scala/org/ergoplatform/nodeView/history/NonVerifyADHistorySpecification.scala
index b2cbb964ca..f4a7e10894 100644
--- a/src/test/scala/org/ergoplatform/nodeView/history/NonVerifyADHistorySpecification.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/history/NonVerifyADHistorySpecification.scala
@@ -6,6 +6,7 @@ import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.history.popow.NipopowAlgos
import org.ergoplatform.modifiers.history.HeaderChain
import org.ergoplatform.nodeView.state.StateType
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.settings.Algos
import org.ergoplatform.utils.HistoryTestHelpers
import scorex.crypto.hash.Digest32
@@ -268,7 +269,7 @@ class NonVerifyADHistorySpecification extends HistoryTestHelpers {
val chain = genHeaderChain(BlocksInChain, history, diffBitsOpt = None, useRealTs = false)
chain.headers.foreach { header =>
- val inHeight = history.heightOf(header.parentId).getOrElse(ErgoHistory.EmptyHistoryHeight)
+ val inHeight = history.heightOf(header.parentId).getOrElse(EmptyHistoryHeight)
history.contains(header) shouldBe false
history.applicable(header) shouldBe true
diff --git a/src/test/scala/org/ergoplatform/nodeView/history/UtxoSetSnapshotProcessorSpecification.scala b/src/test/scala/org/ergoplatform/nodeView/history/UtxoSetSnapshotProcessorSpecification.scala
index 3903251054..3d93a5f0ad 100644
--- a/src/test/scala/org/ergoplatform/nodeView/history/UtxoSetSnapshotProcessorSpecification.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/history/UtxoSetSnapshotProcessorSpecification.scala
@@ -1,6 +1,7 @@
package org.ergoplatform.nodeView.history
import org.ergoplatform.nodeView.history.storage.HistoryStorage
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.nodeView.history.storage.modifierprocessors.UtxoSetSnapshotProcessor
import org.ergoplatform.nodeView.state.{StateType, UtxoState}
import org.ergoplatform.settings.{Algos, ErgoSettings}
@@ -19,7 +20,7 @@ class UtxoSetSnapshotProcessorSpecification extends HistoryTestHelpers {
val epochLength = 20
val utxoSetSnapshotProcessor = new UtxoSetSnapshotProcessor {
- var minimalFullBlockHeightVar = ErgoHistory.GenesisHeight
+ var minimalFullBlockHeightVar = GenesisHeight
override protected val settings: ErgoSettings = s.copy(chainSettings =
s.chainSettings.copy(voting = s.chainSettings.voting.copy(votingLength = epochLength)))
override protected val historyStorage: HistoryStorage = HistoryStorage(settings)
diff --git a/src/test/scala/org/ergoplatform/nodeView/history/VerifyADHistorySpecification.scala b/src/test/scala/org/ergoplatform/nodeView/history/VerifyADHistorySpecification.scala
index 0240d00afb..0a645b56a4 100644
--- a/src/test/scala/org/ergoplatform/nodeView/history/VerifyADHistorySpecification.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/history/VerifyADHistorySpecification.scala
@@ -3,6 +3,7 @@ package org.ergoplatform.nodeView.history
import org.ergoplatform.modifiers.history.extension.Extension
import org.ergoplatform.modifiers.history.HeaderChain
import org.ergoplatform.modifiers.history.header.Header
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.modifiers.{ErgoFullBlock, BlockSection}
import org.ergoplatform.nodeView.ErgoModifiersCache
import org.ergoplatform.nodeView.state.StateType
@@ -19,7 +20,7 @@ class VerifyADHistorySpecification extends HistoryTestHelpers with NoShrink {
type PM = BlockSection
private def genHistory(blocksNum: Int = 0,
- minFullHeight: Option[Int] = Some(ErgoHistory.GenesisHeight)): (ErgoHistory, Seq[ErgoFullBlock]) = {
+ minFullHeight: Option[Int] = Some(GenesisHeight)): (ErgoHistory, Seq[ErgoFullBlock]) = {
val inHistory = generateHistory(verifyTransactions = true, StateType.Digest, PoPoWBootstrap = false, BlocksToKeep)
minFullHeight.foreach { h =>
inHistory.writeMinimalFullBlockHeight(h)
diff --git a/src/test/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexerSpecification.scala b/src/test/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexerSpecification.scala
index a377e8a2e7..4bbab55b42 100644
--- a/src/test/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexerSpecification.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexerSpecification.scala
@@ -11,9 +11,10 @@ import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.history.popow.NipopowAlgos
import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction}
import org.ergoplatform.nodeView.history.ErgoHistory
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.nodeView.history.extra.IndexedErgoAddressSerializer.hashErgoTree
import org.ergoplatform.nodeView.history.extra.SegmentSerializer.{boxSegmentId, txSegmentId}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.SortingOption
+import org.ergoplatform.nodeView.mempool.ErgoMemPoolTypes.SortingOption
import org.ergoplatform.nodeView.state._
import org.ergoplatform.settings.{ErgoSettings, NetworkType, NipopowSettings, NodeConfigurationSettings, UtxoSettings}
import org.ergoplatform.utils.{ErgoPropertyTest, ErgoTestHelpers, HistoryTestHelpers}
@@ -310,7 +311,7 @@ object ChainGenerator extends ErgoTestHelpers {
acc: Seq[ModifierId])(history: ErgoHistory): Seq[ModifierId] = {
val time: Long = last.map(_.timestamp + blockInterval.toMillis).getOrElse(startTime)
if (time < System.currentTimeMillis()) {
- val (txs, lastOut) = genTransactions(last.map(_.height).getOrElse(ErgoHistory.GenesisHeight),
+ val (txs, lastOut) = genTransactions(last.map(_.height).getOrElse(GenesisHeight),
initBox, state.stateContext)
val candidate = genCandidate(defaultProver.hdPubKeys.head.key, last, time, txs, state)(history)
diff --git a/src/test/scala/org/ergoplatform/nodeView/history/storage/HistoryStorageSpec.scala b/src/test/scala/org/ergoplatform/nodeView/history/storage/HistoryStorageSpec.scala
index 7020d1fee7..bd83682256 100644
--- a/src/test/scala/org/ergoplatform/nodeView/history/storage/HistoryStorageSpec.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/history/storage/HistoryStorageSpec.scala
@@ -3,7 +3,7 @@ package org.ergoplatform.nodeView.history.storage
import org.ergoplatform.modifiers.BlockSection
import org.ergoplatform.modifiers.history.ADProofs
import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.nodeView.history.ErgoHistory
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.settings.Algos
import org.ergoplatform.utils.HistoryTestHelpers
import org.scalacheck.Gen
@@ -17,7 +17,7 @@ class HistoryStorageSpec extends HistoryTestHelpers {
property("Write Read Remove") {
val headers: Array[Header] = Gen.listOfN(20, defaultHeaderGen).sample.get.toArray
val modifiers: Array[ADProofs] = Gen.listOfN(20, randomADProofsGen).sample.get.toArray
- def validityKey(id: ModifierId) = ByteArrayWrapper(Algos.hash("validity".getBytes(ErgoHistory.CharsetName) ++ idToBytes(id)))
+ def validityKey(id: ModifierId) = ByteArrayWrapper(Algos.hash("validity".getBytes(CharsetName) ++ idToBytes(id)))
val indexes = headers.flatMap(h => Array(validityKey(h.id) -> Array(1.toByte)))
db.insert(indexes, (headers ++ modifiers).asInstanceOf[Array[BlockSection]]) shouldBe 'success
diff --git a/src/test/scala/org/ergoplatform/nodeView/mempool/ErgoMemPoolSpec.scala b/src/test/scala/org/ergoplatform/nodeView/mempool/ErgoMemPoolSpec.scala
index 38aaa799d3..159129b456 100644
--- a/src/test/scala/org/ergoplatform/nodeView/mempool/ErgoMemPoolSpec.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/mempool/ErgoMemPoolSpec.scala
@@ -1,9 +1,8 @@
package org.ergoplatform.nodeView.mempool
import org.ergoplatform.{ErgoBoxCandidate, Input}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.SortingOption
+import org.ergoplatform.nodeView.mempool.ErgoMemPoolTypes.{SortingOption, ProcessingOutcome}
import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.ProcessingOutcome
import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
import org.ergoplatform.settings.ErgoSettings
import org.ergoplatform.utils.ErgoTestHelpers
diff --git a/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala b/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala
index e166806043..5eaf57d740 100644
--- a/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala
@@ -4,7 +4,7 @@ import org.ergoplatform.modifiers.ErgoFullBlock
import org.ergoplatform.modifiers.history.BlockTransactions
import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.settings.{Args, ErgoSettings}
+import org.ergoplatform.settings.{Args, ErgoSettingsReader}
import org.ergoplatform.utils.{ErgoPropertyTest, RandomWrapper}
import org.ergoplatform.wallet.boxes.ErgoBoxSerializer
import org.scalacheck.Gen
@@ -66,7 +66,7 @@ class ErgoStateSpecification extends ErgoPropertyTest {
}
property("generateGenesisUtxoState & generateGenesisDigestState are compliant") {
- val settings = ErgoSettings.read(Args.empty)
+ val settings = ErgoSettingsReader.read(Args.empty)
val dir = createTempDir
val rootHash = createUtxoState(settings)._1.rootDigest
val expectedRootHash = ErgoState.generateGenesisDigestState(dir, settings).rootDigest
diff --git a/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala b/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala
index e3dc146a8c..1811e9b1d3 100644
--- a/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala
@@ -9,7 +9,7 @@ import org.ergoplatform.modifiers.history.extension.Extension
import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.history.{ADProofs, BlockTransactions}
import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction}
-import org.ergoplatform.nodeView.history.ErgoHistory
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
import org.ergoplatform.settings.Constants
import org.ergoplatform.utils.{ErgoPropertyTest, RandomWrapper}
@@ -62,7 +62,7 @@ class UtxoStateSpecification extends ErgoPropertyTest with ErgoTransactionGenera
property("Founders should be able to spend genesis founders box") {
var (us, bh) = createUtxoState(settings)
val foundersBox = genesisBoxes.last
- var height: Int = ErgoHistory.GenesisHeight
+ var height: Int = GenesisHeight
val settingsPks = settings.chainSettings.foundersPubkeys
.map(str => groupElemFromBytes(Base16.decode(str).get))
@@ -160,7 +160,7 @@ class UtxoStateSpecification extends ErgoPropertyTest with ErgoTransactionGenera
property("proofsForTransactions") {
var (us: UtxoState, bh) = createUtxoState(settings)
- var height: Int = ErgoHistory.GenesisHeight
+ var height: Int = GenesisHeight
forAll(defaultHeaderGen) { header =>
val t = validTransactionsFromBoxHolder(bh, new RandomWrapper(Some(height)))
val txs = t._1
@@ -184,7 +184,7 @@ class UtxoStateSpecification extends ErgoPropertyTest with ErgoTransactionGenera
var bh = BoxHolder(Seq(genesisEmissionBox))
var us = createUtxoState(bh, parameters)
- var height: Int = ErgoHistory.GenesisHeight
+ var height: Int = GenesisHeight
// generate chain of correct full blocks
val chain = (0 until 10) map { _ =>
val header = defaultHeaderGen.sample.value
diff --git a/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedDigestState.scala b/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedDigestState.scala
index fe1933fad9..765e0b2444 100644
--- a/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedDigestState.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedDigestState.scala
@@ -1,6 +1,6 @@
package org.ergoplatform.nodeView.state.wrapped
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedModifier
+import org.ergoplatform.nodeView.ErgoNodeViewHolderLocallyGeneratedModifier._
import org.ergoplatform.ErgoLikeContext.Height
import org.ergoplatform.modifiers.BlockSection
import org.ergoplatform.nodeView.state.DigestState
diff --git a/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedUtxoState.scala b/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedUtxoState.scala
index d747a4b5be..114d6a1243 100644
--- a/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedUtxoState.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/state/wrapped/WrappedUtxoState.scala
@@ -4,7 +4,7 @@ import java.io.File
import akka.actor.ActorRef
import org.ergoplatform.ErgoBox
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedModifier
+import org.ergoplatform.nodeView.ErgoNodeViewHolderLocallyGeneratedModifier._
import org.ergoplatform.ErgoLikeContext.Height
import org.ergoplatform.modifiers.BlockSection
import org.ergoplatform.nodeView.state._
diff --git a/src/test/scala/org/ergoplatform/nodeView/viewholder/ErgoNodeViewHolderSpec.scala b/src/test/scala/org/ergoplatform/nodeView/viewholder/ErgoNodeViewHolderSpec.scala
index 83e9243ad9..93f1563d58 100644
--- a/src/test/scala/org/ergoplatform/nodeView/viewholder/ErgoNodeViewHolderSpec.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/viewholder/ErgoNodeViewHolderSpec.scala
@@ -4,17 +4,18 @@ import java.io.File
import org.ergoplatform.ErgoBoxCandidate
import org.ergoplatform.modifiers.ErgoFullBlock
import org.ergoplatform.modifiers.mempool.UnconfirmedTransaction
-import org.ergoplatform.nodeView.history.ErgoHistory
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.nodeView.state.StateType.Utxo
import org.ergoplatform.nodeView.state._
import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
import org.ergoplatform.settings.{Algos, Constants, ErgoSettings}
import org.ergoplatform.utils.{ErgoPropertyTest, HistoryTestHelpers, NodeViewTestConfig, NodeViewTestOps, TestCase}
import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages._
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages._
+import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages._
import org.ergoplatform.nodeView.ErgoNodeViewHolder
import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.ChainProgress
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.ProcessingOutcome.Accepted
+import org.ergoplatform.nodeView.ErgoNodeViewHolderLocallyGeneratedModifier.LocallyGeneratedModifier
+import org.ergoplatform.nodeView.mempool.ErgoMemPoolTypes.ProcessingOutcome.Accepted
import scorex.crypto.authds.{ADKey, SerializedAdProof}
import scorex.testkit.utils.NoShrink
import scorex.util.{ModifierId, bytesToId}
@@ -55,7 +56,7 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
val block = validFullBlock(None, us, bh)
getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
+ getHistoryHeight shouldBe EmptyHistoryHeight
subscribeEvents(classOf[SyntacticallySuccessfulModifier])
@@ -63,8 +64,8 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
nodeViewHolderRef ! LocallyGeneratedModifier(block.header)
expectMsgType[SyntacticallySuccessfulModifier]
- getHistoryHeight shouldBe ErgoHistory.GenesisHeight
- getHeightOf(block.header.id) shouldBe Some(ErgoHistory.GenesisHeight)
+ getHistoryHeight shouldBe GenesisHeight
+ getHeightOf(block.header.id) shouldBe Some(GenesisHeight)
getLastHeadersLength(10) shouldBe 1
getBestHeaderOpt shouldBe Some(block.header)
}
@@ -76,7 +77,7 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
val block = validFullBlock(Some(parentBlock), us, bh)
getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
+ getHistoryHeight shouldBe EmptyHistoryHeight
subscribeEvents(classOf[SyntacticallySuccessfulModifier])
@@ -317,7 +318,7 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
val (us, bh) = createUtxoState(fixture.settings)
val block = validFullBlock(None, us, bh)
getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
+ getHistoryHeight shouldBe EmptyHistoryHeight
subscribeEvents(classOf[RecoverableFailedModification])
subscribeEvents(classOf[SyntacticallySuccessfulModifier])
@@ -327,8 +328,8 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
nodeViewHolderRef ! LocallyGeneratedModifier(block.header)
expectMsgType[SyntacticallySuccessfulModifier]
val currentHeight = getHistoryHeight
- currentHeight shouldBe ErgoHistory.GenesisHeight
- getHeightOf(block.header.id) shouldBe Some(ErgoHistory.GenesisHeight)
+ currentHeight shouldBe GenesisHeight
+ getHeightOf(block.header.id) shouldBe Some(GenesisHeight)
val randomId = modifierIdGen.sample.value
val recoverableTxs = block.blockTransactions.copy(headerId = randomId)
@@ -371,7 +372,7 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
val block = validFullBlock(None, us, bh)
getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
+ getHistoryHeight shouldBe EmptyHistoryHeight
subscribeEvents(classOf[RecoverableFailedModification])
subscribeEvents(classOf[SyntacticallySuccessfulModifier])
@@ -404,7 +405,7 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
val block = validFullBlock(None, us, bh)
getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
+ getHistoryHeight shouldBe EmptyHistoryHeight
subscribeEvents(classOf[RecoverableFailedModification])
subscribeEvents(classOf[SyntacticallySuccessfulModifier])
@@ -414,7 +415,7 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
nodeViewHolderRef ! LocallyGeneratedModifier(block.header)
expectMsgType[SyntacticallyFailedModification]
getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
+ getHistoryHeight shouldBe EmptyHistoryHeight
}
private val t15 = TestCase("apply genesis block header if it's equal to genesisId from config") { fixture =>
@@ -424,7 +425,7 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
updateConfig(genesisIdConfig(Some(block.header.id)))
getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
+ getHistoryHeight shouldBe EmptyHistoryHeight
subscribeEvents(classOf[RecoverableFailedModification])
subscribeEvents(classOf[SyntacticallySuccessfulModifier])
@@ -432,8 +433,8 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
nodeViewHolderRef ! LocallyGeneratedModifier(block.header)
expectMsgType[SyntacticallySuccessfulModifier]
- getHistoryHeight shouldBe ErgoHistory.GenesisHeight
- getHeightOf(block.header.id) shouldBe Some(ErgoHistory.GenesisHeight)
+ getHistoryHeight shouldBe GenesisHeight
+ getHeightOf(block.header.id) shouldBe Some(GenesisHeight)
}
private val t16 = TestCase("apply forks that include genesis block") { fixture =>
@@ -473,7 +474,7 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
val header = validFullBlock(None, us, bh).header.copy(parentId = bytesToId(Array.fill(32)(9: Byte)))
getBestHeaderOpt shouldBe None
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
+ getHistoryHeight shouldBe EmptyHistoryHeight
subscribeEvents(classOf[RecoverableFailedModification])
subscribeEvents(classOf[SyntacticallySuccessfulModifier])
@@ -481,7 +482,7 @@ class ErgoNodeViewHolderSpec extends ErgoPropertyTest with HistoryTestHelpers wi
nodeViewHolderRef ! LocallyGeneratedModifier(header)
expectMsgType[SyntacticallyFailedModification]
- getHistoryHeight shouldBe ErgoHistory.EmptyHistoryHeight
+ getHistoryHeight shouldBe EmptyHistoryHeight
getHeightOf(header.id) shouldBe None
}
diff --git a/src/test/scala/org/ergoplatform/nodeView/viewholder/PrunedNodeViewHolderSpec.scala b/src/test/scala/org/ergoplatform/nodeView/viewholder/PrunedNodeViewHolderSpec.scala
index 621a2119dd..7572e87ded 100644
--- a/src/test/scala/org/ergoplatform/nodeView/viewholder/PrunedNodeViewHolderSpec.scala
+++ b/src/test/scala/org/ergoplatform/nodeView/viewholder/PrunedNodeViewHolderSpec.scala
@@ -5,10 +5,10 @@ import org.ergoplatform.mining.DefaultFakePowScheme
import org.ergoplatform.modifiers.ErgoFullBlock
import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
import org.ergoplatform.nodeView.state.{DigestState, StateType}
-import org.ergoplatform.settings.{ErgoSettings, VotingSettings}
+import org.ergoplatform.settings.{ErgoSettings, ErgoSettingsReader, VotingSettings}
import org.ergoplatform.utils.fixtures.NodeViewFixture
import org.ergoplatform.utils.{ErgoPropertyTest, NodeViewTestOps}
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedModifier
+import org.ergoplatform.nodeView.ErgoNodeViewHolderLocallyGeneratedModifier._
import scorex.testkit.utils.NoShrink
import scala.concurrent.duration._
@@ -20,7 +20,7 @@ class PrunedNodeViewHolderSpec extends ErgoPropertyTest with NodeViewTestOps wit
private val BlockInterval = 2.minutes
def prunedSettings(blocksToKeep: Int): ErgoSettings = {
- val defaultSettings = ErgoSettings.read()
+ val defaultSettings = ErgoSettingsReader.read()
defaultSettings.copy(
chainSettings = defaultSettings.chainSettings.copy(
powScheme = new DefaultFakePowScheme(defaultSettings.chainSettings.powScheme.k, defaultSettings.chainSettings.powScheme.n),
diff --git a/src/test/scala/org/ergoplatform/sanity/ErgoSanityDigest.scala b/src/test/scala/org/ergoplatform/sanity/ErgoSanityDigest.scala
index d9b07a50e7..8a20ca97f2 100644
--- a/src/test/scala/org/ergoplatform/sanity/ErgoSanityDigest.scala
+++ b/src/test/scala/org/ergoplatform/sanity/ErgoSanityDigest.scala
@@ -5,14 +5,14 @@ import akka.testkit.TestProbe
import org.ergoplatform.modifiers.ErgoFullBlock
import org.ergoplatform.modifiers.history.BlockTransactions
import org.ergoplatform.modifiers.history.header.HeaderSerializer
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.{ChangedHistory, ChangedMempool}
+import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages.{ChangedHistory, ChangedMempool}
import org.ergoplatform.network.ErgoSyncTracker
import org.ergoplatform.nodeView.history.ErgoSyncInfoMessageSpec
import org.ergoplatform.nodeView.mempool.ErgoMemPool
import org.ergoplatform.nodeView.state.wrapped.{WrappedDigestState, WrappedUtxoState}
import org.ergoplatform.nodeView.state.{DigestState, StateType}
import org.ergoplatform.sanity.ErgoSanity._
-import org.ergoplatform.settings.ErgoSettings
+import org.ergoplatform.settings.ErgoSettingsReader
import org.scalacheck.Gen
import scorex.core.idToBytes
import scorex.core.network.{ConnectedPeer, DeliveryTracker}
@@ -58,7 +58,7 @@ class ErgoSanityDigest extends ErgoSanity[DIGEST_ST] {
val h = historyGen.sample.get
@SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
val s = stateGen.sample.get
- val settings = ErgoSettings.read()
+ val settings = ErgoSettingsReader.read()
val pool = ErgoMemPool.empty(settings)
val v = h.bestFullBlockIdOpt.orElse(h.bestHeaderIdOpt)
v.foreach(id => s.store.update(idToBytes(id), Seq(), Seq()).get)
diff --git a/src/test/scala/org/ergoplatform/sanity/ErgoSanityUTXO.scala b/src/test/scala/org/ergoplatform/sanity/ErgoSanityUTXO.scala
index ef6107e35b..2653a195cb 100644
--- a/src/test/scala/org/ergoplatform/sanity/ErgoSanityUTXO.scala
+++ b/src/test/scala/org/ergoplatform/sanity/ErgoSanityUTXO.scala
@@ -5,14 +5,14 @@ import akka.testkit.TestProbe
import org.ergoplatform.modifiers.ErgoFullBlock
import org.ergoplatform.modifiers.history.BlockTransactions
import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages.{ChangedHistory, ChangedMempool}
+import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages.{ChangedHistory, ChangedMempool}
import org.ergoplatform.network.ErgoSyncTracker
import org.ergoplatform.nodeView.history.ErgoSyncInfoMessageSpec
import org.ergoplatform.nodeView.mempool.ErgoMemPool
import org.ergoplatform.nodeView.state.StateType
import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
import org.ergoplatform.sanity.ErgoSanity._
-import org.ergoplatform.settings.ErgoSettings
+import org.ergoplatform.settings.ErgoSettingsReader
import org.ergoplatform.utils.ErgoTestHelpers
import org.scalacheck.Gen
import scorex.core.network.{ConnectedPeer, DeliveryTracker}
@@ -55,7 +55,7 @@ class ErgoSanityUTXO extends ErgoSanity[UTXO_ST] with ErgoTestHelpers {
val h = historyGen.sample.get
@SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
val s = stateGen.sample.get
- val settings = ErgoSettings.read()
+ val settings = ErgoSettingsReader.read()
val pool = ErgoMemPool.empty(settings)
implicit val ec: ExecutionContextExecutor = system.dispatcher
val ncProbe = TestProbe("NetworkControllerProbe")
diff --git a/src/test/scala/org/ergoplatform/serialization/JsonSerializationSpec.scala b/src/test/scala/org/ergoplatform/serialization/JsonSerializationSpec.scala
index 016696d708..f0be0e97a2 100644
--- a/src/test/scala/org/ergoplatform/serialization/JsonSerializationSpec.scala
+++ b/src/test/scala/org/ergoplatform/serialization/JsonSerializationSpec.scala
@@ -4,7 +4,7 @@ import io.circe.syntax._
import io.circe.{ACursor, Decoder, Encoder, Json}
import org.ergoplatform.ErgoBox
import org.ergoplatform.ErgoBox.{AdditionalRegisters, NonMandatoryRegisterId}
-import org.ergoplatform.http.api.ApiCodecs
+import org.ergoplatform.http.api.{ApiCodecs, ApiNodeViewCodecs}
import org.ergoplatform.http.api.ApiEncoderOption.HideDetails.implicitValue
import org.ergoplatform.http.api.ApiEncoderOption.{Detalization, ShowDetails}
import org.ergoplatform.modifiers.ErgoFullBlock
@@ -12,7 +12,7 @@ import org.ergoplatform.modifiers.history.popow.NipopowProof
import org.ergoplatform.modifiers.mempool.UnsignedErgoTransaction
import org.ergoplatform.nodeView.wallet.requests._
import org.ergoplatform.sdk.wallet.secrets.{DhtSecretKey, DlogSecretKey}
-import org.ergoplatform.settings.{Algos, ErgoSettings}
+import org.ergoplatform.settings.{Algos, ErgoSettingsReader}
import org.ergoplatform.utils.ErgoPropertyTest
import org.ergoplatform.utils.generators.WalletGenerators
import org.ergoplatform.wallet.Constants.ScanId
@@ -24,7 +24,7 @@ import sigmastate.Values.{ErgoTree, EvaluatedValue}
import scala.util.Random
-class JsonSerializationSpec extends ErgoPropertyTest with WalletGenerators with ApiCodecs {
+class JsonSerializationSpec extends ErgoPropertyTest with WalletGenerators with ApiCodecs with ApiNodeViewCodecs {
property("ErgoFullBlock should be encoded into JSON and decoded back correctly") {
@@ -52,7 +52,7 @@ class JsonSerializationSpec extends ErgoPropertyTest with WalletGenerators with
}
property("PaymentRequest should be serialized to json") {
- val ergoSettings = ErgoSettings.read()
+ val ergoSettings = ErgoSettingsReader.read()
implicit val requestEncoder: Encoder[PaymentRequest] = new PaymentRequestEncoder(ergoSettings)
implicit val requestDecoder: Decoder[PaymentRequest] = new PaymentRequestDecoder(ergoSettings)
forAll(paymentRequestGen) { request =>
@@ -88,7 +88,7 @@ class JsonSerializationSpec extends ErgoPropertyTest with WalletGenerators with
}
property("AssetIssueRequest should be serialized to json") {
- val ergoSettings = ErgoSettings.read()
+ val ergoSettings = ErgoSettingsReader.read()
implicit val requestEncoder: Encoder[AssetIssueRequest] = new AssetIssueRequestEncoder(ergoSettings)
implicit val requestDecoder: Decoder[AssetIssueRequest] = new AssetIssueRequestDecoder(ergoSettings)
forAll(assetIssueRequestGen) { request =>
diff --git a/src/test/scala/org/ergoplatform/serialization/SerializationTests.scala b/src/test/scala/org/ergoplatform/serialization/SerializationTests.scala
index a792c82c3e..be26e2d5e3 100644
--- a/src/test/scala/org/ergoplatform/serialization/SerializationTests.scala
+++ b/src/test/scala/org/ergoplatform/serialization/SerializationTests.scala
@@ -6,10 +6,11 @@ import org.ergoplatform.modifiers.history.extension.ExtensionSerializer
import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer}
import org.ergoplatform.modifiers.history.popow.NipopowProofSerializer
import org.ergoplatform.modifiers.mempool.ErgoTransactionSerializer
+import org.ergoplatform.network.ErgoNodeViewSynchronizer
import org.ergoplatform.nodeView.history.ErgoSyncInfoSerializer
import org.ergoplatform.nodeView.wallet.persistence.WalletDigestSerializer
import org.ergoplatform.nodeView.state.ErgoStateContextSerializer
-import org.ergoplatform.settings.{Constants, ErgoValidationSettings, ErgoValidationSettingsSerializer, ErgoValidationSettingsUpdateSerializer}
+import org.ergoplatform.settings.{ErgoValidationSettings, ErgoValidationSettingsSerializer, ErgoValidationSettingsUpdateSerializer}
import org.ergoplatform.utils.ErgoPropertyTest
import org.ergoplatform.utils.generators.WalletGenerators
import org.scalacheck.Gen
@@ -30,7 +31,7 @@ class SerializationTests extends ErgoPropertyTest with WalletGenerators with sco
property("Serializers should be defined for all block sections") {
val block = invalidErgoFullBlockGen.sample.get
block.toSeq.foreach { s =>
- Constants.modifierSerializers.get(s.modifierTypeId) should not be None
+ ErgoNodeViewSynchronizer.modifierSerializers.get(s.modifierTypeId) should not be None
}
}
diff --git a/src/test/scala/org/ergoplatform/settings/ErgoSettingsSpecification.scala b/src/test/scala/org/ergoplatform/settings/ErgoSettingsSpecification.scala
index e222ec2d88..fe815bd734 100644
--- a/src/test/scala/org/ergoplatform/settings/ErgoSettingsSpecification.scala
+++ b/src/test/scala/org/ergoplatform/settings/ErgoSettingsSpecification.scala
@@ -1,6 +1,6 @@
package org.ergoplatform.settings
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.SortingOption
+import org.ergoplatform.nodeView.mempool.ErgoMemPoolTypes.SortingOption
import org.ergoplatform.nodeView.state.StateType
import org.ergoplatform.utils.ErgoPropertyTest
import scorex.core.settings.RESTApiSettings
@@ -14,12 +14,12 @@ class ErgoSettingsSpecification extends ErgoPropertyTest {
private val txSizeLimit = initSettings.nodeSettings.maxTransactionSize
property("should keep data user home by default") {
- val settings = ErgoSettings.read()
+ val settings = ErgoSettingsReader.read()
settings.directory shouldBe System.getProperty("user.dir") + "/.ergo_test/data"
}
property("should read default settings") {
- val settings = ErgoSettings.read()
+ val settings = ErgoSettingsReader.read()
settings.nodeSettings shouldBe NodeConfigurationSettings(
StateType.Utxo,
verifyTransactions = true,
@@ -68,7 +68,7 @@ class ErgoSettingsSpecification extends ErgoPropertyTest {
}
property("should read user settings from json file") {
- val settings = ErgoSettings.read(Args(Some("src/test/resources/settings.json"), None))
+ val settings = ErgoSettingsReader.read(Args(Some("src/test/resources/settings.json"), None))
settings.nodeSettings shouldBe NodeConfigurationSettings(
StateType.Utxo,
verifyTransactions = true,
@@ -110,7 +110,7 @@ class ErgoSettingsSpecification extends ErgoPropertyTest {
}
property("should read user settings from HOCON file") {
- val settings = ErgoSettings.read(Args(Some("src/test/resources/settings.conf"), None))
+ val settings = ErgoSettingsReader.read(Args(Some("src/test/resources/settings.conf"), None))
settings.nodeSettings shouldBe NodeConfigurationSettings(
StateType.Utxo,
verifyTransactions = true,
@@ -162,7 +162,7 @@ class ErgoSettingsSpecification extends ErgoPropertyTest {
"http://example.com?foo=bar"
).map(new URL(_))
- invalidUrls.forall(ErgoSettings.invalidRestApiUrl) shouldBe true
+ invalidUrls.forall(ErgoSettingsReader.invalidRestApiUrl) shouldBe true
val validUrls =
List(
@@ -172,7 +172,7 @@ class ErgoSettingsSpecification extends ErgoPropertyTest {
"http://82.90.21.31:80"
).map(new URL(_))
- validUrls.forall(url => !ErgoSettings.invalidRestApiUrl(url)) shouldBe true
+ validUrls.forall(url => !ErgoSettingsReader.invalidRestApiUrl(url)) shouldBe true
}
}
diff --git a/src/test/scala/org/ergoplatform/tools/ChainGenerator.scala b/src/test/scala/org/ergoplatform/tools/ChainGenerator.scala
index 7fb07b62f9..a4b4f81fca 100644
--- a/src/test/scala/org/ergoplatform/tools/ChainGenerator.scala
+++ b/src/test/scala/org/ergoplatform/tools/ChainGenerator.scala
@@ -9,8 +9,8 @@ import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.history.popow.NipopowAlgos
import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction}
import org.ergoplatform.nodeView.history.ErgoHistory
-import org.ergoplatform.nodeView.history.ErgoHistory.Height
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.SortingOption
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
+import org.ergoplatform.nodeView.mempool.ErgoMemPoolTypes.SortingOption
import org.ergoplatform.nodeView.state._
import org.ergoplatform.settings._
import org.ergoplatform.utils.{ErgoTestHelpers, HistoryTestHelpers}
@@ -32,7 +32,7 @@ import scala.util.Try
object ChainGenerator extends App with ErgoTestHelpers {
val realNetworkSetting = {
- val initSettings = ErgoSettings.read(Args(None, Some(NetworkType.TestNet)))
+ val initSettings = ErgoSettingsReader.read(Args(None, Some(NetworkType.TestNet)))
initSettings.copy(chainSettings = initSettings.chainSettings.copy(genesisId = None))
}
@@ -94,7 +94,7 @@ object ChainGenerator extends App with ErgoTestHelpers {
acc: Seq[ModifierId]): Seq[ModifierId] = {
val time: Long = last.map(_.timestamp + blockInterval.toMillis).getOrElse(startTime)
if (time < System.currentTimeMillis()) {
- val (txs, lastOut) = genTransactions(last.map(_.height).getOrElse(ErgoHistory.GenesisHeight),
+ val (txs, lastOut) = genTransactions(last.map(_.height).getOrElse(GenesisHeight),
initBox, state.stateContext)
val candidate = genCandidate(prover.hdPubKeys.head.key, last, time, txs, state)
diff --git a/src/test/scala/org/ergoplatform/tools/DifficultyControlSimulator.scala b/src/test/scala/org/ergoplatform/tools/DifficultyControlSimulator.scala
index 8c38a167e4..bcb0a8ff64 100644
--- a/src/test/scala/org/ergoplatform/tools/DifficultyControlSimulator.scala
+++ b/src/test/scala/org/ergoplatform/tools/DifficultyControlSimulator.scala
@@ -2,8 +2,8 @@ package org.ergoplatform.tools
import org.ergoplatform.mining.difficulty.{DifficultyAdjustment, DifficultySerializer}
import org.ergoplatform.modifiers.history.header.Header
-import org.ergoplatform.nodeView.history.ErgoHistory.Difficulty
-import org.ergoplatform.settings.ErgoSettings
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants.Difficulty
+import org.ergoplatform.settings.ErgoSettingsReader
import org.ergoplatform.utils.generators.ErgoGenerators
import scala.annotation.tailrec
@@ -86,7 +86,7 @@ object DifficultyControlSimulator extends App with ErgoGenerators {
def printTestnetData(): Unit = {
val baseHeader = defaultHeaderGen.sample.get
- val chainSettings = ErgoSettings.read().chainSettings.copy(epochLength = 1)
+ val chainSettings = ErgoSettingsReader.read().chainSettings.copy(epochLength = 1)
val difficultyControl = new DifficultyAdjustment(chainSettings)
val headers = Source.fromResource("difficulty.csv").getLines().toSeq.tail.map { line =>
diff --git a/src/test/scala/org/ergoplatform/utils/ErgoTestConstants.scala b/src/test/scala/org/ergoplatform/utils/ErgoTestConstants.scala
index 302ac4aac5..ff3227256a 100644
--- a/src/test/scala/org/ergoplatform/utils/ErgoTestConstants.scala
+++ b/src/test/scala/org/ergoplatform/utils/ErgoTestConstants.scala
@@ -46,7 +46,7 @@ trait ErgoTestConstants extends ScorexLogging {
Parameters(0, Parameters.DefaultParameters ++ extension, ErgoValidationSettingsUpdate.empty)
}
- val initSettings: ErgoSettings = ErgoSettings.read(Args(Some("src/test/resources/application.conf"), None))
+ val initSettings: ErgoSettings = ErgoSettingsReader.read(Args(Some("src/test/resources/application.conf"), None))
implicit val settings: ErgoSettings = initSettings
diff --git a/src/test/scala/org/ergoplatform/utils/HistoryTestHelpers.scala b/src/test/scala/org/ergoplatform/utils/HistoryTestHelpers.scala
index b38d920120..fc158d2f64 100644
--- a/src/test/scala/org/ergoplatform/utils/HistoryTestHelpers.scala
+++ b/src/test/scala/org/ergoplatform/utils/HistoryTestHelpers.scala
@@ -1,8 +1,9 @@
package org.ergoplatform.utils
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.nodeView.history.ErgoHistory
import org.ergoplatform.nodeView.history.storage.modifierprocessors.{EmptyBlockSectionProcessor, FullBlockPruningProcessor, ToDownloadProcessor}
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.SortingOption
+import org.ergoplatform.nodeView.mempool.ErgoMemPoolTypes.SortingOption
import org.ergoplatform.nodeView.state.StateType
import org.ergoplatform.settings._
import org.scalacheck.Gen
@@ -84,7 +85,7 @@ object HistoryTestHelpers {
val ppM = ru.typeOf[ToDownloadProcessor].member(ru.TermName("pruningProcessor")).asMethod
val pp = procInstance.reflectMethod(ppM).apply().asInstanceOf[FullBlockPruningProcessor]
val f = ru.typeOf[FullBlockPruningProcessor].member(ru.TermName("minimalFullBlockHeightVar")).asTerm.accessed.asTerm
- runtimeMirror.reflect(pp).reflectField(f).set(ErgoHistory.GenesisHeight)
+ runtimeMirror.reflect(pp).reflectField(f).set(GenesisHeight)
val f2 = ru.typeOf[FullBlockPruningProcessor].member(ru.TermName("isHeadersChainSyncedVar")).asTerm.accessed.asTerm
runtimeMirror.reflect(pp).reflectField(f2).set(true)
}
diff --git a/src/test/scala/org/ergoplatform/utils/NodeViewTestConfig.scala b/src/test/scala/org/ergoplatform/utils/NodeViewTestConfig.scala
index 8df386a697..3b708d9d06 100644
--- a/src/test/scala/org/ergoplatform/utils/NodeViewTestConfig.scala
+++ b/src/test/scala/org/ergoplatform/utils/NodeViewTestConfig.scala
@@ -2,7 +2,7 @@ package org.ergoplatform.utils
import org.ergoplatform.mining.DefaultFakePowScheme
import org.ergoplatform.nodeView.state.StateType
-import org.ergoplatform.settings.{ErgoSettings, NipopowSettings}
+import org.ergoplatform.settings.{ErgoSettings, ErgoSettingsReader, NipopowSettings}
case class NodeViewTestConfig(stateType: StateType,
@@ -10,7 +10,7 @@ case class NodeViewTestConfig(stateType: StateType,
popowBootstrap: Boolean) {
def toSettings: ErgoSettings = {
- val defaultSettings = ErgoSettings.read()
+ val defaultSettings = ErgoSettingsReader.read()
defaultSettings.copy(
chainSettings = defaultSettings.chainSettings.copy(
powScheme = new DefaultFakePowScheme(defaultSettings.chainSettings.powScheme.k, defaultSettings.chainSettings.powScheme.n)
diff --git a/src/test/scala/org/ergoplatform/utils/NodeViewTestOps.scala b/src/test/scala/org/ergoplatform/utils/NodeViewTestOps.scala
index d78b852d81..aeb8fcbf71 100644
--- a/src/test/scala/org/ergoplatform/utils/NodeViewTestOps.scala
+++ b/src/test/scala/org/ergoplatform/utils/NodeViewTestOps.scala
@@ -11,8 +11,9 @@ import org.ergoplatform.nodeView.history.ErgoHistory
import org.ergoplatform.nodeView.state.{ErgoState, StateType, UtxoState}
import org.ergoplatform.settings.Algos
import org.ergoplatform.nodeView.ErgoNodeViewHolder.CurrentView
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.{GetDataFromCurrentView, LocallyGeneratedModifier}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages._
+import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.GetDataFromCurrentView
+import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages._
+import org.ergoplatform.nodeView.ErgoNodeViewHolderLocallyGeneratedModifier.LocallyGeneratedModifier
import scorex.core.validation.MalformedModifierError
import scorex.util.ModifierId
diff --git a/src/test/scala/org/ergoplatform/utils/Stubs.scala b/src/test/scala/org/ergoplatform/utils/Stubs.scala
index 556dd034ca..2369d16c2d 100644
--- a/src/test/scala/org/ergoplatform/utils/Stubs.scala
+++ b/src/test/scala/org/ergoplatform/utils/Stubs.scala
@@ -11,13 +11,13 @@ import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction}
import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedTransaction
import org.ergoplatform.nodeView.ErgoReadersHolder.{GetDataFromHistory, GetReaders, Readers}
-import org.ergoplatform.nodeView.history.ErgoHistory
+import org.ergoplatform.nodeView.history.{ErgoHistory, ErgoHistoryConstants}
import org.ergoplatform.nodeView.mempool.ErgoMemPool
-import org.ergoplatform.nodeView.mempool.ErgoMemPool.{ProcessingOutcome, SortingOption}
+import org.ergoplatform.nodeView.mempool.ErgoMemPoolTypes.{ProcessingOutcome, SortingOption}
import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
import org.ergoplatform.nodeView.state.{DigestState, ErgoStateContext, StateType}
-import org.ergoplatform.nodeView.wallet.ErgoWalletActor._
-import org.ergoplatform.nodeView.wallet.ErgoWalletService.DeriveNextKeyResult
+import org.ergoplatform.nodeView.wallet.ErgoWalletActorMessages._
+import org.ergoplatform.nodeView.wallet.ErgoWalletServiceUtils.DeriveNextKeyResult
import org.ergoplatform.nodeView.wallet._
import org.ergoplatform.nodeView.wallet.persistence.WalletDigest
import org.ergoplatform.nodeView.wallet.scanning.Scan
@@ -182,7 +182,7 @@ trait Stubs extends ErgoGenerators with ErgoTestHelpers with ChainGenerator with
case RescanWallet(_) => sender ! Success(())
- case GetWalletStatus => sender() ! WalletStatus(true, true, None, ErgoHistory.GenesisHeight, error = None)
+ case GetWalletStatus => sender() ! WalletStatus(true, true, None, ErgoHistoryConstants.GenesisHeight, error = None)
case _: CheckSeed => sender() ! true
diff --git a/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala b/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala
index 42407311f2..6c9bf3bf4b 100644
--- a/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala
+++ b/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala
@@ -5,7 +5,7 @@ import org.ergoplatform._
import org.ergoplatform.mining.CandidateGenerator
import org.ergoplatform.modifiers.ErgoFullBlock
import org.ergoplatform.modifiers.mempool.ErgoTransaction
-import org.ergoplatform.nodeView.history.ErgoHistory
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.nodeView.state.{ErgoState, UtxoState}
import org.ergoplatform.nodeView.wallet.ErgoWallet
import org.ergoplatform.nodeView.wallet.IdUtils._
@@ -86,7 +86,7 @@ trait WalletTestOps extends NodeViewBaseOps {
}
CandidateGenerator.collectRewards(Some(genesisEmissionBox),
- ErgoHistory.EmptyHistoryHeight,
+ EmptyHistoryHeight,
Seq.empty,
publicKey,
emptyStateContext,
@@ -97,7 +97,7 @@ trait WalletTestOps extends NodeViewBaseOps {
val inputs = IndexedSeq(new Input(genesisEmissionBox.id, emptyProverResult))
val assets: Seq[(TokenId, Long)] = replaceNewAssetStub(assetsIn, inputs)
CandidateGenerator.collectRewards(Some(genesisEmissionBox),
- ErgoHistory.EmptyHistoryHeight,
+ EmptyHistoryHeight,
Seq.empty,
publicKey,
emptyStateContext,
diff --git a/src/test/scala/org/ergoplatform/utils/generators/ErgoTransactionGenerators.scala b/src/test/scala/org/ergoplatform/utils/generators/ErgoTransactionGenerators.scala
index 1d210f38a0..f3cb4297ea 100644
--- a/src/test/scala/org/ergoplatform/utils/generators/ErgoTransactionGenerators.scala
+++ b/src/test/scala/org/ergoplatform/utils/generators/ErgoTransactionGenerators.scala
@@ -5,7 +5,7 @@ import org.ergoplatform.modifiers.ErgoFullBlock
import org.ergoplatform.modifiers.history.BlockTransactions
import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction}
-import org.ergoplatform.nodeView.history.ErgoHistory
+import org.ergoplatform.nodeView.history.ErgoHistoryConstants._
import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState
import org.ergoplatform.nodeView.state.{BoxHolder, ErgoStateContext, VotingData}
import org.ergoplatform.nodeView.wallet.requests.{ExternalSecret, TransactionSigningRequest}
@@ -61,7 +61,7 @@ trait ErgoTransactionGenerators extends ErgoGenerators with Generators {
def ergoBoxGenForTokens(tokens: Seq[(TokenId, Long)],
propositionGen: Gen[ErgoTree]): Gen[ErgoBox] = {
- ergoBoxGen(propGen = propositionGen, tokensGen = Gen.oneOf(tokens, tokens), heightGen = ErgoHistory.EmptyHistoryHeight)
+ ergoBoxGen(propGen = propositionGen, tokensGen = Gen.oneOf(tokens, tokens), heightGen = EmptyHistoryHeight)
}
def unspendableErgoBoxGen(minValue: Long = parameters.minValuePerByte * 200,
diff --git a/src/test/scala/scorex/testkit/properties/NodeViewHolderTests.scala b/src/test/scala/scorex/testkit/properties/NodeViewHolderTests.scala
index 775b58d8d0..6d1553c561 100644
--- a/src/test/scala/scorex/testkit/properties/NodeViewHolderTests.scala
+++ b/src/test/scala/scorex/testkit/properties/NodeViewHolderTests.scala
@@ -7,8 +7,9 @@ import org.ergoplatform.nodeView.history.ErgoHistory
import org.scalatest.matchers.should.Matchers
import org.scalatest.propspec.AnyPropSpec
import org.ergoplatform.nodeView.ErgoNodeViewHolder.CurrentView
-import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.{GetDataFromCurrentView, LocallyGeneratedModifier}
-import org.ergoplatform.network.ErgoNodeViewSynchronizer.ReceivableMessages._
+import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.GetDataFromCurrentView
+import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages._
+import org.ergoplatform.nodeView.ErgoNodeViewHolderLocallyGeneratedModifier.LocallyGeneratedModifier
import org.ergoplatform.nodeView.state.ErgoState
import scorex.testkit.generators._
import scorex.testkit.utils.AkkaFixture