diff --git a/agents/iguana b/agents/iguana deleted file mode 100755 index 90f8d12ac..000000000 Binary files a/agents/iguana and /dev/null differ diff --git a/agents/libcrypto777.a b/agents/libcrypto777.a deleted file mode 100755 index 7a71827de..000000000 Binary files a/agents/libcrypto777.a and /dev/null differ diff --git a/confs/BTCD_hdrs.txt b/confs/BTCD_hdrs.txt old mode 100755 new mode 100644 index f6fd2a2f9..482b1333d --- a/confs/BTCD_hdrs.txt +++ b/confs/BTCD_hdrs.txt @@ -1,4 +1,4 @@ -889011 +1013511 0 0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46 a5d211145f8e6ba0920b2893d307c5d7c207ae0800a80955299678d1706ea8ac 500 000000000680a9a697eb71155b18a5827e0889fca28afb81fcbb46469ed7877e 79f80a8f54c6762d6408347c6dd7dfd2f8b8c191077c1d7881dfc5b7ec6a408e 1000 0000000000000cf908c887020f8970b7fe952f8b81164d83a87621dfdb581d08 3356ec4296ff2f04281492b0dedbaed80edeb6dd9170b87230ff79f6b0daade7 @@ -1776,5 +1776,254 @@ 887000 51902324fddad3458c70670d38df58410ce98950a70fcc4aba475fb2a4c10554 b4c451e8d6f329db4a0d191970be6d74479b4df4615f1d576589a826cf025fda 887500 576f26ef969d63688e1ea000213b96aedbe715cf97031c64ad19c0e5a0f9332c c1ae2f4a3337bb92b30c745971a612af9e911d78bf9503f2d4173d32ea3e2a6f 888000 a67f9a20265eba880a4615aa5ed2e62c51dda0d707b65f45eee03b4fc44f0e1f 87877dd3894621175bd850a8656bbb101ca98ddac12d54a86af38a08684fb31d -888500 ffe36e4c302b226917ba2587b586115115ccb319b79626fb739ab1f4e511f048 0167b781dbd255ab898ff8c21f10f5ae14b6c6182728eaf64570cb64026ccbe3 -889000 3fae8f764be49d5fef337a07943d3419f749eab745c5349faa81aee4aea0a638 c2d745d450a820d6d8e4aa241606ecf0b855dff32f8ebc3e2435dafb51f81f73 +888500 ffe36e4c302b226917ba2587b586115115ccb319b79626fb739ab1f4e511f048 0a3fe9d179cd2bebaf9f4fe064c9c6addb877f12a05090709f2abdd570b36ddc +889000 3fae8f764be49d5fef337a07943d3419f749eab745c5349faa81aee4aea0a638 14c98ca1a85488d6878125fa5085d35c8373a461ba7458e3b689a54a13153f84 +889500 49a7936fd2f10c0c1fe2dcd9b65a0938fd4ae50f7c4ac195c6084fa067f76919 b971aed9ab7b39f4a9d42d50c714443e9be5172b9cdbb055245695c28266ad53 +890000 761f8aad21a4501b257bc29b52ebff2e27f55b0a465fb5497587ad11212b98b6 81e6670cbf8594d99c9d24120c2ca70574834637314f6ca75996fa13a2694810 +890500 6f040c12fce7f3e45c6cf2305533ebc2e740c7ed5aa812201372447494772b19 b79f97bf1e7764c569e5cdd10751ae56de90d41ee4324f9c4b51ee3603852364 +891000 945ad3b937d8e0e0c8ca33a5da647d1019b9c8e37e0ac4337b66fd3e3a3cd09e d02331f0631f106e84bdc9a77e5e4d4ff4f3456286b1eef2962dfcade867522c +891500 118403722d3ba35113e3d5406abc1daa269440550145bcbd0272a84e528da03b 90f9f71ce4b26c8cce5558f04e9b842f539ef65f16bf55de4d7003d28b5f9c8d +892000 80769648898afb23defea7a20cf1241f584c76ee5637cfc7a49223cd53d5ad76 ebdc74487afd6fd4c963f8120e760ee8b8f0f8534cbf85cc28ec67058c642fed +892500 887d6de372d68314ba865a6a1bc5a431e2f8df673742bd2fb7e11b439117b0c4 46a0ffffbd5887f14c94ac1c232f46304cdfd029f1871b1a30b704fd1378b949 +893000 8b0bacc43bfc87581959a67dabb72df9fe52ff891daeffbac58b0581403a46e5 5c472f2d80c437716aee3cbc3439ce0b4e256363248a93b5d1adbee71d77690e +893500 961d3fa31e522bbdf6cea3742ce5b8646b3fca603fd44daa57f5c10f830e4071 49e19baf811717ab81e294b95c8eeeb5d96fdd1a4cb26fda305046aeb5041207 +894000 cd17ae71de5a09dfa983f6dfcb13fcfa6d6f242080ecf3be722c72f6bd7d402b 9a26285e49feb36f6ae744bf0e89cc91a3b871339cfe538b8beeaf5ebbf54fd6 +894500 25fa66f74866b3b730f3fbb2a9f92d3c705354e71f2efb2747f8ffe1427f494e a37b7358d87c473235c3731bb985bc698bf95f6cff9a5d3e225e4d1ba1c668e5 +895000 50b47a9ba28ab1c5131ec35372be0690b9ff7c5967a81f7d6d7d5d7bab8c34e8 c6d808c63cdcdc412b9318270655cb0d37c315957dff5039d0b018ede34113fb +895500 944784b12fdca39238803ecceb354bc4e8e5d91d4279ec25792820866d5c3e5d 21129c892476213ae6df19646a942694518db3758cd2916e38b4afe436d0be2c +896000 8b45a6293b573820f4b798c57a2144f7d94bd2edd02118d44cc0c59d4c92a5ab de0a319d296d3e88d7bcc46a4cfcf93ec469305122840f5512114776011cc03f +896500 c3303636f08723508f17d63f0d376e9819e7c537d96e7ddf5bacc5cf02455287 36654846452e690e6b833d5fc2d4b6d402c5fe81754332d35162ea65b1ead7c2 +897000 6cf1a830afc57e6d8549c8197e90839f477113278db181bba75a3ccb3cd0718c 387883d5fdf2362515430c50fb20dbbb0ef24c387c3b6fd4f21be58102f4f20f +897500 323544c069e43993ba59d272db7d92d8857855f67cecfb03afb9fc6495aaeb98 b006d9690b7a362398d09b5d5066bd8086f36863295b5da7c2a113035852ab00 +898000 e303ff088305156ddd6d2b5d0c239e459d5175585902840d3f6713a40b2490f0 4504065e186d009dd784aee6d957fbe295c8eb1c3bca23d860a92c6be32a9e16 +898500 4400aba3a75afc73ab3f6f8328a179905fbae533dc9a75a67e8533dc34da8281 f78290551a6f5db3989f2c6f6087b5746c0419604cca77a8bcd63268455aff2a +899000 30d2245ee16163dcab5b9b71fd37c6e0a1a5a3924f621dc4bf2213702878da82 83f95bf132b64bfdc4bd75ca04fd972d5caff941d36a7792f55f478fe140972a +899500 f35505a5677e09578cbfc9c7900bc40b1add13a8df9f70781a95b00ff972add6 c2e16965e43b94444853f16cb48de52c406448aa65a2ccbad61163a18f2529f0 +900000 e37b70b214a685698666a18c3de3362baf0bd158b6f972e77bd306e62e7e4bea 7a6f099828ed54a20b3b9565c1548ce0fcfa4de8c6131ed4caaa629d96e17864 +900500 a2473a95b679ead1011918bbc526ef833ee8b03a5aa3f3e11198e30d11d2efae 9736c820b1d63362019d39a77218d604205e38ec79a117c117ad12d1dd1f0075 +901000 dda19f6a2f7a7da12753b2d7c334e3df7cfaf74a44ba8304b3c5f5e05882afc7 bc0f02a893b0609aa80e08392cffd1ad14ee3b625837d16be6869b5e405139c2 +901500 5d1585d8239afd15b1028bf7deac725db26ee14e9f611aaa8f972b27c8f8dc6f 6f02fa43604aed757759d0116918538b094641c0cb9f66d75ccf62458139c5d8 +902000 433e97c928b52d4964e08193549e6ebe938a665a0fb4bbea22307bc94c5ebc73 6cc41a90d5140aece6e637d823cca6e4bb96fc7317a4d603c72fabc7f6239cb6 +902500 4650e5d627e8526ec617f4f8c5a31bfb8ce3c6bdb2d10cea58873bf361cad4ef 06acce13e151648075467370e9bec6864b80189ae6efe4e0e94a395b4852fcc9 +903000 3f9bdecef49c48d9d259d75cc8d8de5a09baa6b51aed59ac4cb9661afd4ee856 ecb871b85f6e41259176b80cdfdbbca72a0e5831c0ec4d42dd90cfa361f2ea32 +903500 38512db7f3d831faafa2e27c548d9f10e08176c8745fceeb56a59b4f1ec16179 cfe52056c802d202a734e35fa3693c77a8ba3a8f0774b76b9b2e9d962687003e +904000 56e1e664a1de1e2f3fa285ed05c87b89a1db02aad29d4aa425d4491d6b502bff ffce9af2a239a9b97ab7f571269255fbe6bed14ec448078aa1315b1d7d823467 +904500 62ed0214dee8bd914f40e07f60d0b42c2838e060aaa771b39e3fad5db4aba3e6 004bdff9bea3fb7de4ed18cb1a546bae626f03adeda035d47fc8c6c7d04fce21 +905000 02c1fb3064dd2e906dea5b09a9e9515ffeaf4a8e6290d213adf0328aa310e023 0e8364f05dc947ea27a36adb21a97604d9e2fac67508a098f1c147968b7f9341 +905500 013be02154184cdeeaa19e1e3419d4dd5f63991ad93362a2b4fa2e49039e9beb a12d791cfad9e6e291441245832cc82f7887902d4112108b57ddf584ba71d122 +906000 3b1787f731829c85e9888fb9bc683df92ca34b636a1aa2878106d04e4d1ff448 bc52cd21978e040a67220c44f03933086337dfe37f69cc3ace07f5d8ab1b3474 +906500 0be9d3396dc9be557baf880730a8c8c98f0d008ccad020b54ab2f4d3ac5b2bf2 79047ea467c9ea723cf97796ad295841d72b866b1e9b925fe363f99071eb9ec7 +907000 6e80e964c740b9b31d2ffb3939b60f86d019bee6af9c3714f3afb313f659e9da 9fced4419a17762d628a0fb6efce506270556b2b041eac626ed03b923e68730f +907500 7f70ecb783d1d233ea3f331fc823479f0478d4ba40e0b3e25bb5149307e688e2 06a68c9ca8e4e9803d7d91072c7b8008dd77da2df6f1a329f071ab497b16dcf7 +908000 1bb873cd795e98cb9b30c692846a31531cc7f4ce5a474a50bed96e2061e65e17 0b269ad251a90950543ba4657bd0044258f3bdcf6c50d4aac1c89d87499d1aca +908500 c57c7855c97f82ce4645a2addcea5145c98d1cb9553d56ad8909d43a29bdf320 b97be283db5a293ad45e219ce5d9c8287118d7daa887e25eca7914ecce5b5db4 +909000 340e921bae13e9a770996bfdc6b30d21502a9dbd0016d2cf0a60d299e01b55c4 50d0d76f836bf9a1f6c807cfc9512ce2621a7f8e8d3215310d78222eff1dcdcc +909500 bb00fca39de21c9b3eeaef52a0f3ed353e63f041c817977b6339f6fa1c127827 69b6dbb417be0072ca4ceb44d11e61569bff4161834baaf439361c0b17eef028 +910000 355ed393bdcd6c79964e984b96df10eac86ebbdd70652985e5652175230e3f24 6be87fd1fb578588c43235926805d8740eaf1fa271ed3ef54e1b830a976b85ab +910500 cebecf803381bd5bcfe62dd27d0fc46b34ca7f14ebbc463ec770e6998a1b629e 6dca0680947bdb1ba9f6f2ebffd1475d18874ccc79ec26b75134ece99dee8c04 +911000 0fce8ead8161e060242c6f7a6003c4de749dbc1194d8efa84dd22daea8cceab6 649a3e01e83b89631a710906ed025cc0f67e8ea52f11e0b51ab3f8422a14de46 +911500 6e60193890cf91c0dafce4c0756a47c2d57b70b84723bed083cd3af287d82435 b12f27c0626739460618af055b57710d241bf473d10c209edf8b10300d64a119 +912000 c612c0ef542a4a95bc1f45d8b5992c5bbd499a0204d057fc5c3b8c6052b0bb48 ef4f90f0e2c4a627416f8c7b590c79a4d030ce3b6ef7040fa8dfe20d9b1341cc +912500 4e8c07cc191bdca3f15f8e5e8fa2a0ccba376f23dc9618991f9fccaad35b1694 6d2cf50ef5fb9c21ed59b5669566dc625e1a023ad3aefb75351c4e96a2df4222 +913000 fc9fafc9d5208d6507d92462be6ffc8b3acebc7d3acba2bdb5f5b1afae779ab8 bc2b997013ceeba576521c5a2dbaaf429b9d6eea2501947de4c696c2fc8083fb +913500 928d12b4332252e7216fbb36d4384eba4ffd8bb79a50667b3fc15878c7deec76 49d8085c3c7a8477fcdb80af39c1abdb69f5a0366e0dac79bfd30439b2f293e7 +914000 7bf600d26589f7dc4cf0c68a9fd820b4709e95c864c379b4e5175b23d518091e 6e60fe7892f34d0eb38229ada52332a8d1f0d120de231e404ef18f319adf5715 +914500 8e5cf10113f76678cb5265e293bd0365012f0ae661e58e6998005c96f1ac9869 5df5fd9760d67bdf9708867bd15b11fe60230e125abf2db4500fd7db945fa6bd +915000 33ddfa347fc55f5b299363d8b6bff03dc1d98ec1041236e66babf4023d3d52e7 8a85853ae490805462a8aa3700c84a276cac17603b3dd0002c54490842cebee3 +915500 afba8520a990af275a8d1f82de844c793547432b5c6941e1b30859513098758f 06ceaf9f70d81c901054cd961ddb15b5399fc0f19235c048649ff24bf916f552 +916000 fa8e0f7e4c73fa9914b795af620ee52434bf37fdaffba88d318af058830dd361 41ec81c005795442c4705e943715065eb89cb4b32a2f38a311cf643b06880d79 +916500 2b20f9d73d4c0af59212b3bf8383f845c95baabc51df6db044ba80fd5051eda1 324489489a55e3767836aac9d5b620f5be775806ada19f27a61671a94098f269 +917000 b7b20466d119311d1c85ebe1ef60dca612ee14b87e88d633fecc679d00b959a2 96843566d7519919c12ee3cde2b4793e7043a066f63f3dfd690638d3b3d2bf5f +917500 624ee2db152989d3e86cd4bdd32e84cde6f8d0fbc556561bc690c8d64d95319a d043c5740ca03cf42a53e4f8abcc96dea665a16acb738dacf29cccd3721a9081 +918000 eab30c35d483b6b8d4ac7db12c139b294c9b9aec8d4c0db627f57586b3d1f6a8 121c7b5a220fbcba9735c6ce0425ec14d9d80f75bb498a986684c446ce8ea2c6 +918500 e9bfefe8932f66486d1d3a740d14b1fbab1fbf80b5abc9abb4af1333efada148 3909b21ceddd287e2b1d8cf16accff743dbfe6c2c0a0080a33592036cae626ca +919000 4111e02c00666bb2701731d59808917da660228f50fad0d338d31324219fcd2c faa3d00c409b5cd2cac4bff556bc5d07fe901df0b3e6f1e1059e661f59dca640 +919500 fe8ceefd0657909d523c68ab34109db47c31a56d96190f25eec23ccac28356ac dff9eadfdd7da200e3f9ee425b46e6f1869c2947d77eb068d3de8e281ccc9f33 +920000 94c0c84e0720cf98585709161f8e0d52106a76810c36e8eceaa50c5937423e31 985aeea9e4d2fa5b24727c5bab4979f7c181d52e1939f5c1e9b9fd9d8d21ffa5 +920500 7942c1928c1c7fdce2a7f9948db255a58ac28c650d44f2cbb568b14b7e77a869 3fac2092a646a391bcf3f5a3703341b9667c9dd1800148346bf3d0ac8eb0b8f8 +921000 3ad13dc5aa84d6f0c89d4c1d4424928e1c3f17def687432e3dc5bc0d1f748e4d fc66d327154d4f892c6fc8a1a766917e137dd5ac1de66a8e93a1e3206318133f +921500 fe4b447119ad825c1f495dbb58a1aa394eeb40e6fa1de1ddf72886ea69042eee aae2951a99bc6f730c70d78dbb6486d95d432b7fb154696f0e866b5e661baca6 +922000 7d1d205b9c72f860b446b8b254d1c22a8e5a5049227ceff04424ff01761cc29a 9fca8ce08cf17dda9b4a2695096a50f5cbd54c8c11f7c048bad4e27c01a7dc9a +922500 c16ad392838d47ba7fcef91e9a0be7cfa1dd11d22c9ccc0b6f631aa48abc73f8 01ccf18791d85e7a78fdc9e751948c42a6d58d9c4fefc118cf882c0a5bef2ac5 +923000 438bd2d6867e38f68f61f9dc64952993f7492e39771516520eedd7d5d9d4054f 40b95ef95e78ae4c9e99865bd4e7a4f7d106c8d2aba90f54aed550f14aa9ce17 +923500 6c205a2902c4c350df7de4e96c6815eda103645b9181fd9e8bbd6e53b5ed843f 9d8c87504c9db8490188c7d8fb0e6aa1950a03a80cd2bd0f8baf0297a73ceb27 +924000 821de00a7dd17becc9dc0ff750b9e74237ec391e9e2effbabb71d33fe96e574b c87cec5b256635170e6428e3040000d705decb654b84a7ac9d1566211e18dd36 +924500 fc66fbb75f4f01611cc4bc86249e329e5f217ec40e0f64f332ef508f4d524fa4 1a9d440004523707f292fd87bf077df59c59e3d39e7f799604765343197f722b +925000 b290fffcf3f8eb763704f79a4a6e5fd76a853a3cd013efe2e41fafb9177d223a 3d9b89cc34b988fb0d1df0135f59df3495da0221277ed3abefed3558408ee132 +925500 3a1fb804b8f62e4c394b4fb34b250986d195b4a066238eec560443219bb06a25 3024ae8c2825c85dfe675f2b66b4576a6ebb934166dda6a12016fa8f79f12a63 +926000 819094082ab3ba4c3a715880ca1de8c9b7036d68224202838a077d1c48a0fa33 afb6ae704efec0cb30127cdc4c608245d88b3bd39e3f09b30273420046051679 +926500 eb74c0dd62c2e8fc7e9c45545e190d959a6ca29515bc7775cf20f2bce27349f1 13849b250174a3db106e2184f7621ea88b2e6b6fa4d36ebb2353cd7fcd0d4a12 +927000 6397314f6bdd9ef003cc2ba39a4539c1e2267b13272c78b886127419a1edcd28 3455accc7f9a3e2324080e7691ba7134f8a6a3d6b0f59ac8ab1f8de3b1db976c +927500 5f1f6df5959482ae36d755bb88a5b2788a0f6e8ce6e2d62811da77c02324703f 044a874fd1df9bc0e384a192c669fcacc6946d2ed148bd5b3cae0eea0ecaf625 +928000 3ee8e52f1ecd00dfa60cf89435c08ffbbfbd1e0f9596541cbcbef38c520cd71e af25521212acea8f5c894fb0e2c0f38a4abee868b66ed124a77980e5ae7fd840 +928500 c3f4c0ddbf8dc7a91e5e27e3bd4d8f817d18ce724d9756354449d7894f96cb7f d7cd61faaf6d8e0b362aaef72304bf0d1d8d751b1fdb6e8c11482fa5b14c2045 +929000 73c7f82ac5c353490479945a8e5a3528e85ba4276e3c7b5b359ed66f34006d68 9def4754e80ad70729276465a92e65e9d70a3fec02ce46d76a6b748bbf19180f +929500 90838c6bda7f6f4a9964c3b99caff44d656fde4928d526d7b761aade9f6c5a4d 43be3d47189799a47edbe664a2e9452e57e7ecf8f5df272a5090552cce912ac5 +930000 993167ee131ed2e0875b7a764cb7e8651a01b44b85b4b40c16cf8b69f0754029 5183e99bf7bc05a09fd514bcd646aa16fd040d8313d5c2083291d350988e99e7 +930500 53525fdf3fee3ea4bd860ca7185365312b74dd8cc1e3f6397f3a467f2fd659f5 b08fdc19e65d7ba7a01ae37de9db8065c344f602cd6811a6b0fa7efc22cc9ef5 +931000 310257cecaa31778dc0ad056b4d0ba181b0339630bd9a54f1d2c01241546b648 e84fb5af344ef95707e5060d1675d11e8b7373524227fbcdfd3a7790530b9eba +931500 8f92f22fd3d4d35cd69456574605c6463abf15a58bafd4fb2144e58b2ae60bbc a05d6abd0dde92b9e65dfc93c149ca2f6ace7416efb996cbe4a1eb31d4add968 +932000 975a067e94d2f89f81945c70161dad251c93387934c9869007bf17f9f8175f66 38b53fea2e9bf87fa3f0478da19edae0de9444e35605e064e864f441c6531ec1 +932500 438ce459632f23fc45667091be8a8a4247f6f83500e46805a7a63c72fd674b22 aa7fc841988e91577fef8ed0b8b134e9261d1f8afadd12aac3fe7a39129cc393 +933000 07ece8e5df3457f385595c03d9abbf7b42654e15548ee72fa01b7c98d87fd654 de3e7b6128fe92260b645119d9aef6a57361cc46ae6328c4752cf0feffa7e93a +933500 bdbeb91240264a917bf44b878b92c09c6a15005a39d51bd7cc4d6d401e1e4319 ae3181503323e70a8fd2a11ebc82decaaebe409793fdf43f8fce394b17dad188 +934000 f3bd01e5acae46dbfb3365f3432ec1c81a2cfdff7cc6affae91c109ef698615e 74af995d48d047894f0d544423ba75d2018f04d928c6e7e468115bc9d447317b +934500 d1518129840b5977d13fd42440c257445bb31944c177691c8204c6babbd58f46 c270324df573701c0b3e41267557932eb7fd68e46d96f84e1e302b6e336207f2 +935000 00f16b56da0b5e21f74c506d5d2a1d7a10f4403e6feda3b75b269b93a7b8751a 85b16fbf368e56074baa64cfe454fcd4d387dd2a3e4e8dfee7de5d65ea7a423c +935500 bca2a40ec3e783714d2dea107f8a35cd01ac37f845d78181e79e88d3770b9192 99a2c6c0e33f5dc75a98b39100a26426408944d396bdfa5302fa0aa8df340f2f +936000 03e8bf996ca3565405d01cfacc215f59481b90ed44d2b8329379fce0967290c5 7c6c2acfeb309f1fc6132fe8a812310aef3840b6af2cc1928394be16105e253a +936500 36b9b71a5a9d854eb5456a8df936d8995f40520173c81befa852db9773a1d26b 53733cbe7fd5a371c8508291f8d2ed3720b87838f3f15d3db8c16656f722b5d1 +937000 665e5bb5ece8d808b906d0476716f2fffff168696bfeca1b5483c7345f029a7c 801b0c3ff2814d875ba2f1be4f26abb060fea42ca9190a45275d13523103d015 +937500 89c15cc1d22a312379aad5255d2c965ce9d466a9a308052fdace9d955878b03f e1b6c64abf2b80105d8c292532489650af97b6de6b6362ca8d5a090e3fb6e930 +938000 69263892b7a2117af68e35c3e6f5ac6de567bb84d10d86ef9492eb31cdb78e36 1db7af4a0cf53f0686e7ad7dcc15076154d06e9fd8ca256fef101fd82a76adda +938500 031638da90c052d869dc3da33fc044507e0831219ae121e416c10cd8ff5c25fe 2e94ef6c5ac4720c93b9389a66cf999f22145751f58cf13bdaace6d5b1735344 +939000 342f820c0656c6e11de2032ca29247575c0121d8414c63e703c486a5662fcc00 e23bfa4425b2d940da54a62f26883b429558dbae605a1a762be33a5aa18b63fd +939500 250cd72bd19b23ca51479cea2a7a9f4bfec67e343e250cd67b6727baee2d8520 b2514af432838f255641352ff93268b990c0346997e2c11e93987dbffbf50344 +940000 1fe1cf60f5e02ab75067eae08e3f8c71e4cff03d232bf2f2c6f789ef49dd134c c4b2e8af2ad3c324a01c586f22be66a30dce34d76e05c9c8296b6391cc143e44 +940500 37fd0de5d9900234dafcd91f2800fedc4bdd5f5f77c6091c5007ea3f5091e834 257db0f9e944de6816c015102334c79e531decc0e89396c49ab043143d557ae7 +941000 6751331b479dab2a45ccab32a8df6c5667df8717d99bce3eda9099d5a93976c3 8d3c34ea9311963d4aa20cf0c35c17d5556c926589354d474ae4f89fc7610ce3 +941500 e20ebc38059a946e50e5779e069d3598de8677e2974efac3aae5189904ec9b2c 7d08a1657f10154b398f06cfba601c5b8cf68d0a70afb8b1905ea8b9e449ae43 +942000 08b423776e24127b4db2d00a86ef3d23defa5a94ee9e8a8d04723a0061c80d09 94e541a46a6d4c989c209f262c0c563bec8a6cafa3bf7a61e1bf73008a3ccf90 +942500 e99b00e621c453bc93e1238a8de8af078b2cb639f185a7061fe7b1d97c66b6b4 0fcee30b06113c4d3b1f019e57cc19c5f448efa689f5a95f041a715c115deea1 +943000 dabc19a6f8952c1f8c2b4a6ee8540d91c59b54a953ab93071f026150cca356fb 66da69070bf359d355715c3f66470c0711470eadaf3ceb1ac80648beb4265b5e +943500 efa86ec88589aa9853bbf58b7a66708f52d72b32a43901253b48ef89fdc68195 da99ff838ba09c7843aa05dd869311fc058e9a266ab3cb560e4c4ebad30bd6b7 +944000 2f594ae136ca24d6d073e29d4a7278134ae0fdb782e823c2fe6efa9ba8c053dc d285a29599828a65ddaad8acd888a3030133f8583f5618af616c3637c3778861 +944500 c3ba87169f55a8669f3f2c7e94df26be0afb0e810104dfb2fcabfe40847eb644 e028eac5db8fb1a565277f5587d8ff105a3f4523946a20a3cbdb16e7eebaf586 +945000 5aabdf7dbbf96f3b9136f7891335b4b4d2ded4a4ef4b15aae24400ce7eede6d5 a791d33db0c6c72fe407c3141d954c7b6166964cadecc7fc7d9d70a05c64f5d1 +945500 160513624bd360141f9f2aa0b77e15f2f78adffde5408688a3f5cf2748f5a33e 1978fbf063588d8d5c669261b70e569bb5242c67ea4b896e4fd273cd5fc919e9 +946000 baef0350d326a00c5724bbb63a3a7d12a8463d59407afe8cb775f3282dabe66f 3a08925e17e7c91fa44526b13304a55ac9344cf0139d6b2573fb362efbf6e2e1 +946500 3ba6204f144b41e18b5f571aaddd7591cc8a2461790e23117eb263def13a409b c72dd099c929527f4916ed7dc0cf34d3c4b98a4ea8f488be7b92980af42ba4d3 +947000 1bdd194c738e7fdf54249f73177a6c78104e06133d0fd97d2e732e86752d53ce 45f323adec9c4eee2e3ca82bbb2a165a0a94db22d3d700dd34688fb2575343bb +947500 b99a2375ff79648c98fa232d1b0fe37759deb5826866853913e7ef1fe2eb65c2 17dd7cc2b9689b1b4ac97ec835fdcf9ce80cd5728d2d5d2a14883e382e182f51 +948000 de7bbfc82a59fa0c6691020204c4916b9b102f66536e061a3585824472bbf2ac 2de0049ec5f874e752ed146e2c7edf63f6095e53a8a349ed06c052a341d87e1c +948500 ac2e0e3c131538ed118a3123795a2fe51803a11c3b4b08a7e47981884b2f62cf f870ed2d50bf25f95cee956ed54551f4b3e92d54abeecc3f0aa5cc15c5b10a80 +949000 e1e69e1b1b21e4f0a18b04ac9cfd9f8285db96ff6f4e9ba2ea5a454d7b4a51cf f08f455608a96421e2c42c6fb44348331ded8f44536def80ddc2aaea53f811be +949500 5be555320df6b2e99d8f77952bb45df07ca3f9f1bffe4a4800a156af93d0c629 989e6b9308da79b0b768c6216474a6d1700eb89a59771bec804e8caa61089dac +950000 e227fbd4fabcb18eb1e600e30654fe09de863f77f81c7634c2815bdf909992a2 5c5fdf4e2450ff02361822c4702cbecdd0cef3c818ec819a8ada6c7791516396 +950500 9c0dd1fb0034c4a92f5b77bcc7e5818dcccee55af147ec6edccd499465ed8502 94d3663c2526c1645a1e7430614a665a7f35183275b7167c5893d6b1fac7b530 +951000 2e932c87fedb78048a70c47b4f33425ac91e5edf91ee12421a4dc6675c50b084 2b9e81d117f74eb48f91f5ef0c75c345f0d1f8685b2caccdd0e739f8a4d54d04 +951500 3d14b8f5c18082a279d433595fed521d134c844ada0f144595bd1c6c271b02bb 9b6803d021c36acac84246ff8e5ecf486a40de03cf3f256b91dbc1020c62f772 +952000 f1d7b3035d1b4a3ca9bb76325f8e09ff28baf0c0bc02d6d02f2f12e09cb25bf5 336abcd43c7b1c697e751756f24bc499eb5450d9d6adbe83b01233a73587b72e +952500 09ddfeb92d32ba800b9f715b8c2148d283e4fd0bfbd1d0fb1a32c2249dd919c9 a22209348a5e34a49ff2a9dad503299d59877783d47d5ca6e770a29a07396adf +953000 613e697f705fac48776f20e3f1ead078e683ba3b5ad72ad9867e14be2d28cecd 5d74a3b0feadd5f3edbafc529ee8a086eb81cfd9f8588e12ec8631eacb955600 +953500 f9ab20889ab4c8d6f7dd46411b80f89f3551920684d8e4b1d3de88a5dfcfdd6f 3b4c8c9739de63889bdbae40394a5e0bb12b982a5159e01c32d005e31ba7b4cd +954000 01471d646b617bc8199e95555f46f2893e97502bf541dc6dde371e0ceca8ddf1 b805b91fa492fea176eb197c88526fe225f18a52196cfc3da37b8850eb36e4be +954500 c26bbf96a0ff7d8d6ef2d2ca911b2c8f649be385be4f526753cd5776686f9683 e22b003c8414dd5d24dcbd5882705846e7391883fee7252d2f0019d0f066193f +955000 2812f54afa9234f02d0f89ce067730047af24ee14b3c380024da7a6567787b3c 3a796a63e0dfc3baaa249d05553a993a4bae85c3ed54b183adfbaaed1a1398a2 +955500 9c05768aa95ace543246ebb963ce1548cd9e5ddee7a6f5e45cce1db5c47bb2a7 c824fcfa5ae174f199cd91ecf2ed8049716e6d7dcedc0cb4be2a3bae035aa6ec +956000 769586a0e2d78803ddc48d46a6477505359896a7b8070cb55076d142d9360ec3 69a7018a58df10204ad1f874a7d652185e74bbd75d6e6b29dfe6bce759dfe945 +956500 ee555f15c4a433b4ad77468b6dad7560838ceabb56fe1e67076ee0e23a2e5aee 727ffc7586197dd0e3929e7641f10fe84c5b7c1255a4075496afa76cf8a4a473 +957000 1df30e4f986c04325e299cfb1350dffc76591f9ad53b40ab249769b38a1488cd 3e689b1cb999a8528c0fb90fbe51adbd0b90f6237a80169b49991a25caa86fea +957500 0be5166150c2dadabff827efe2a7e1760807aea08f7c0c5855a47e9cea4149c8 b8c9f5d0a6b7baa4947e6bb898ef1ca502c6c77fb6e1abcb58bad5451bfaa94d +958000 05d2d2d75328dad0ecf43961e0b52b227ef311a18576b2a2c58f9a1fd4844aec ab2e7a9c7bac8c39a3bc96f989afe46468975542d8186cef457c9ad8adbb876b +958500 a06d333eb4fda03d0e2cbd27d8d415e84d5da63d7e5db371e0d5b2744c32e625 7b093292ab44a6f779b5ed00cca79a1bae4eb79de2cb150b9ed38a43e7deb57a +959000 ce381f9253633f9d2b48b71987f9827e5b8d68d09bc55248badbbeb85ccd33dc ef5fa33efab771f5175bdeb4ad9f5a0e6b122f02d47fc5dfcf950d467778a23e +959500 c6e95e1ea44b4e47cece003fb1e8da01479c0b41de18ed008e1f6746f208b75b 9b6c1ecd301c7dce7d5c3f0da8c4e1e7523570aa387c8f3c5006a55117fc5420 +960000 bdb90de7a26c79d8559d48f9cf9acfd272a2ebefe86c78e11759a9614e5f2400 5defaf36aad68670ae534577435596269927ebb28ff6daf25e7992863e048ac4 +960500 c8394c48d68806fade6e2d1b27fb16f1db969be718c19151625ed723c4d782c4 9074493aa1e6b8327a8c725279fc67b90dee31ebe94e9e2431ac9388f8d6b7c3 +961000 9177a28ac1eaf2190c6d3e96bbcfe1ace9cec8687d91c5d1ef6a51d3133a6251 13d00e3d155f0535894a8a170925f592f63112f285d5859b05119a90d6ef06b9 +961500 7fc9e7b2460070aa7de93a059e74f220dfed6ca9d60784f305737f4924067658 d688c89a2e08e78cf11cf0b62ef92e4969f934a53ab7650a09b3178693f9f4f1 +962000 92b750fd920737b637e87ec6ba242570e05c24805a4c06ca6adfe72de1cf3cca 79ceeaf812c0d470eede3c04b06ae94cd14e3569958bd0e7ae4ab4583f1652a9 +962500 4723dabab6846111db863946410887489b0917f28b6941661d38150e80045834 2b5b5f09f42e8441a73d1d69ec1248b881401b23610153724bf4721158a8cdf9 +963000 e7718854b1a117c939c705a60d706adbab7bc1eb29e18b3fa86f6f7052a4ff5e aeff06b67b31c015553db2a96db0360e61d61e3ba03b81622a2f6535540bd431 +963500 64755a7e2fe737d5c50c0294b03ce6f11cb5ec07f55e42955c5e0363f371c5ae 3d5d8c6aac6ecff5aa8be9a984838046bd6a8c591e0e179ef9e171b1cb04869d +964000 59bd046c3893cc35c97f871dfcb03988af640790f5b81bcd37720fd13a4eafff c0dcc142ef875e0a37f250ebc98a96a50671a4f3e36868d2b6e3782be04c275f +964500 6f0dce76e2a057372de537c19e9cf8e89261cc24a56b30bd3cef7d9458efae79 186d6eb95874086c7dbede1decbe52e2ef4f9bd7389ff5897d40e5d63e4fbb97 +965000 6e7d4ade21bc5b59d50ba629a0bac97eba1ea1c22b909d55c62115d83c48b0a6 9ceae7a7c366ce13b5903ef59ee5a940c2f50eeb7ed88e1b5d3fe41f3d5cc8e1 +965500 07073df1aab61b4e7d6ac4e3a47cb41266476326136ae32a17e63da2df0eea3b 8bba0ae4edf8a31f1d3f2eb3e2bc8cf89913e3588470c4c26002cab2533120de +966000 46de91c0817c0802081c0382a111d4eb0383e64cc412e20e14925ca8256da92f 4da17f7bced7a0672c7932fffcc076da613c82178e51618ba0d051897294a49c +966500 5d31a7188d2e344852c1cda1fca474397652e623eb5160cac91f0765317e1157 4dd7385532824e90376cd8b918f5877e7d65e7826a55cc5eaec718f9959ced59 +967000 ab1b701b49ea5a3d698a37dd97453251fd53b70ff008b8fb6b34d90c30298e07 f4d5279f7270a1277967be4076aee31ea3553c8baa7229456ec833a974713408 +967500 fcec3fe1ca40415a65df82b0587f4ccee3f121fe82592d724de22700399e38a7 c7fdcac6633aeb83f348ab7e86341906e3f30c84422c33b1352e96b858dcd2bb +968000 9b8ded270161eeb47e94caf849655c0930476f6b73ca1afc050f35af10103e47 3fd0c2e552084120e2fcc8b943e734d4bc1a60ff598ce4365fa8a1beec829381 +968500 0845de27097e020706a6f139763ff199f0d665d00567812507bbdb4c4739a7c4 75003bbc6f63a32615d906f51b0e325f78a3281c706162f24d3468ef42d0b2f6 +969000 f92cd5a018e68cbe9a7f4da90a101409966d441e596d102bcac073828c13cc11 caffbbd1f4a08e8b23273a4ab7bcb53ad5c1b80f73925a18268d2f17f930d1f2 +969500 b08c175b0d02a58d410f0d9bb296059e5478c58ceb35259b225ce26c58ec2ab6 003d4e578d4e99ecd8d1b569535e33d57e5287248eeeefaa97ad0487f8836f15 +970000 391747367a3e4346b56c97953d6fb4fa89473d95429e93a75cd5844ffe846812 9af7f2fb1b4e414d796c5cf0d2324150025e5366e8db18cfa5ad7804956e4e27 +970500 caa262b1741e47d85bf772b131badec7e12319a3ab8a617d9f57d6584360c2ad 293f56976cad2572a3c4b77266dc83d0810a915c1b9f4c4dad5e1cccdd715101 +971000 ac906e072ba4a6d698d5581a7ec46bf277c76691314d3390188e86b68089190c 718aa15407bea582e47710421ec160dd724f9905a088d83c7d240097501ca2b5 +971500 dd461c00d3aa9922d31abdaa8679ae8bbd75b8aade9a7f9e0bdd0174bb81318e 6d4cf414e86245695ca9ecb3a4bc3fb9b5896f3348f4e9ba916daac9133d7916 +972000 099e80a3f22cb61144d56175c2e423681e9d5fbcf8c82743af51019d0123b21a 2ec23f05afd3c6f60376c4544414f84617c48f368b3c1a1b7b90b060fbd27018 +972500 eb380990470813b19e97939e36bc7ec145ed5bb84a5c15a18f53d8c6c399f626 b7f9eafe3239574d3c22e39a2d2a62b471b8a7ea59c8570b206fd2d67b23207d +973000 55ddd462f4830ae58cef001b80805828381fa6f01763551fe3bf41c47bd06e33 48e54fb3fa548f31b6b8012129886ad14d438d0e6af6a05a82230ef00d80905d +973500 0a3ae4c2d5937527041e62d202f1f3eeb575062e464a3566f6e3d4e9811236ba 5fdd512a86c7668309807bdb7146dcaefa13813bfe05f812935dbba0c7c04d62 +974000 55e80cbd096b8eb1df3fc9fdc1a4db0685f135deef48c22236a3be1df8d075af 69b5c8b41f2e5b28a329e3cb10293ba29312c252fd97e2a6e9257b2cc225354d +974500 57983b1af96d8dca16423e30c6feb4451abb992c59eb7daac3aec47f0c10404d 67c8b4a9a90a48fbf8bd43f41d290fb38c4318f00d177b76472d176fa4960836 +975000 789decbf3352b728ca2513866842487ccc080040c301c20e219a6169af17f8ad 8cd8670e216d098ef817bc6f4ac83b0de623fabe5b0bdba2bd588c28b40b7b04 +975500 e4955374301cd615e606fa045946f8e1b09dd05be8d4cb90ea334e1f0bb9b0bc 73bfca0d4522e57aad1864c6659e0906da259865cac1fadc2d4c8aed47f23a12 +976000 911ee9db7be3ef0f0932647a9ce131e21d7eef9ac7c3a40fb9da8f3d328a3313 a2d82537257e03c3256edd144045b2767b844046c07dcb75122d4100830f7800 +976500 82038a79a9cb494206fba58cc2903270b915d0396a2b3d2dcfc00c5bffcdccec 147ca1336392af0bc36504c629248081cc5abad35dda21a7c10be10d2850df55 +977000 92456a662c9047c73f7083d2cb6a9bbd7f484ec5eca845c3a23362dfc9387796 9700bed9001c1f54a9193337b07715abc03c91d0da1da02bfba14cd22cf7bd6d +977500 bf8914d9c6c6b33e67c47ff6100b7f026dc80f11cc6bbcdd91489f68887a68c1 8093398e5a2f391a3ef245664e6222069167cdf90491f84e9899eec391e01f8e +978000 b1d888e91bc2d0788175d1167c270dab6bb1257ba68bd0f8d1d57e19788a71ae cfb5b13f8abc2bfd9cbea92a9feccda90f4bdb96861e29d6824d6abf40088dee +978500 6e5e3a0db764ba19342ffacc3343df6000afc4fd7ee8aef59ff7b6e933017eca 6d5b50718e56fe6f6cfd3bc8a1c058b7c9cfbc7b6cb4701f1d2049e9401f5c7f +979000 8ab1104fca85862d1df0ab6edb7d4a001962e612b427f7814b83a3e63a56ab39 e8b74e9b60ace577954c8eb0504dbf1b8e5c0dc057d438554c156878d6924a11 +979500 4b5c03ed2fa33e96b1dd3be6646c65adb5bd35a3e70dcef17dc6eaef44f7512e 1c899654861cf5a3f58d764f8cea03248806c5de89594eafd2a42d084c546be6 +980000 d6dced594593bd65bdafe4f455f97c83aaaf195a195c327275d358517276cdc0 cb73280ea478de4ba35c27fc544edca9f7ff6bb3a0c1a0b44c17452fc61f8a11 +980500 a9b5fee48434bf6d6062d4c3f62403fe8882716af75891ee9de40c010ff4984a 50c67a1f249e74da33887c715d827f8dadcae23627c3c01cc3c86e2cc332d3d9 +981000 e49a842bf035c8ba0d6eeff766f7674df57bafba5bc8574c7ffd55a1918f4e07 3352d7d0d6554aefd57951186ffd4a20906c4c9a562c1d85a911f8541e1f5833 +981500 f7563d6939461d13b3d2886ea0eeae55bfd5b70a2124fb1f99e3128b1aa57c41 ede14ce9d15b6d7dd03bf87dd1d6f4358eef1de87edde1b4189b5a7006242895 +982000 4bce72fa79b9a6cc3a049ee07f2b153aa5de690bdd9177c60b9129d0a3ec65ea 790c73a90c7513fb9c6a2b0293739d8305807d61d8dd5d4ff607f8bfd385e96a +982500 77132e20fdc5fab30cf9b662a7f7f0e7cf54d1cb4d81367de088f28a594e8670 2ee079db6a79f9348a2f6484b787092b71ed1bb4c1267d5a18eff8d4c321c14e +983000 fa83e50346e0ddfb583789e0e053b74ca5765a4240f99f02c80753b0664a2851 9987f99ab0e62c8c49f5b8465f24689b780cc9c016f0c7094a489dd6724ba646 +983500 4c65a2ebacb363949d2a461a6a7c0a2ef50e4318675f4f5c9e417fdccba4c8c6 62e4e5b983d0546fed593a3012c6b7cfa0ff96ef28ccc455142618ac4c7fb0d0 +984000 15b16b66f736e2f12a9324bb45854c9f6b49dfc6b367f346e772eaf8ea49f14f 46695fd3d752266cd9f1e6d529472996f8ba494f161a7194bbf05b1130e3a4ce +984500 bd9c47bb23b50fd7e77822c377f78d7aea793eeb694484291b8901322642c7dc b8d50e9fb564090ff86cfb90867834e86bb23d4a1b9f03ba65b3729e78a85aa2 +985000 215551bd7b382b243fba86059c241a3315ced3cb6eebcec5d64c731a9aa07d95 f7bf9600e24bcacd6716ac7e79942f9f62f16b644aaa5bbfc2cf87b84a418494 +985500 aed846fcf07535b706e65ae53577ac77f106d4d196aa5adcd04d81ee2159f6c2 0c10ecc979a353ee4b5d050ec570f95c8199401598d09ff9009d0d7e03a7326a +986000 f273f50890e0f8125bd23c8ccbe22be64a280b6f293cbab62dd9e9482096a58f 289913c0b5c8c8c34c66bbbc27b602060a274ce12463a0d94928b37cded39687 +986500 bb2726763523d72fa76ae25415b8e5251d234caf180c1cbc46684d30ec96c1fe a6322ac39bd1cbb2d2a6cff84e25e3e310e4e51c7f78aca2c1828c443cfa42f7 +987000 eb16d2f4fd89294f684687a1fda4cef1d5d494324818c0c16b9e2b9669211c60 a922d18fd438b0b631a45cc52f1b35192e101b890e35787f60676d5ee100a0f7 +987500 d50c6155658a1707ecad02738b6557432513bf5ea78bf3a2e1cde78a3b672f91 95b19f76982eda85133625b6b2d8ed6ec049533d9a8f015a7d8eeea85ebda3ce +988000 8fae67f15c83e3f5ce559fa3be81c49b47ea2923be52f8fca6ea76432973a87f db354947189daf8324430538ebacff70a48b80bb9fbc80e640efe5a0032aed71 +988500 7c7b9d686c788f19718bc1bb0aa3add6d5071118fbf2a914d4447ec2867de02a f8360801e9268cc2ed86aa0ec2facf7d228bd891e0cb54a5ad7d4761797409a5 +989000 464836cbe95821ce2f4bf0ae1eb094b086d894130057e25703f109fd1f6932ab 3e3682d443a12d532d27364e2f7b6a5edd53eb7236159d859c5fb4b60315af05 +989500 29766a224c17b8de90c83325930b52e2b52ea23242192f7a3795120d43c6ceae 6d1e2b7a6c886b98a131cecee608276d80903d9f230f2486a7eeb4b094bf13fe +990000 7a0d6f86cc9693e0a0ee0febca3b3f8116a2c1ca3e3f5478dc713b9c03f1286f 77ac7bb4b87ce136b1e951aefa132fa8e70566b1aa83e2b41c7e51b50f7ce994 +990500 2c605fb768a51433d5ff066d9e6736e991a806d3b387c873efe12b5edb30a967 19bbe2a5c3b3d2416b9219cf5570841f143d71a0fc20e29382eb6cb07901707b +991000 13a48c504165faf127f177f7d4fe19e150c94f27e55747dffdeb035a9cd26c1e eb2aaa0eca1b723d685a29f82d8a802e81e53009b8f53d57f0c2d80aa5dd2c71 +991500 d28753c20fc3c35531286a7c815604103662a182986e5f1e5f84e2437b49abcf 7f0ad9f3223bd8989cac9836665da3878a14b6ab705495b626bab79a73ae3e92 +992000 86d7ea18c4c4d8ad086d71a384f12bf1cfac15ab847838aa2dd3dc2bec258f16 b94aef8147f94f009f2ceefb00902ef16cb7bcd31acd16633162dbad61bdb282 +992500 e1b3cb464a21d2243d3577a87ffa8a5cf4f886ceda5c3b70e5142097b425fd46 4c934f704aab283fa3ae0b18dff434bedcd7c549816fa1e1a4639b6252ffdf4d +993000 88a8e95ccbef1cf83a82690b89c170722120394b01ea641001a35379ca8bbae6 fca6247b8ee3dcb01af1aa29846486eca0092ca90bc14274d16d29c823abc081 +993500 c34e2bcb4c7ead30c306385655a8202de556ef19ced40c59aa14c0efac91e2ba 796047ec552f3417fbda0bb7e8b47476652a831590572051ef810adce0b28f9e +994000 d5298162e2923b179e6cbdd230cdcc57dbd74ee47f24b94467f61039eb9ea1f5 4b23ad485cf4edb61c5db401a01488b7546d5c9ee52f2bd3d9152ecc35212b8e +994500 b0664adfbec0e115415ded1b9645a536b50ca6abbf6d4064fa0004b70fde8e6a e7c1d777900ebe2a77996f06d21877252817e02a565346e4d014b06c1a29767a +995000 e508ee8874d2bbe69aefc606873f503678aedf80f7d94f41d2f2c5dd03875cf4 86d2b0cd16d25e2bffc226f79d7212271480febb960efbd50258fcc13096e179 +995500 a707c4371079cf705cd28106444573df7512088f6ddf94529d3ad23a7300293c d45f3c7e465894cbf6ade11bec71ce70dbaa476e9883264398651c58aadad749 +996000 f7b87eb786f79e735e906e314053d44ca9e390f3e95ace03d9210540bf481ee9 b97629b917bf0cf5d8fea9f1fc2e70c68b7dd5e26e7d9d46e39ab007e0d1da1b +996500 b558b1cf6b6c8433c5800f23ae615142084f8f3d928a40e409f874aabbaca98e cced61b2eef93c36342b81a9d83762f622a6bd502c0cc7dd1c0682a4724742eb +997000 caaeb7a33c8889c80539ae6c7630467e1f9a63c7ad7e785b981a407da287a641 670fffa544fc0473595daef1fabde40074c4f7044d4dc30693940beaeccfc389 +997500 8e34f4d6d0a279a37c8ba482b77251ad9f7fc96501553dab0680fcb22e6ede26 302b33d0ad1a64fef2ef8930018ada4c3c5a78c1c73cb8000c0d7761e47ee10c +998000 4d92ce92ad50fc20856ea205479db25276de24f146f131b15a84554d0aa6f9af 3a0b07fc0edc28355ff8d43ea3394e609fef61e0452c1a6dea2ddf15c0ded10d +998500 9fa48484cb1aac18acaf940acefb7e016a01f2758bea1ebce66a20ce4f035bf9 d46c0a9835b479ae3f11573929492f282a89d3cd81de832bfbf621c1f447f4df +999000 ffc5bce237b717abe7ce11f385387313ecc2aa4696c69619a5b4086a53ee3271 ff9b6e5ab60a595494e3acef825047568620b1c43e8e6113142603e7b0350082 +999500 6fcd2218fbb6bb99a7ab3ee9907cb2d91332f8050a43f540dd1b927ea7406d06 125f37d51d86d8fd684971d3ddf14658459571bd6d21d87a2b8a29aa79946ae9 +1000000 0eab5112b99ed6e8cf660a001c42d98c8080cb6366c7097eea2ff77dc1609f37 acb74f062691fcec64ec6ed73d0a383fa41a034d58367c8622fec495427df074 +1000500 d1def6c86921155cf5563b6f8c4ce542cdd4fdf9754d4000dbacadf94048ae82 6f7bd3d0026433254bb0ec777cc7ada57e9f10918a0a422dacb183d2c35ef820 +1001000 895076795aca0adde7b87924fa062ba68e78c47288b2bb85f00e7e4d49db4b26 688a346250fe2ba536b9825274d23fe3ab45f80bdd79adb081f2e94982a5e4ab +1001500 5c22477fdd5bd95bd2d21c677164d7f5f0af91b4e57c40d3a4455a84bec21e57 5ad71bdbeee74ce1a181a3ae5e6369ee464104bc12fd976ceb5f17c118829070 +1002000 19c686c9af79a78c7cc99f40e01c1b6ef8e1a2fb2fa71be9534627a4d4f9a025 658279857f203a5c1e707bf87d65c3395b687f8dd865831d892ecb7cdc8779b1 +1002500 6d44ea79ca8224f60c6e406dfe9c7b459b253173288fb27fd53f2459be869fe1 4d4cf2b50e60efd3830b0e19de7109bfcca8ef40807d483e32260b1a85a2ef9d +1003000 e5b417ad3beff6e4f8864ea986901adc70cb998335784643accb38300ba26f33 f947088aa2b8ce56cc93358c4049c034128ca2f3e67330d0881ebf49e0748f11 +1003500 da0ed4a993783299c429b78e8702b1dc731cb587a331106925a410112ee6a241 0f0c1c4ceffb15f8a875034287aabb36c185962d010699ad1161ec4a82f98367 +1004000 764ac91a87f912be6230e1b59065b818bed0579c6ecb1f96a17e7303de702b39 2ab1ef7f085464ccc0245b130d84641be08b8fc885c1f15960ab72e486834cb5 +1004500 bdb68fc38ebf22d68dc2a984407588ed9c452a7aee062317ed760140148b0db1 49563018d17110ead9266c3efd001ac2c0965f31cb08ea8c69b9309a00e08822 +1005000 98dd7428557fcb55e93aacc5ce52d4685a9ff114e27777124371bfbb82856a18 a429996bc47364fab997ca87316cc079a62290f061b8495b93a14fe24087c49d +1005500 0a94bafc026c86b317b33f8cd2661d6494b8f9b01a6931d771505ebd80ef3314 37566fb68bc84fa11fa17c73f90cbafa0ab29336a0ff0f98eefa590c7426869c +1006000 db286315d07b3d4cc4de96bf6b344be65c9406c6186318e32d10fd8d66d5e3ee 2f1984d31cf7ab600246083e52855afac8a6ff5bdf62badd04f6ec8c532dc5c8 +1006500 7ed79e53672acebe07b0a25853c34af6822ef69078c94de86137f16ef35a39e2 1d503606be0bf1c476e7154c2d632489d9b0ee7f13138a1face4d411a0e6f9a9 +1007000 98056fa1e52b11ee70eb294a962ef9288df96ea4ad8fc4a5166a58ffa67cf650 a802403c8ffeedfb9de8a5fc863730e39a06c142b04b3b88b791f12b3340741c +1007500 037eea45d7e266fe26cf97846726facb73968441f3c3b0b8f384371335ca8b54 f919c88493be76b460431acafe67adf6c2cf18ad72549b93f51934791b628c22 +1008000 0ac8cae34eadd6a2b2b4f8c19dbe7b81b3bd432c7fa84a4635ed19c8109df8d1 7859a5b85c491881a7bf6f3d0d5dd0c0dfe381e2d76295608ae4a2e12ad52f40 +1008500 903511e59fc4c13cef0ba01903a85ad56a60406abcc5804fe0021d1f364f35f4 be8421e49bd2f3e64db5309ba30e8954d1cf68eb8ead03f5f820fa88bce8cb51 +1009000 0c4432de0745d517d1bd48fb5bccd988985d77628c45f9bff545834b63986ac8 577c73b6278b78665f4315543688743a5c49ebe86f63f985e9e7989829030386 +1009500 e8ad9cb3b8e542229367fc34627ec8e1f6e4847a37552ebe2bcbc36eb0c0d955 5bab28311ec5b559f423c3e7980a1d55e5c0971682ea84ff9d6740ff9ad43195 +1010000 8c8b963aa26439dcf83d0a67799551fc5fa3b1fce2261db4374a913e50745184 d3c41f512eb318d2fb9c76dd883dde048ea1bae997bafb4013950b582d79f780 +1010500 f3bb272a4c6145fd3a142e85744d9838c7e1ea33388c5501b76f2bf3fb6f2021 015a4e570fa61d5b9cb0d8404f237d56571600de80f4e9291fd69b5f981a52d5 +1011000 e99b3e7d03403da96fa17a760491b2e627324e6e40c99c6291ee2477325506d2 59894713ba320d48c79325fedf70951bb8112781aa32679b55c49f6739d4549f +1011500 624b57fa2f3c1be8a6df1d8d07162b6dcbfe4d5b5bab6ae76dab199518c997b5 b9b72cce7e651a9beeb7a0af57e82dd1a11ff0fe4df6c7935bd67d10978b7b91 +1012000 1b26bceffc486dad37b7b8ec5822a388cc5b24d884fc6463963f1bb432440981 308612e9d27755371409af57a2e7bbb53d9432ff575aa742854b074c8ee6f237 +1012500 1fe71ca40d446eef37d4c00d208ecf6f503e180e6f55c68dbb5fcb9e3d2eb746 bb77811625dd920f9ca60331a354187ec62026d596a06f49bf6aae63ed72da2e +1013000 332859dc2b9962c6f20ba5af9d3093ee01d1e034e8c1b2defbd65e81154a7f6e de3d066931f8e54297a44e6e2d44fed5829456960c2f5aab427c460522dba461 +1013500 0e4af0f0df0ec61fa3a5af0aec7c4b4987d876be19be280f8a3046c36bb39a5b 90a3e76d69a0556ecfab5ab4ece1960353fe0040732065d2900167415b007ebe diff --git a/confs/BTCD_peers.txt b/confs/BTCD_peers.txt index 69592171a..380bfffc4 100755 --- a/confs/BTCD_peers.txt +++ b/confs/BTCD_peers.txt @@ -10,48 +10,3 @@ 67.212.70.88 94.102.50.69 50.179.58.158 -194.135.94.30 -109.236.85.42 -104.236.127.154 -68.45.147.145 -37.59.14.7 -78.47.115.250 -188.40.138.8 -62.75.143.120 -82.241.71.230 -217.23.6.2 -73.28.172.128 -45.55.149.34 -192.0.242.54 -81.181.155.53 -91.66.185.97 -85.25.217.233 -144.76.239.66 -95.80.9.112 -80.162.193.118 -173.65.129.85 -2.26.173.58 -78.14.250.69 -188.226.253.77 -58.107.67.39 -124.191.37.212 -176.226.137.238 -69.145.25.85 -24.168.14.28 -73.201.180.47 -76.188.171.53 -63.247.147.166 -121.108.241.247 -36.74.36.125 -106.186.119.171 -188.166.91.37 -223.134.228.208 -89.248.160.244 -178.33.209.212 -71.53.156.38 -88.198.10.165 -24.117.221.0 -74.14.104.57 -158.69.27.82 -110.174.129.213 -75.130.163.51 diff --git a/crypto777/OS_portable.c b/crypto777/OS_portable.c index 38bfed58b..6599eb554 100755 --- a/crypto777/OS_portable.c +++ b/crypto777/OS_portable.c @@ -185,7 +185,7 @@ void *OS_portable_mapfile(char *fname,long *filesizep,int32_t enablewrite) return(0); } *filesizep = filesize; - //printf("mapped %ld -> %p\n",(long)filesize,ptr); + //printf("mapped rw.%d %ld -> %s\n",enablewrite,(long)filesize,fname); return(ptr); #endif } diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index d1c878e13..2de139073 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -14,10 +14,13 @@ ******************************************************************************/ #include "OS_portable.h" -//#include "../includes/cJSON.h" - +#ifdef _WIN32 #include #include +#else +#include +#include +#endif // return data from the server #define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 0978af460..c7ce836c0 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -26,10 +26,10 @@ #include #include "../includes/cJSON.h" -//#define DEFINES_ONLY -//#include "../common/system777.c" -//#undef DEFINES_ONLY + +#ifndef DBL_EPSILON #define DBL_EPSILON 2.2204460492503131E-16 +#endif static const char *ep; diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index e2ec357d2..31d14dc6f 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -81,8 +81,8 @@ long myallocated(uint8_t type,long change) Total_allocated += change; if ( Total_allocated > HWM_allocated ) { - printf("HWM allocated %ld %s\n",(long)Total_allocated,mbstr(str,Total_allocated)); HWM_allocated = Total_allocated * 1.5; + printf("HWM allocated %ld %s\n",(long)Total_allocated,mbstr(str,Total_allocated)); } } return(total); @@ -234,6 +234,7 @@ void queue_enqueue(char *name,queue_t *queue,struct queueitem *origitem,int32_t printf("FATAL type error: queueing empty value\n");//, getchar(); return; } + //fprintf(stderr,"enqueue.(%s) %p offset.%d\n",queue->name,origitem,offsetflag); lock_queue(queue); item = (struct queueitem *)((long)origitem - offsetflag*sizeof(struct queueitem)); DL_APPEND(queue->list,item); diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index d69a4e981..40f2b7ff8 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -190,8 +190,8 @@ double dxblend(double *destp,double val,double decay) return(slope); } -/*queue_t TerminateQ; int32_t TerminateQ_queued; -void iguana_terminator(void *arg) +queue_t TerminateQ; int32_t TerminateQ_queued; +/*void iguana_terminator(void *arg) { struct iguana_thread *t; uint32_t lastdisp = 0; int32_t terminated = 0; printf("iguana_terminator\n"); @@ -229,7 +229,7 @@ void iguana_launcher(void *ptr) coin = t->coin; t->funcp(t->arg); coin->Terminated[t->type % (sizeof(coin->Terminated)/sizeof(*coin->Terminated))]++; - queue_enqueue("TerminateQ",&coin->TerminateQ,&t->DL,0); + queue_enqueue("TerminateQ",&TerminateQ,&t->DL,0); } void iguana_terminate(struct iguana_info *coin,struct iguana_thread *t) @@ -254,7 +254,7 @@ struct iguana_thread *iguana_launch(struct iguana_info *coin,char *name,iguana_f retval = OS_thread_create(&t->handle,NULL,(void *)iguana_launcher,(void *)t); if ( retval != 0 ) printf("error launching %s\n",t->name); - while ( (t= queue_dequeue(&coin->TerminateQ,0)) != 0 ) + while ( (t= queue_dequeue(&TerminateQ,0)) != 0 ) { if ( (rand() % 100000) == 0 ) printf("terminated.%d launched.%d terminate.%p\n",coin->Terminated[t->type],coin->Launched[t->type],t); diff --git a/crypto777/inet.c b/crypto777/inet.c index 2057f90d3..d9f216a9b 100755 --- a/crypto777/inet.c +++ b/crypto777/inet.c @@ -19,12 +19,8 @@ #ifndef crypto777_inet_h #define crypto777_inet_h #include "OS_portable.h" -//#include #ifdef _WIN32 -//#include -//#include -//#include #define in6_addr sockaddr #define in_addr_t struct sockaddr_storage #define EAFNOSUPPORT WSAEAFNOSUPPORT @@ -37,7 +33,12 @@ struct sockaddr_in6 { u_long sin6_scope_id; }; #endif +#ifdef _WIN32 +#ifdef AF_INET6 +#undef AF_INET6 +#endif #define AF_INET6 23 +#endif static int inet_ntop4(unsigned char *src, char *dst, size_t size); static int inet_ntop6(unsigned char *src, char *dst, size_t size); static int inet_pton4(char *src, unsigned char *dst); diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h index 043561e08..b39849342 100755 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -14395,5 +14395,125 @@ len = 0; printf("SPECULATIVE issue.%d bp.[%d]\n",counter,bp->hdrsi); bp->lastspeculative = (uint32_t)time(NULL); }*/ + //ramchain->A = OS_filestr(&filesize,fname); + //if ( filesize != sizeof(*ramchain->A)*ramchain->H.data->numpkinds ) + // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->A)*ramchain->H.data->numpkinds); + sprintf(fname,"DB/%s/accounts/lastspends.%d",coin->symbol,ramchain->H.data->height); + //ramchain->Uextras = OS_filestr(&filesize,fname); + //if ( filesize != sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds ) + // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds); + //if ( ramchain->A == 0 ) + ramchain->A = myaligned_alloc(sizeof(*ramchain->A) * ramchain->H.data->numpkinds); + //if ( ramchain->Uextras == 0 ) + ramchain->Uextras = myaligned_alloc(sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); + //printf("hashmem.%p A allocated.%p numpkinds.%d %ld\n",hashmem,ramchain->A,ramchain->H.data->numpkinds,sizeof(struct iguana_account)*ramchain->H.data->numpkinds); + //ramchain->P2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_pkextra) * ramchain->H.data->numpkinds,1) : mycalloc('2',ramchain->H.data->numpkinds,sizeof(struct iguana_pkextra)); + ///ramchain->U2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_Uextra) * ramchain->H.data->numunspents,1) : mycalloc('3',ramchain->H.data->numunspents,sizeof(struct iguana_Uextra)); + //printf("iguana_ramchain_extras A.%p:%p U2.%p:%p P2.%p:%p\n",ramchain->A,ramchain->roA,ramchain->U2,ramchain->roU2,ramchain->P2,ramchain->roP2); + //memcpy(ramchain->U2,ramchain->roU2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); + //memcpy(ramchain->P2,ramchain->roP2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); + + int32_t iguana_spendfind(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t spendind,int32_t emit) + { + struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; + struct iguana_bundle *spentbp; struct iguana_txid *T; + ramchain = &bp->ramchain; + if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 || ramchain->Xspendinds == 0 ) + return(-1); + S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); + s = &S[spendind]; + u = 0; + unspentind = 0; + hdrsi = -1; + spentbp = 0; + if ( s->external != 0 && s->prevout >= 0 ) + { + if ( emit >= ramchain->numXspends ) + errs++; + else + { + h = ramchain->Xspendinds[emit].height; + unspentind = ramchain->Xspendinds[emit].ind; + if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi <= bp->hdrsi ) + spentbp = coin->bundles[hdrsi]; + else + { + printf("iguana_balancegen[%d] s.%d illegal hdrsi.%d emit.%d\n",bp->hdrsi,spendind,hdrsi,emit); + return(-1); + } + //printf("%d of %d: [%d] X spendind.%d -> (%d u%d)\n",emit,ramchain->numXspends,bp->hdrsi,spendind,hdrsi,unspentind); + emit++; + } + } + else if ( s->prevout >= 0 ) + { + spentbp = bp; + hdrsi = bp->hdrsi; + h = refheight; + if ( (txidind= s->spendtxidind) != 0 && txidind < spentbp->ramchain.H.data->numtxids ) + { + T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); + unspentind = T[txidind].firstvout + s->prevout; + if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) + { + printf("iguana_balancegen unspentind overflow %u vs %u\n",unspentind,spentbp->ramchain.H.data->numunspents); + return(-1); + } + //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); + } + else + { + printf("iguana_balancegen txidind overflow %u vs %u\n",txidind,spentbp->ramchain.H.data->numtxids); + return(-1); + } + //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); + } + else return(0); + if ( (spendind & 0xff) == 1 ) + now = (uint32_t)time(NULL); + if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) + { + if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) + { + //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,&spentbp->ramchain); + spentbp->lastprefetch = now; + } + } + + } + if ( 0 && coin->blocks.hwmchain.height > coin->chain->bundlesize && bp->hdrsi == coin->blocks.hwmchain.height/coin->chain->bundlesize ) + { + for (bundlei=0; bundlein; bundlei++) + { + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); + if ( checki == bundlei ) + { + if ( (fp= fopen(fname,"rb")) != 0 ) + fclose(fp); + else break; + } + } + if ( bp == coin->current && (bp->ramchain.H.data == 0 || bp->ramchain.H.data->numblocks != bundlei) ) + { + printf("RT bundls\n"); + if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) + { + + } + } + } + /*for (j=0; jdead = (uint32_t)time(NULL); + addr->rank = 0; free_json(json); if ( ptr != 0 ) free(ptr); diff --git a/iguana/confs/BTCD_hdrs.txt b/iguana/confs/BTCD_hdrs.txt old mode 100755 new mode 100644 index f6fd2a2f9..482b1333d --- a/iguana/confs/BTCD_hdrs.txt +++ b/iguana/confs/BTCD_hdrs.txt @@ -1,4 +1,4 @@ -889011 +1013511 0 0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46 a5d211145f8e6ba0920b2893d307c5d7c207ae0800a80955299678d1706ea8ac 500 000000000680a9a697eb71155b18a5827e0889fca28afb81fcbb46469ed7877e 79f80a8f54c6762d6408347c6dd7dfd2f8b8c191077c1d7881dfc5b7ec6a408e 1000 0000000000000cf908c887020f8970b7fe952f8b81164d83a87621dfdb581d08 3356ec4296ff2f04281492b0dedbaed80edeb6dd9170b87230ff79f6b0daade7 @@ -1776,5 +1776,254 @@ 887000 51902324fddad3458c70670d38df58410ce98950a70fcc4aba475fb2a4c10554 b4c451e8d6f329db4a0d191970be6d74479b4df4615f1d576589a826cf025fda 887500 576f26ef969d63688e1ea000213b96aedbe715cf97031c64ad19c0e5a0f9332c c1ae2f4a3337bb92b30c745971a612af9e911d78bf9503f2d4173d32ea3e2a6f 888000 a67f9a20265eba880a4615aa5ed2e62c51dda0d707b65f45eee03b4fc44f0e1f 87877dd3894621175bd850a8656bbb101ca98ddac12d54a86af38a08684fb31d -888500 ffe36e4c302b226917ba2587b586115115ccb319b79626fb739ab1f4e511f048 0167b781dbd255ab898ff8c21f10f5ae14b6c6182728eaf64570cb64026ccbe3 -889000 3fae8f764be49d5fef337a07943d3419f749eab745c5349faa81aee4aea0a638 c2d745d450a820d6d8e4aa241606ecf0b855dff32f8ebc3e2435dafb51f81f73 +888500 ffe36e4c302b226917ba2587b586115115ccb319b79626fb739ab1f4e511f048 0a3fe9d179cd2bebaf9f4fe064c9c6addb877f12a05090709f2abdd570b36ddc +889000 3fae8f764be49d5fef337a07943d3419f749eab745c5349faa81aee4aea0a638 14c98ca1a85488d6878125fa5085d35c8373a461ba7458e3b689a54a13153f84 +889500 49a7936fd2f10c0c1fe2dcd9b65a0938fd4ae50f7c4ac195c6084fa067f76919 b971aed9ab7b39f4a9d42d50c714443e9be5172b9cdbb055245695c28266ad53 +890000 761f8aad21a4501b257bc29b52ebff2e27f55b0a465fb5497587ad11212b98b6 81e6670cbf8594d99c9d24120c2ca70574834637314f6ca75996fa13a2694810 +890500 6f040c12fce7f3e45c6cf2305533ebc2e740c7ed5aa812201372447494772b19 b79f97bf1e7764c569e5cdd10751ae56de90d41ee4324f9c4b51ee3603852364 +891000 945ad3b937d8e0e0c8ca33a5da647d1019b9c8e37e0ac4337b66fd3e3a3cd09e d02331f0631f106e84bdc9a77e5e4d4ff4f3456286b1eef2962dfcade867522c +891500 118403722d3ba35113e3d5406abc1daa269440550145bcbd0272a84e528da03b 90f9f71ce4b26c8cce5558f04e9b842f539ef65f16bf55de4d7003d28b5f9c8d +892000 80769648898afb23defea7a20cf1241f584c76ee5637cfc7a49223cd53d5ad76 ebdc74487afd6fd4c963f8120e760ee8b8f0f8534cbf85cc28ec67058c642fed +892500 887d6de372d68314ba865a6a1bc5a431e2f8df673742bd2fb7e11b439117b0c4 46a0ffffbd5887f14c94ac1c232f46304cdfd029f1871b1a30b704fd1378b949 +893000 8b0bacc43bfc87581959a67dabb72df9fe52ff891daeffbac58b0581403a46e5 5c472f2d80c437716aee3cbc3439ce0b4e256363248a93b5d1adbee71d77690e +893500 961d3fa31e522bbdf6cea3742ce5b8646b3fca603fd44daa57f5c10f830e4071 49e19baf811717ab81e294b95c8eeeb5d96fdd1a4cb26fda305046aeb5041207 +894000 cd17ae71de5a09dfa983f6dfcb13fcfa6d6f242080ecf3be722c72f6bd7d402b 9a26285e49feb36f6ae744bf0e89cc91a3b871339cfe538b8beeaf5ebbf54fd6 +894500 25fa66f74866b3b730f3fbb2a9f92d3c705354e71f2efb2747f8ffe1427f494e a37b7358d87c473235c3731bb985bc698bf95f6cff9a5d3e225e4d1ba1c668e5 +895000 50b47a9ba28ab1c5131ec35372be0690b9ff7c5967a81f7d6d7d5d7bab8c34e8 c6d808c63cdcdc412b9318270655cb0d37c315957dff5039d0b018ede34113fb +895500 944784b12fdca39238803ecceb354bc4e8e5d91d4279ec25792820866d5c3e5d 21129c892476213ae6df19646a942694518db3758cd2916e38b4afe436d0be2c +896000 8b45a6293b573820f4b798c57a2144f7d94bd2edd02118d44cc0c59d4c92a5ab de0a319d296d3e88d7bcc46a4cfcf93ec469305122840f5512114776011cc03f +896500 c3303636f08723508f17d63f0d376e9819e7c537d96e7ddf5bacc5cf02455287 36654846452e690e6b833d5fc2d4b6d402c5fe81754332d35162ea65b1ead7c2 +897000 6cf1a830afc57e6d8549c8197e90839f477113278db181bba75a3ccb3cd0718c 387883d5fdf2362515430c50fb20dbbb0ef24c387c3b6fd4f21be58102f4f20f +897500 323544c069e43993ba59d272db7d92d8857855f67cecfb03afb9fc6495aaeb98 b006d9690b7a362398d09b5d5066bd8086f36863295b5da7c2a113035852ab00 +898000 e303ff088305156ddd6d2b5d0c239e459d5175585902840d3f6713a40b2490f0 4504065e186d009dd784aee6d957fbe295c8eb1c3bca23d860a92c6be32a9e16 +898500 4400aba3a75afc73ab3f6f8328a179905fbae533dc9a75a67e8533dc34da8281 f78290551a6f5db3989f2c6f6087b5746c0419604cca77a8bcd63268455aff2a +899000 30d2245ee16163dcab5b9b71fd37c6e0a1a5a3924f621dc4bf2213702878da82 83f95bf132b64bfdc4bd75ca04fd972d5caff941d36a7792f55f478fe140972a +899500 f35505a5677e09578cbfc9c7900bc40b1add13a8df9f70781a95b00ff972add6 c2e16965e43b94444853f16cb48de52c406448aa65a2ccbad61163a18f2529f0 +900000 e37b70b214a685698666a18c3de3362baf0bd158b6f972e77bd306e62e7e4bea 7a6f099828ed54a20b3b9565c1548ce0fcfa4de8c6131ed4caaa629d96e17864 +900500 a2473a95b679ead1011918bbc526ef833ee8b03a5aa3f3e11198e30d11d2efae 9736c820b1d63362019d39a77218d604205e38ec79a117c117ad12d1dd1f0075 +901000 dda19f6a2f7a7da12753b2d7c334e3df7cfaf74a44ba8304b3c5f5e05882afc7 bc0f02a893b0609aa80e08392cffd1ad14ee3b625837d16be6869b5e405139c2 +901500 5d1585d8239afd15b1028bf7deac725db26ee14e9f611aaa8f972b27c8f8dc6f 6f02fa43604aed757759d0116918538b094641c0cb9f66d75ccf62458139c5d8 +902000 433e97c928b52d4964e08193549e6ebe938a665a0fb4bbea22307bc94c5ebc73 6cc41a90d5140aece6e637d823cca6e4bb96fc7317a4d603c72fabc7f6239cb6 +902500 4650e5d627e8526ec617f4f8c5a31bfb8ce3c6bdb2d10cea58873bf361cad4ef 06acce13e151648075467370e9bec6864b80189ae6efe4e0e94a395b4852fcc9 +903000 3f9bdecef49c48d9d259d75cc8d8de5a09baa6b51aed59ac4cb9661afd4ee856 ecb871b85f6e41259176b80cdfdbbca72a0e5831c0ec4d42dd90cfa361f2ea32 +903500 38512db7f3d831faafa2e27c548d9f10e08176c8745fceeb56a59b4f1ec16179 cfe52056c802d202a734e35fa3693c77a8ba3a8f0774b76b9b2e9d962687003e +904000 56e1e664a1de1e2f3fa285ed05c87b89a1db02aad29d4aa425d4491d6b502bff ffce9af2a239a9b97ab7f571269255fbe6bed14ec448078aa1315b1d7d823467 +904500 62ed0214dee8bd914f40e07f60d0b42c2838e060aaa771b39e3fad5db4aba3e6 004bdff9bea3fb7de4ed18cb1a546bae626f03adeda035d47fc8c6c7d04fce21 +905000 02c1fb3064dd2e906dea5b09a9e9515ffeaf4a8e6290d213adf0328aa310e023 0e8364f05dc947ea27a36adb21a97604d9e2fac67508a098f1c147968b7f9341 +905500 013be02154184cdeeaa19e1e3419d4dd5f63991ad93362a2b4fa2e49039e9beb a12d791cfad9e6e291441245832cc82f7887902d4112108b57ddf584ba71d122 +906000 3b1787f731829c85e9888fb9bc683df92ca34b636a1aa2878106d04e4d1ff448 bc52cd21978e040a67220c44f03933086337dfe37f69cc3ace07f5d8ab1b3474 +906500 0be9d3396dc9be557baf880730a8c8c98f0d008ccad020b54ab2f4d3ac5b2bf2 79047ea467c9ea723cf97796ad295841d72b866b1e9b925fe363f99071eb9ec7 +907000 6e80e964c740b9b31d2ffb3939b60f86d019bee6af9c3714f3afb313f659e9da 9fced4419a17762d628a0fb6efce506270556b2b041eac626ed03b923e68730f +907500 7f70ecb783d1d233ea3f331fc823479f0478d4ba40e0b3e25bb5149307e688e2 06a68c9ca8e4e9803d7d91072c7b8008dd77da2df6f1a329f071ab497b16dcf7 +908000 1bb873cd795e98cb9b30c692846a31531cc7f4ce5a474a50bed96e2061e65e17 0b269ad251a90950543ba4657bd0044258f3bdcf6c50d4aac1c89d87499d1aca +908500 c57c7855c97f82ce4645a2addcea5145c98d1cb9553d56ad8909d43a29bdf320 b97be283db5a293ad45e219ce5d9c8287118d7daa887e25eca7914ecce5b5db4 +909000 340e921bae13e9a770996bfdc6b30d21502a9dbd0016d2cf0a60d299e01b55c4 50d0d76f836bf9a1f6c807cfc9512ce2621a7f8e8d3215310d78222eff1dcdcc +909500 bb00fca39de21c9b3eeaef52a0f3ed353e63f041c817977b6339f6fa1c127827 69b6dbb417be0072ca4ceb44d11e61569bff4161834baaf439361c0b17eef028 +910000 355ed393bdcd6c79964e984b96df10eac86ebbdd70652985e5652175230e3f24 6be87fd1fb578588c43235926805d8740eaf1fa271ed3ef54e1b830a976b85ab +910500 cebecf803381bd5bcfe62dd27d0fc46b34ca7f14ebbc463ec770e6998a1b629e 6dca0680947bdb1ba9f6f2ebffd1475d18874ccc79ec26b75134ece99dee8c04 +911000 0fce8ead8161e060242c6f7a6003c4de749dbc1194d8efa84dd22daea8cceab6 649a3e01e83b89631a710906ed025cc0f67e8ea52f11e0b51ab3f8422a14de46 +911500 6e60193890cf91c0dafce4c0756a47c2d57b70b84723bed083cd3af287d82435 b12f27c0626739460618af055b57710d241bf473d10c209edf8b10300d64a119 +912000 c612c0ef542a4a95bc1f45d8b5992c5bbd499a0204d057fc5c3b8c6052b0bb48 ef4f90f0e2c4a627416f8c7b590c79a4d030ce3b6ef7040fa8dfe20d9b1341cc +912500 4e8c07cc191bdca3f15f8e5e8fa2a0ccba376f23dc9618991f9fccaad35b1694 6d2cf50ef5fb9c21ed59b5669566dc625e1a023ad3aefb75351c4e96a2df4222 +913000 fc9fafc9d5208d6507d92462be6ffc8b3acebc7d3acba2bdb5f5b1afae779ab8 bc2b997013ceeba576521c5a2dbaaf429b9d6eea2501947de4c696c2fc8083fb +913500 928d12b4332252e7216fbb36d4384eba4ffd8bb79a50667b3fc15878c7deec76 49d8085c3c7a8477fcdb80af39c1abdb69f5a0366e0dac79bfd30439b2f293e7 +914000 7bf600d26589f7dc4cf0c68a9fd820b4709e95c864c379b4e5175b23d518091e 6e60fe7892f34d0eb38229ada52332a8d1f0d120de231e404ef18f319adf5715 +914500 8e5cf10113f76678cb5265e293bd0365012f0ae661e58e6998005c96f1ac9869 5df5fd9760d67bdf9708867bd15b11fe60230e125abf2db4500fd7db945fa6bd +915000 33ddfa347fc55f5b299363d8b6bff03dc1d98ec1041236e66babf4023d3d52e7 8a85853ae490805462a8aa3700c84a276cac17603b3dd0002c54490842cebee3 +915500 afba8520a990af275a8d1f82de844c793547432b5c6941e1b30859513098758f 06ceaf9f70d81c901054cd961ddb15b5399fc0f19235c048649ff24bf916f552 +916000 fa8e0f7e4c73fa9914b795af620ee52434bf37fdaffba88d318af058830dd361 41ec81c005795442c4705e943715065eb89cb4b32a2f38a311cf643b06880d79 +916500 2b20f9d73d4c0af59212b3bf8383f845c95baabc51df6db044ba80fd5051eda1 324489489a55e3767836aac9d5b620f5be775806ada19f27a61671a94098f269 +917000 b7b20466d119311d1c85ebe1ef60dca612ee14b87e88d633fecc679d00b959a2 96843566d7519919c12ee3cde2b4793e7043a066f63f3dfd690638d3b3d2bf5f +917500 624ee2db152989d3e86cd4bdd32e84cde6f8d0fbc556561bc690c8d64d95319a d043c5740ca03cf42a53e4f8abcc96dea665a16acb738dacf29cccd3721a9081 +918000 eab30c35d483b6b8d4ac7db12c139b294c9b9aec8d4c0db627f57586b3d1f6a8 121c7b5a220fbcba9735c6ce0425ec14d9d80f75bb498a986684c446ce8ea2c6 +918500 e9bfefe8932f66486d1d3a740d14b1fbab1fbf80b5abc9abb4af1333efada148 3909b21ceddd287e2b1d8cf16accff743dbfe6c2c0a0080a33592036cae626ca +919000 4111e02c00666bb2701731d59808917da660228f50fad0d338d31324219fcd2c faa3d00c409b5cd2cac4bff556bc5d07fe901df0b3e6f1e1059e661f59dca640 +919500 fe8ceefd0657909d523c68ab34109db47c31a56d96190f25eec23ccac28356ac dff9eadfdd7da200e3f9ee425b46e6f1869c2947d77eb068d3de8e281ccc9f33 +920000 94c0c84e0720cf98585709161f8e0d52106a76810c36e8eceaa50c5937423e31 985aeea9e4d2fa5b24727c5bab4979f7c181d52e1939f5c1e9b9fd9d8d21ffa5 +920500 7942c1928c1c7fdce2a7f9948db255a58ac28c650d44f2cbb568b14b7e77a869 3fac2092a646a391bcf3f5a3703341b9667c9dd1800148346bf3d0ac8eb0b8f8 +921000 3ad13dc5aa84d6f0c89d4c1d4424928e1c3f17def687432e3dc5bc0d1f748e4d fc66d327154d4f892c6fc8a1a766917e137dd5ac1de66a8e93a1e3206318133f +921500 fe4b447119ad825c1f495dbb58a1aa394eeb40e6fa1de1ddf72886ea69042eee aae2951a99bc6f730c70d78dbb6486d95d432b7fb154696f0e866b5e661baca6 +922000 7d1d205b9c72f860b446b8b254d1c22a8e5a5049227ceff04424ff01761cc29a 9fca8ce08cf17dda9b4a2695096a50f5cbd54c8c11f7c048bad4e27c01a7dc9a +922500 c16ad392838d47ba7fcef91e9a0be7cfa1dd11d22c9ccc0b6f631aa48abc73f8 01ccf18791d85e7a78fdc9e751948c42a6d58d9c4fefc118cf882c0a5bef2ac5 +923000 438bd2d6867e38f68f61f9dc64952993f7492e39771516520eedd7d5d9d4054f 40b95ef95e78ae4c9e99865bd4e7a4f7d106c8d2aba90f54aed550f14aa9ce17 +923500 6c205a2902c4c350df7de4e96c6815eda103645b9181fd9e8bbd6e53b5ed843f 9d8c87504c9db8490188c7d8fb0e6aa1950a03a80cd2bd0f8baf0297a73ceb27 +924000 821de00a7dd17becc9dc0ff750b9e74237ec391e9e2effbabb71d33fe96e574b c87cec5b256635170e6428e3040000d705decb654b84a7ac9d1566211e18dd36 +924500 fc66fbb75f4f01611cc4bc86249e329e5f217ec40e0f64f332ef508f4d524fa4 1a9d440004523707f292fd87bf077df59c59e3d39e7f799604765343197f722b +925000 b290fffcf3f8eb763704f79a4a6e5fd76a853a3cd013efe2e41fafb9177d223a 3d9b89cc34b988fb0d1df0135f59df3495da0221277ed3abefed3558408ee132 +925500 3a1fb804b8f62e4c394b4fb34b250986d195b4a066238eec560443219bb06a25 3024ae8c2825c85dfe675f2b66b4576a6ebb934166dda6a12016fa8f79f12a63 +926000 819094082ab3ba4c3a715880ca1de8c9b7036d68224202838a077d1c48a0fa33 afb6ae704efec0cb30127cdc4c608245d88b3bd39e3f09b30273420046051679 +926500 eb74c0dd62c2e8fc7e9c45545e190d959a6ca29515bc7775cf20f2bce27349f1 13849b250174a3db106e2184f7621ea88b2e6b6fa4d36ebb2353cd7fcd0d4a12 +927000 6397314f6bdd9ef003cc2ba39a4539c1e2267b13272c78b886127419a1edcd28 3455accc7f9a3e2324080e7691ba7134f8a6a3d6b0f59ac8ab1f8de3b1db976c +927500 5f1f6df5959482ae36d755bb88a5b2788a0f6e8ce6e2d62811da77c02324703f 044a874fd1df9bc0e384a192c669fcacc6946d2ed148bd5b3cae0eea0ecaf625 +928000 3ee8e52f1ecd00dfa60cf89435c08ffbbfbd1e0f9596541cbcbef38c520cd71e af25521212acea8f5c894fb0e2c0f38a4abee868b66ed124a77980e5ae7fd840 +928500 c3f4c0ddbf8dc7a91e5e27e3bd4d8f817d18ce724d9756354449d7894f96cb7f d7cd61faaf6d8e0b362aaef72304bf0d1d8d751b1fdb6e8c11482fa5b14c2045 +929000 73c7f82ac5c353490479945a8e5a3528e85ba4276e3c7b5b359ed66f34006d68 9def4754e80ad70729276465a92e65e9d70a3fec02ce46d76a6b748bbf19180f +929500 90838c6bda7f6f4a9964c3b99caff44d656fde4928d526d7b761aade9f6c5a4d 43be3d47189799a47edbe664a2e9452e57e7ecf8f5df272a5090552cce912ac5 +930000 993167ee131ed2e0875b7a764cb7e8651a01b44b85b4b40c16cf8b69f0754029 5183e99bf7bc05a09fd514bcd646aa16fd040d8313d5c2083291d350988e99e7 +930500 53525fdf3fee3ea4bd860ca7185365312b74dd8cc1e3f6397f3a467f2fd659f5 b08fdc19e65d7ba7a01ae37de9db8065c344f602cd6811a6b0fa7efc22cc9ef5 +931000 310257cecaa31778dc0ad056b4d0ba181b0339630bd9a54f1d2c01241546b648 e84fb5af344ef95707e5060d1675d11e8b7373524227fbcdfd3a7790530b9eba +931500 8f92f22fd3d4d35cd69456574605c6463abf15a58bafd4fb2144e58b2ae60bbc a05d6abd0dde92b9e65dfc93c149ca2f6ace7416efb996cbe4a1eb31d4add968 +932000 975a067e94d2f89f81945c70161dad251c93387934c9869007bf17f9f8175f66 38b53fea2e9bf87fa3f0478da19edae0de9444e35605e064e864f441c6531ec1 +932500 438ce459632f23fc45667091be8a8a4247f6f83500e46805a7a63c72fd674b22 aa7fc841988e91577fef8ed0b8b134e9261d1f8afadd12aac3fe7a39129cc393 +933000 07ece8e5df3457f385595c03d9abbf7b42654e15548ee72fa01b7c98d87fd654 de3e7b6128fe92260b645119d9aef6a57361cc46ae6328c4752cf0feffa7e93a +933500 bdbeb91240264a917bf44b878b92c09c6a15005a39d51bd7cc4d6d401e1e4319 ae3181503323e70a8fd2a11ebc82decaaebe409793fdf43f8fce394b17dad188 +934000 f3bd01e5acae46dbfb3365f3432ec1c81a2cfdff7cc6affae91c109ef698615e 74af995d48d047894f0d544423ba75d2018f04d928c6e7e468115bc9d447317b +934500 d1518129840b5977d13fd42440c257445bb31944c177691c8204c6babbd58f46 c270324df573701c0b3e41267557932eb7fd68e46d96f84e1e302b6e336207f2 +935000 00f16b56da0b5e21f74c506d5d2a1d7a10f4403e6feda3b75b269b93a7b8751a 85b16fbf368e56074baa64cfe454fcd4d387dd2a3e4e8dfee7de5d65ea7a423c +935500 bca2a40ec3e783714d2dea107f8a35cd01ac37f845d78181e79e88d3770b9192 99a2c6c0e33f5dc75a98b39100a26426408944d396bdfa5302fa0aa8df340f2f +936000 03e8bf996ca3565405d01cfacc215f59481b90ed44d2b8329379fce0967290c5 7c6c2acfeb309f1fc6132fe8a812310aef3840b6af2cc1928394be16105e253a +936500 36b9b71a5a9d854eb5456a8df936d8995f40520173c81befa852db9773a1d26b 53733cbe7fd5a371c8508291f8d2ed3720b87838f3f15d3db8c16656f722b5d1 +937000 665e5bb5ece8d808b906d0476716f2fffff168696bfeca1b5483c7345f029a7c 801b0c3ff2814d875ba2f1be4f26abb060fea42ca9190a45275d13523103d015 +937500 89c15cc1d22a312379aad5255d2c965ce9d466a9a308052fdace9d955878b03f e1b6c64abf2b80105d8c292532489650af97b6de6b6362ca8d5a090e3fb6e930 +938000 69263892b7a2117af68e35c3e6f5ac6de567bb84d10d86ef9492eb31cdb78e36 1db7af4a0cf53f0686e7ad7dcc15076154d06e9fd8ca256fef101fd82a76adda +938500 031638da90c052d869dc3da33fc044507e0831219ae121e416c10cd8ff5c25fe 2e94ef6c5ac4720c93b9389a66cf999f22145751f58cf13bdaace6d5b1735344 +939000 342f820c0656c6e11de2032ca29247575c0121d8414c63e703c486a5662fcc00 e23bfa4425b2d940da54a62f26883b429558dbae605a1a762be33a5aa18b63fd +939500 250cd72bd19b23ca51479cea2a7a9f4bfec67e343e250cd67b6727baee2d8520 b2514af432838f255641352ff93268b990c0346997e2c11e93987dbffbf50344 +940000 1fe1cf60f5e02ab75067eae08e3f8c71e4cff03d232bf2f2c6f789ef49dd134c c4b2e8af2ad3c324a01c586f22be66a30dce34d76e05c9c8296b6391cc143e44 +940500 37fd0de5d9900234dafcd91f2800fedc4bdd5f5f77c6091c5007ea3f5091e834 257db0f9e944de6816c015102334c79e531decc0e89396c49ab043143d557ae7 +941000 6751331b479dab2a45ccab32a8df6c5667df8717d99bce3eda9099d5a93976c3 8d3c34ea9311963d4aa20cf0c35c17d5556c926589354d474ae4f89fc7610ce3 +941500 e20ebc38059a946e50e5779e069d3598de8677e2974efac3aae5189904ec9b2c 7d08a1657f10154b398f06cfba601c5b8cf68d0a70afb8b1905ea8b9e449ae43 +942000 08b423776e24127b4db2d00a86ef3d23defa5a94ee9e8a8d04723a0061c80d09 94e541a46a6d4c989c209f262c0c563bec8a6cafa3bf7a61e1bf73008a3ccf90 +942500 e99b00e621c453bc93e1238a8de8af078b2cb639f185a7061fe7b1d97c66b6b4 0fcee30b06113c4d3b1f019e57cc19c5f448efa689f5a95f041a715c115deea1 +943000 dabc19a6f8952c1f8c2b4a6ee8540d91c59b54a953ab93071f026150cca356fb 66da69070bf359d355715c3f66470c0711470eadaf3ceb1ac80648beb4265b5e +943500 efa86ec88589aa9853bbf58b7a66708f52d72b32a43901253b48ef89fdc68195 da99ff838ba09c7843aa05dd869311fc058e9a266ab3cb560e4c4ebad30bd6b7 +944000 2f594ae136ca24d6d073e29d4a7278134ae0fdb782e823c2fe6efa9ba8c053dc d285a29599828a65ddaad8acd888a3030133f8583f5618af616c3637c3778861 +944500 c3ba87169f55a8669f3f2c7e94df26be0afb0e810104dfb2fcabfe40847eb644 e028eac5db8fb1a565277f5587d8ff105a3f4523946a20a3cbdb16e7eebaf586 +945000 5aabdf7dbbf96f3b9136f7891335b4b4d2ded4a4ef4b15aae24400ce7eede6d5 a791d33db0c6c72fe407c3141d954c7b6166964cadecc7fc7d9d70a05c64f5d1 +945500 160513624bd360141f9f2aa0b77e15f2f78adffde5408688a3f5cf2748f5a33e 1978fbf063588d8d5c669261b70e569bb5242c67ea4b896e4fd273cd5fc919e9 +946000 baef0350d326a00c5724bbb63a3a7d12a8463d59407afe8cb775f3282dabe66f 3a08925e17e7c91fa44526b13304a55ac9344cf0139d6b2573fb362efbf6e2e1 +946500 3ba6204f144b41e18b5f571aaddd7591cc8a2461790e23117eb263def13a409b c72dd099c929527f4916ed7dc0cf34d3c4b98a4ea8f488be7b92980af42ba4d3 +947000 1bdd194c738e7fdf54249f73177a6c78104e06133d0fd97d2e732e86752d53ce 45f323adec9c4eee2e3ca82bbb2a165a0a94db22d3d700dd34688fb2575343bb +947500 b99a2375ff79648c98fa232d1b0fe37759deb5826866853913e7ef1fe2eb65c2 17dd7cc2b9689b1b4ac97ec835fdcf9ce80cd5728d2d5d2a14883e382e182f51 +948000 de7bbfc82a59fa0c6691020204c4916b9b102f66536e061a3585824472bbf2ac 2de0049ec5f874e752ed146e2c7edf63f6095e53a8a349ed06c052a341d87e1c +948500 ac2e0e3c131538ed118a3123795a2fe51803a11c3b4b08a7e47981884b2f62cf f870ed2d50bf25f95cee956ed54551f4b3e92d54abeecc3f0aa5cc15c5b10a80 +949000 e1e69e1b1b21e4f0a18b04ac9cfd9f8285db96ff6f4e9ba2ea5a454d7b4a51cf f08f455608a96421e2c42c6fb44348331ded8f44536def80ddc2aaea53f811be +949500 5be555320df6b2e99d8f77952bb45df07ca3f9f1bffe4a4800a156af93d0c629 989e6b9308da79b0b768c6216474a6d1700eb89a59771bec804e8caa61089dac +950000 e227fbd4fabcb18eb1e600e30654fe09de863f77f81c7634c2815bdf909992a2 5c5fdf4e2450ff02361822c4702cbecdd0cef3c818ec819a8ada6c7791516396 +950500 9c0dd1fb0034c4a92f5b77bcc7e5818dcccee55af147ec6edccd499465ed8502 94d3663c2526c1645a1e7430614a665a7f35183275b7167c5893d6b1fac7b530 +951000 2e932c87fedb78048a70c47b4f33425ac91e5edf91ee12421a4dc6675c50b084 2b9e81d117f74eb48f91f5ef0c75c345f0d1f8685b2caccdd0e739f8a4d54d04 +951500 3d14b8f5c18082a279d433595fed521d134c844ada0f144595bd1c6c271b02bb 9b6803d021c36acac84246ff8e5ecf486a40de03cf3f256b91dbc1020c62f772 +952000 f1d7b3035d1b4a3ca9bb76325f8e09ff28baf0c0bc02d6d02f2f12e09cb25bf5 336abcd43c7b1c697e751756f24bc499eb5450d9d6adbe83b01233a73587b72e +952500 09ddfeb92d32ba800b9f715b8c2148d283e4fd0bfbd1d0fb1a32c2249dd919c9 a22209348a5e34a49ff2a9dad503299d59877783d47d5ca6e770a29a07396adf +953000 613e697f705fac48776f20e3f1ead078e683ba3b5ad72ad9867e14be2d28cecd 5d74a3b0feadd5f3edbafc529ee8a086eb81cfd9f8588e12ec8631eacb955600 +953500 f9ab20889ab4c8d6f7dd46411b80f89f3551920684d8e4b1d3de88a5dfcfdd6f 3b4c8c9739de63889bdbae40394a5e0bb12b982a5159e01c32d005e31ba7b4cd +954000 01471d646b617bc8199e95555f46f2893e97502bf541dc6dde371e0ceca8ddf1 b805b91fa492fea176eb197c88526fe225f18a52196cfc3da37b8850eb36e4be +954500 c26bbf96a0ff7d8d6ef2d2ca911b2c8f649be385be4f526753cd5776686f9683 e22b003c8414dd5d24dcbd5882705846e7391883fee7252d2f0019d0f066193f +955000 2812f54afa9234f02d0f89ce067730047af24ee14b3c380024da7a6567787b3c 3a796a63e0dfc3baaa249d05553a993a4bae85c3ed54b183adfbaaed1a1398a2 +955500 9c05768aa95ace543246ebb963ce1548cd9e5ddee7a6f5e45cce1db5c47bb2a7 c824fcfa5ae174f199cd91ecf2ed8049716e6d7dcedc0cb4be2a3bae035aa6ec +956000 769586a0e2d78803ddc48d46a6477505359896a7b8070cb55076d142d9360ec3 69a7018a58df10204ad1f874a7d652185e74bbd75d6e6b29dfe6bce759dfe945 +956500 ee555f15c4a433b4ad77468b6dad7560838ceabb56fe1e67076ee0e23a2e5aee 727ffc7586197dd0e3929e7641f10fe84c5b7c1255a4075496afa76cf8a4a473 +957000 1df30e4f986c04325e299cfb1350dffc76591f9ad53b40ab249769b38a1488cd 3e689b1cb999a8528c0fb90fbe51adbd0b90f6237a80169b49991a25caa86fea +957500 0be5166150c2dadabff827efe2a7e1760807aea08f7c0c5855a47e9cea4149c8 b8c9f5d0a6b7baa4947e6bb898ef1ca502c6c77fb6e1abcb58bad5451bfaa94d +958000 05d2d2d75328dad0ecf43961e0b52b227ef311a18576b2a2c58f9a1fd4844aec ab2e7a9c7bac8c39a3bc96f989afe46468975542d8186cef457c9ad8adbb876b +958500 a06d333eb4fda03d0e2cbd27d8d415e84d5da63d7e5db371e0d5b2744c32e625 7b093292ab44a6f779b5ed00cca79a1bae4eb79de2cb150b9ed38a43e7deb57a +959000 ce381f9253633f9d2b48b71987f9827e5b8d68d09bc55248badbbeb85ccd33dc ef5fa33efab771f5175bdeb4ad9f5a0e6b122f02d47fc5dfcf950d467778a23e +959500 c6e95e1ea44b4e47cece003fb1e8da01479c0b41de18ed008e1f6746f208b75b 9b6c1ecd301c7dce7d5c3f0da8c4e1e7523570aa387c8f3c5006a55117fc5420 +960000 bdb90de7a26c79d8559d48f9cf9acfd272a2ebefe86c78e11759a9614e5f2400 5defaf36aad68670ae534577435596269927ebb28ff6daf25e7992863e048ac4 +960500 c8394c48d68806fade6e2d1b27fb16f1db969be718c19151625ed723c4d782c4 9074493aa1e6b8327a8c725279fc67b90dee31ebe94e9e2431ac9388f8d6b7c3 +961000 9177a28ac1eaf2190c6d3e96bbcfe1ace9cec8687d91c5d1ef6a51d3133a6251 13d00e3d155f0535894a8a170925f592f63112f285d5859b05119a90d6ef06b9 +961500 7fc9e7b2460070aa7de93a059e74f220dfed6ca9d60784f305737f4924067658 d688c89a2e08e78cf11cf0b62ef92e4969f934a53ab7650a09b3178693f9f4f1 +962000 92b750fd920737b637e87ec6ba242570e05c24805a4c06ca6adfe72de1cf3cca 79ceeaf812c0d470eede3c04b06ae94cd14e3569958bd0e7ae4ab4583f1652a9 +962500 4723dabab6846111db863946410887489b0917f28b6941661d38150e80045834 2b5b5f09f42e8441a73d1d69ec1248b881401b23610153724bf4721158a8cdf9 +963000 e7718854b1a117c939c705a60d706adbab7bc1eb29e18b3fa86f6f7052a4ff5e aeff06b67b31c015553db2a96db0360e61d61e3ba03b81622a2f6535540bd431 +963500 64755a7e2fe737d5c50c0294b03ce6f11cb5ec07f55e42955c5e0363f371c5ae 3d5d8c6aac6ecff5aa8be9a984838046bd6a8c591e0e179ef9e171b1cb04869d +964000 59bd046c3893cc35c97f871dfcb03988af640790f5b81bcd37720fd13a4eafff c0dcc142ef875e0a37f250ebc98a96a50671a4f3e36868d2b6e3782be04c275f +964500 6f0dce76e2a057372de537c19e9cf8e89261cc24a56b30bd3cef7d9458efae79 186d6eb95874086c7dbede1decbe52e2ef4f9bd7389ff5897d40e5d63e4fbb97 +965000 6e7d4ade21bc5b59d50ba629a0bac97eba1ea1c22b909d55c62115d83c48b0a6 9ceae7a7c366ce13b5903ef59ee5a940c2f50eeb7ed88e1b5d3fe41f3d5cc8e1 +965500 07073df1aab61b4e7d6ac4e3a47cb41266476326136ae32a17e63da2df0eea3b 8bba0ae4edf8a31f1d3f2eb3e2bc8cf89913e3588470c4c26002cab2533120de +966000 46de91c0817c0802081c0382a111d4eb0383e64cc412e20e14925ca8256da92f 4da17f7bced7a0672c7932fffcc076da613c82178e51618ba0d051897294a49c +966500 5d31a7188d2e344852c1cda1fca474397652e623eb5160cac91f0765317e1157 4dd7385532824e90376cd8b918f5877e7d65e7826a55cc5eaec718f9959ced59 +967000 ab1b701b49ea5a3d698a37dd97453251fd53b70ff008b8fb6b34d90c30298e07 f4d5279f7270a1277967be4076aee31ea3553c8baa7229456ec833a974713408 +967500 fcec3fe1ca40415a65df82b0587f4ccee3f121fe82592d724de22700399e38a7 c7fdcac6633aeb83f348ab7e86341906e3f30c84422c33b1352e96b858dcd2bb +968000 9b8ded270161eeb47e94caf849655c0930476f6b73ca1afc050f35af10103e47 3fd0c2e552084120e2fcc8b943e734d4bc1a60ff598ce4365fa8a1beec829381 +968500 0845de27097e020706a6f139763ff199f0d665d00567812507bbdb4c4739a7c4 75003bbc6f63a32615d906f51b0e325f78a3281c706162f24d3468ef42d0b2f6 +969000 f92cd5a018e68cbe9a7f4da90a101409966d441e596d102bcac073828c13cc11 caffbbd1f4a08e8b23273a4ab7bcb53ad5c1b80f73925a18268d2f17f930d1f2 +969500 b08c175b0d02a58d410f0d9bb296059e5478c58ceb35259b225ce26c58ec2ab6 003d4e578d4e99ecd8d1b569535e33d57e5287248eeeefaa97ad0487f8836f15 +970000 391747367a3e4346b56c97953d6fb4fa89473d95429e93a75cd5844ffe846812 9af7f2fb1b4e414d796c5cf0d2324150025e5366e8db18cfa5ad7804956e4e27 +970500 caa262b1741e47d85bf772b131badec7e12319a3ab8a617d9f57d6584360c2ad 293f56976cad2572a3c4b77266dc83d0810a915c1b9f4c4dad5e1cccdd715101 +971000 ac906e072ba4a6d698d5581a7ec46bf277c76691314d3390188e86b68089190c 718aa15407bea582e47710421ec160dd724f9905a088d83c7d240097501ca2b5 +971500 dd461c00d3aa9922d31abdaa8679ae8bbd75b8aade9a7f9e0bdd0174bb81318e 6d4cf414e86245695ca9ecb3a4bc3fb9b5896f3348f4e9ba916daac9133d7916 +972000 099e80a3f22cb61144d56175c2e423681e9d5fbcf8c82743af51019d0123b21a 2ec23f05afd3c6f60376c4544414f84617c48f368b3c1a1b7b90b060fbd27018 +972500 eb380990470813b19e97939e36bc7ec145ed5bb84a5c15a18f53d8c6c399f626 b7f9eafe3239574d3c22e39a2d2a62b471b8a7ea59c8570b206fd2d67b23207d +973000 55ddd462f4830ae58cef001b80805828381fa6f01763551fe3bf41c47bd06e33 48e54fb3fa548f31b6b8012129886ad14d438d0e6af6a05a82230ef00d80905d +973500 0a3ae4c2d5937527041e62d202f1f3eeb575062e464a3566f6e3d4e9811236ba 5fdd512a86c7668309807bdb7146dcaefa13813bfe05f812935dbba0c7c04d62 +974000 55e80cbd096b8eb1df3fc9fdc1a4db0685f135deef48c22236a3be1df8d075af 69b5c8b41f2e5b28a329e3cb10293ba29312c252fd97e2a6e9257b2cc225354d +974500 57983b1af96d8dca16423e30c6feb4451abb992c59eb7daac3aec47f0c10404d 67c8b4a9a90a48fbf8bd43f41d290fb38c4318f00d177b76472d176fa4960836 +975000 789decbf3352b728ca2513866842487ccc080040c301c20e219a6169af17f8ad 8cd8670e216d098ef817bc6f4ac83b0de623fabe5b0bdba2bd588c28b40b7b04 +975500 e4955374301cd615e606fa045946f8e1b09dd05be8d4cb90ea334e1f0bb9b0bc 73bfca0d4522e57aad1864c6659e0906da259865cac1fadc2d4c8aed47f23a12 +976000 911ee9db7be3ef0f0932647a9ce131e21d7eef9ac7c3a40fb9da8f3d328a3313 a2d82537257e03c3256edd144045b2767b844046c07dcb75122d4100830f7800 +976500 82038a79a9cb494206fba58cc2903270b915d0396a2b3d2dcfc00c5bffcdccec 147ca1336392af0bc36504c629248081cc5abad35dda21a7c10be10d2850df55 +977000 92456a662c9047c73f7083d2cb6a9bbd7f484ec5eca845c3a23362dfc9387796 9700bed9001c1f54a9193337b07715abc03c91d0da1da02bfba14cd22cf7bd6d +977500 bf8914d9c6c6b33e67c47ff6100b7f026dc80f11cc6bbcdd91489f68887a68c1 8093398e5a2f391a3ef245664e6222069167cdf90491f84e9899eec391e01f8e +978000 b1d888e91bc2d0788175d1167c270dab6bb1257ba68bd0f8d1d57e19788a71ae cfb5b13f8abc2bfd9cbea92a9feccda90f4bdb96861e29d6824d6abf40088dee +978500 6e5e3a0db764ba19342ffacc3343df6000afc4fd7ee8aef59ff7b6e933017eca 6d5b50718e56fe6f6cfd3bc8a1c058b7c9cfbc7b6cb4701f1d2049e9401f5c7f +979000 8ab1104fca85862d1df0ab6edb7d4a001962e612b427f7814b83a3e63a56ab39 e8b74e9b60ace577954c8eb0504dbf1b8e5c0dc057d438554c156878d6924a11 +979500 4b5c03ed2fa33e96b1dd3be6646c65adb5bd35a3e70dcef17dc6eaef44f7512e 1c899654861cf5a3f58d764f8cea03248806c5de89594eafd2a42d084c546be6 +980000 d6dced594593bd65bdafe4f455f97c83aaaf195a195c327275d358517276cdc0 cb73280ea478de4ba35c27fc544edca9f7ff6bb3a0c1a0b44c17452fc61f8a11 +980500 a9b5fee48434bf6d6062d4c3f62403fe8882716af75891ee9de40c010ff4984a 50c67a1f249e74da33887c715d827f8dadcae23627c3c01cc3c86e2cc332d3d9 +981000 e49a842bf035c8ba0d6eeff766f7674df57bafba5bc8574c7ffd55a1918f4e07 3352d7d0d6554aefd57951186ffd4a20906c4c9a562c1d85a911f8541e1f5833 +981500 f7563d6939461d13b3d2886ea0eeae55bfd5b70a2124fb1f99e3128b1aa57c41 ede14ce9d15b6d7dd03bf87dd1d6f4358eef1de87edde1b4189b5a7006242895 +982000 4bce72fa79b9a6cc3a049ee07f2b153aa5de690bdd9177c60b9129d0a3ec65ea 790c73a90c7513fb9c6a2b0293739d8305807d61d8dd5d4ff607f8bfd385e96a +982500 77132e20fdc5fab30cf9b662a7f7f0e7cf54d1cb4d81367de088f28a594e8670 2ee079db6a79f9348a2f6484b787092b71ed1bb4c1267d5a18eff8d4c321c14e +983000 fa83e50346e0ddfb583789e0e053b74ca5765a4240f99f02c80753b0664a2851 9987f99ab0e62c8c49f5b8465f24689b780cc9c016f0c7094a489dd6724ba646 +983500 4c65a2ebacb363949d2a461a6a7c0a2ef50e4318675f4f5c9e417fdccba4c8c6 62e4e5b983d0546fed593a3012c6b7cfa0ff96ef28ccc455142618ac4c7fb0d0 +984000 15b16b66f736e2f12a9324bb45854c9f6b49dfc6b367f346e772eaf8ea49f14f 46695fd3d752266cd9f1e6d529472996f8ba494f161a7194bbf05b1130e3a4ce +984500 bd9c47bb23b50fd7e77822c377f78d7aea793eeb694484291b8901322642c7dc b8d50e9fb564090ff86cfb90867834e86bb23d4a1b9f03ba65b3729e78a85aa2 +985000 215551bd7b382b243fba86059c241a3315ced3cb6eebcec5d64c731a9aa07d95 f7bf9600e24bcacd6716ac7e79942f9f62f16b644aaa5bbfc2cf87b84a418494 +985500 aed846fcf07535b706e65ae53577ac77f106d4d196aa5adcd04d81ee2159f6c2 0c10ecc979a353ee4b5d050ec570f95c8199401598d09ff9009d0d7e03a7326a +986000 f273f50890e0f8125bd23c8ccbe22be64a280b6f293cbab62dd9e9482096a58f 289913c0b5c8c8c34c66bbbc27b602060a274ce12463a0d94928b37cded39687 +986500 bb2726763523d72fa76ae25415b8e5251d234caf180c1cbc46684d30ec96c1fe a6322ac39bd1cbb2d2a6cff84e25e3e310e4e51c7f78aca2c1828c443cfa42f7 +987000 eb16d2f4fd89294f684687a1fda4cef1d5d494324818c0c16b9e2b9669211c60 a922d18fd438b0b631a45cc52f1b35192e101b890e35787f60676d5ee100a0f7 +987500 d50c6155658a1707ecad02738b6557432513bf5ea78bf3a2e1cde78a3b672f91 95b19f76982eda85133625b6b2d8ed6ec049533d9a8f015a7d8eeea85ebda3ce +988000 8fae67f15c83e3f5ce559fa3be81c49b47ea2923be52f8fca6ea76432973a87f db354947189daf8324430538ebacff70a48b80bb9fbc80e640efe5a0032aed71 +988500 7c7b9d686c788f19718bc1bb0aa3add6d5071118fbf2a914d4447ec2867de02a f8360801e9268cc2ed86aa0ec2facf7d228bd891e0cb54a5ad7d4761797409a5 +989000 464836cbe95821ce2f4bf0ae1eb094b086d894130057e25703f109fd1f6932ab 3e3682d443a12d532d27364e2f7b6a5edd53eb7236159d859c5fb4b60315af05 +989500 29766a224c17b8de90c83325930b52e2b52ea23242192f7a3795120d43c6ceae 6d1e2b7a6c886b98a131cecee608276d80903d9f230f2486a7eeb4b094bf13fe +990000 7a0d6f86cc9693e0a0ee0febca3b3f8116a2c1ca3e3f5478dc713b9c03f1286f 77ac7bb4b87ce136b1e951aefa132fa8e70566b1aa83e2b41c7e51b50f7ce994 +990500 2c605fb768a51433d5ff066d9e6736e991a806d3b387c873efe12b5edb30a967 19bbe2a5c3b3d2416b9219cf5570841f143d71a0fc20e29382eb6cb07901707b +991000 13a48c504165faf127f177f7d4fe19e150c94f27e55747dffdeb035a9cd26c1e eb2aaa0eca1b723d685a29f82d8a802e81e53009b8f53d57f0c2d80aa5dd2c71 +991500 d28753c20fc3c35531286a7c815604103662a182986e5f1e5f84e2437b49abcf 7f0ad9f3223bd8989cac9836665da3878a14b6ab705495b626bab79a73ae3e92 +992000 86d7ea18c4c4d8ad086d71a384f12bf1cfac15ab847838aa2dd3dc2bec258f16 b94aef8147f94f009f2ceefb00902ef16cb7bcd31acd16633162dbad61bdb282 +992500 e1b3cb464a21d2243d3577a87ffa8a5cf4f886ceda5c3b70e5142097b425fd46 4c934f704aab283fa3ae0b18dff434bedcd7c549816fa1e1a4639b6252ffdf4d +993000 88a8e95ccbef1cf83a82690b89c170722120394b01ea641001a35379ca8bbae6 fca6247b8ee3dcb01af1aa29846486eca0092ca90bc14274d16d29c823abc081 +993500 c34e2bcb4c7ead30c306385655a8202de556ef19ced40c59aa14c0efac91e2ba 796047ec552f3417fbda0bb7e8b47476652a831590572051ef810adce0b28f9e +994000 d5298162e2923b179e6cbdd230cdcc57dbd74ee47f24b94467f61039eb9ea1f5 4b23ad485cf4edb61c5db401a01488b7546d5c9ee52f2bd3d9152ecc35212b8e +994500 b0664adfbec0e115415ded1b9645a536b50ca6abbf6d4064fa0004b70fde8e6a e7c1d777900ebe2a77996f06d21877252817e02a565346e4d014b06c1a29767a +995000 e508ee8874d2bbe69aefc606873f503678aedf80f7d94f41d2f2c5dd03875cf4 86d2b0cd16d25e2bffc226f79d7212271480febb960efbd50258fcc13096e179 +995500 a707c4371079cf705cd28106444573df7512088f6ddf94529d3ad23a7300293c d45f3c7e465894cbf6ade11bec71ce70dbaa476e9883264398651c58aadad749 +996000 f7b87eb786f79e735e906e314053d44ca9e390f3e95ace03d9210540bf481ee9 b97629b917bf0cf5d8fea9f1fc2e70c68b7dd5e26e7d9d46e39ab007e0d1da1b +996500 b558b1cf6b6c8433c5800f23ae615142084f8f3d928a40e409f874aabbaca98e cced61b2eef93c36342b81a9d83762f622a6bd502c0cc7dd1c0682a4724742eb +997000 caaeb7a33c8889c80539ae6c7630467e1f9a63c7ad7e785b981a407da287a641 670fffa544fc0473595daef1fabde40074c4f7044d4dc30693940beaeccfc389 +997500 8e34f4d6d0a279a37c8ba482b77251ad9f7fc96501553dab0680fcb22e6ede26 302b33d0ad1a64fef2ef8930018ada4c3c5a78c1c73cb8000c0d7761e47ee10c +998000 4d92ce92ad50fc20856ea205479db25276de24f146f131b15a84554d0aa6f9af 3a0b07fc0edc28355ff8d43ea3394e609fef61e0452c1a6dea2ddf15c0ded10d +998500 9fa48484cb1aac18acaf940acefb7e016a01f2758bea1ebce66a20ce4f035bf9 d46c0a9835b479ae3f11573929492f282a89d3cd81de832bfbf621c1f447f4df +999000 ffc5bce237b717abe7ce11f385387313ecc2aa4696c69619a5b4086a53ee3271 ff9b6e5ab60a595494e3acef825047568620b1c43e8e6113142603e7b0350082 +999500 6fcd2218fbb6bb99a7ab3ee9907cb2d91332f8050a43f540dd1b927ea7406d06 125f37d51d86d8fd684971d3ddf14658459571bd6d21d87a2b8a29aa79946ae9 +1000000 0eab5112b99ed6e8cf660a001c42d98c8080cb6366c7097eea2ff77dc1609f37 acb74f062691fcec64ec6ed73d0a383fa41a034d58367c8622fec495427df074 +1000500 d1def6c86921155cf5563b6f8c4ce542cdd4fdf9754d4000dbacadf94048ae82 6f7bd3d0026433254bb0ec777cc7ada57e9f10918a0a422dacb183d2c35ef820 +1001000 895076795aca0adde7b87924fa062ba68e78c47288b2bb85f00e7e4d49db4b26 688a346250fe2ba536b9825274d23fe3ab45f80bdd79adb081f2e94982a5e4ab +1001500 5c22477fdd5bd95bd2d21c677164d7f5f0af91b4e57c40d3a4455a84bec21e57 5ad71bdbeee74ce1a181a3ae5e6369ee464104bc12fd976ceb5f17c118829070 +1002000 19c686c9af79a78c7cc99f40e01c1b6ef8e1a2fb2fa71be9534627a4d4f9a025 658279857f203a5c1e707bf87d65c3395b687f8dd865831d892ecb7cdc8779b1 +1002500 6d44ea79ca8224f60c6e406dfe9c7b459b253173288fb27fd53f2459be869fe1 4d4cf2b50e60efd3830b0e19de7109bfcca8ef40807d483e32260b1a85a2ef9d +1003000 e5b417ad3beff6e4f8864ea986901adc70cb998335784643accb38300ba26f33 f947088aa2b8ce56cc93358c4049c034128ca2f3e67330d0881ebf49e0748f11 +1003500 da0ed4a993783299c429b78e8702b1dc731cb587a331106925a410112ee6a241 0f0c1c4ceffb15f8a875034287aabb36c185962d010699ad1161ec4a82f98367 +1004000 764ac91a87f912be6230e1b59065b818bed0579c6ecb1f96a17e7303de702b39 2ab1ef7f085464ccc0245b130d84641be08b8fc885c1f15960ab72e486834cb5 +1004500 bdb68fc38ebf22d68dc2a984407588ed9c452a7aee062317ed760140148b0db1 49563018d17110ead9266c3efd001ac2c0965f31cb08ea8c69b9309a00e08822 +1005000 98dd7428557fcb55e93aacc5ce52d4685a9ff114e27777124371bfbb82856a18 a429996bc47364fab997ca87316cc079a62290f061b8495b93a14fe24087c49d +1005500 0a94bafc026c86b317b33f8cd2661d6494b8f9b01a6931d771505ebd80ef3314 37566fb68bc84fa11fa17c73f90cbafa0ab29336a0ff0f98eefa590c7426869c +1006000 db286315d07b3d4cc4de96bf6b344be65c9406c6186318e32d10fd8d66d5e3ee 2f1984d31cf7ab600246083e52855afac8a6ff5bdf62badd04f6ec8c532dc5c8 +1006500 7ed79e53672acebe07b0a25853c34af6822ef69078c94de86137f16ef35a39e2 1d503606be0bf1c476e7154c2d632489d9b0ee7f13138a1face4d411a0e6f9a9 +1007000 98056fa1e52b11ee70eb294a962ef9288df96ea4ad8fc4a5166a58ffa67cf650 a802403c8ffeedfb9de8a5fc863730e39a06c142b04b3b88b791f12b3340741c +1007500 037eea45d7e266fe26cf97846726facb73968441f3c3b0b8f384371335ca8b54 f919c88493be76b460431acafe67adf6c2cf18ad72549b93f51934791b628c22 +1008000 0ac8cae34eadd6a2b2b4f8c19dbe7b81b3bd432c7fa84a4635ed19c8109df8d1 7859a5b85c491881a7bf6f3d0d5dd0c0dfe381e2d76295608ae4a2e12ad52f40 +1008500 903511e59fc4c13cef0ba01903a85ad56a60406abcc5804fe0021d1f364f35f4 be8421e49bd2f3e64db5309ba30e8954d1cf68eb8ead03f5f820fa88bce8cb51 +1009000 0c4432de0745d517d1bd48fb5bccd988985d77628c45f9bff545834b63986ac8 577c73b6278b78665f4315543688743a5c49ebe86f63f985e9e7989829030386 +1009500 e8ad9cb3b8e542229367fc34627ec8e1f6e4847a37552ebe2bcbc36eb0c0d955 5bab28311ec5b559f423c3e7980a1d55e5c0971682ea84ff9d6740ff9ad43195 +1010000 8c8b963aa26439dcf83d0a67799551fc5fa3b1fce2261db4374a913e50745184 d3c41f512eb318d2fb9c76dd883dde048ea1bae997bafb4013950b582d79f780 +1010500 f3bb272a4c6145fd3a142e85744d9838c7e1ea33388c5501b76f2bf3fb6f2021 015a4e570fa61d5b9cb0d8404f237d56571600de80f4e9291fd69b5f981a52d5 +1011000 e99b3e7d03403da96fa17a760491b2e627324e6e40c99c6291ee2477325506d2 59894713ba320d48c79325fedf70951bb8112781aa32679b55c49f6739d4549f +1011500 624b57fa2f3c1be8a6df1d8d07162b6dcbfe4d5b5bab6ae76dab199518c997b5 b9b72cce7e651a9beeb7a0af57e82dd1a11ff0fe4df6c7935bd67d10978b7b91 +1012000 1b26bceffc486dad37b7b8ec5822a388cc5b24d884fc6463963f1bb432440981 308612e9d27755371409af57a2e7bbb53d9432ff575aa742854b074c8ee6f237 +1012500 1fe71ca40d446eef37d4c00d208ecf6f503e180e6f55c68dbb5fcb9e3d2eb746 bb77811625dd920f9ca60331a354187ec62026d596a06f49bf6aae63ed72da2e +1013000 332859dc2b9962c6f20ba5af9d3093ee01d1e034e8c1b2defbd65e81154a7f6e de3d066931f8e54297a44e6e2d44fed5829456960c2f5aab427c460522dba461 +1013500 0e4af0f0df0ec61fa3a5af0aec7c4b4987d876be19be280f8a3046c36bb39a5b 90a3e76d69a0556ecfab5ab4ece1960353fe0040732065d2900167415b007ebe diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 2e23b1e28..aa33ad6f4 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -74,6 +74,7 @@ struct iguana_info *iguana_coinadd(const char *symbol,cJSON *argjson) coin->chain = iguana_chainfind((char *)symbol,argjson,1); strcpy(coin->symbol,symbol); iguana_initcoin(coin,argjson); + printf("coin.%s initialized\n",symbol); } return(coin); } @@ -180,7 +181,7 @@ int32_t iguana_peermetrics(struct iguana_info *coin) coin->peers.avemetric = (sum / i); if ( i >= (coin->MAXPEERS - 1) && slowest != 0 ) { - printf("prune slowest peer.(%s) numranked.%d\n",slowest->ipaddr,n); + printf("prune slowest peer.(%s) numranked.%d MAXPEERS.%d\n",slowest->ipaddr,n,coin->MAXPEERS); slowest->dead = 1; } } @@ -221,7 +222,7 @@ uint32_t iguana_updatemetrics(struct iguana_info *coin) { for (j=0; jpeers.numranked; j++) { - if ( i != 0 && (tmpaddr= coin->peers.ranked[j]) != 0 && (uint32_t)addr->ipbits == (uint32_t)tmpaddr->ipbits ) + if ( i != j && (tmpaddr= coin->peers.ranked[j]) != 0 && (uint32_t)addr->ipbits == (uint32_t)tmpaddr->ipbits ) break; } if ( j == coin->peers.numranked ) @@ -251,7 +252,7 @@ void iguana_emitQ(struct iguana_info *coin,struct iguana_bundle *bp) ptr->bp = bp, ptr->hdrsi = bp->hdrsi; ptr->type = 'E'; ptr->starttime = (uint32_t)time(NULL); - printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); + //printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); queue_enqueue("emitQ",&emitQ,&ptr->DL,0); } @@ -288,15 +289,19 @@ void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t ti void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_helper *ptr; - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->type = 'V'; - ptr->starttime = (uint32_t)time(NULL); - ptr->timelimit = 0; - //printf("VALIDATE Q %s bundle.%d[%d] utxofinish.%u balancefinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); - queue_enqueue("validateQ",&validateQ,&ptr->DL,0); + if ( bp->validated == 0 ) + { + ptr = mycalloc('i',1,sizeof(*ptr)); + ptr->allocsize = sizeof(*ptr); + ptr->coin = coin; + ptr->bp = bp, ptr->hdrsi = bp->hdrsi; + ptr->type = 'V'; + ptr->starttime = (uint32_t)time(NULL); + ptr->timelimit = 0; + bp->validated = 1; + //printf("VALIDATE Q %s bundle.%d[%d] utxofinish.%u balancefinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); + queue_enqueue("validateQ",&validateQ,&ptr->DL,0); + } } void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp) @@ -309,7 +314,8 @@ void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp) ptr->type = 'B'; ptr->starttime = (uint32_t)time(NULL); ptr->timelimit = 0; - bp->balancefinish = 1; + if ( bp->balancefinish == 0 ) + bp->balancefinish = 1; coin->pendbalances++; //printf("BALANCES Q[%d] %s bundle.%d[%d] balances.%u balancefinish.%u\n",coin->pendbalances,coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); queue_enqueue("balancesQ",&balancesQ,&ptr->DL,0); @@ -323,8 +329,6 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m { if ( (bp= ptr->bp) != 0 ) { - if ( time(NULL) > bp->nexttime ) - return(0); if ( 0 && ptr->type == 'M' ) { if ( (nextbp= ptr->nextbp) != 0 ) @@ -336,6 +340,7 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m } else if ( ptr->type == 'B' ) { + printf("helper bundleiters\n"); iguana_bundleiters(coin,mem,memB,bp,ptr->timelimit); } else if ( ptr->type == 'E' ) @@ -352,43 +357,26 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m return(0); } -void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp) -{ - uint32_t starttime; - starttime = (uint32_t)time(NULL); - if ( iguana_balancegen(coin,bp) < 0 ) - { - printf("GENERATE BALANCES ERROR ht.%d\n",bp->bundleheight); - exit(-1); - } - bp->balancefinish = (uint32_t)time(NULL); - printf("GENERATED BALANCES for ht.%d duration %d seconds\n",bp->bundleheight,bp->balancefinish - (uint32_t)starttime); - iguana_validateQ(coin,bp); -} - void iguana_helper(void *arg) { - FILE *fp = 0; char fname[512],name[64],*helpername = 0; cJSON *argjson=0; int32_t type,flag,idle=0; - struct iguana_helper *ptr; struct iguana_info *coin; struct OS_memspace MEM,*MEMB; + FILE *fp = 0; cJSON *argjson=0; int32_t type,helperid=rand(),flag,allcurrent,idle=0; + struct iguana_helper *ptr; struct iguana_info *coin; struct OS_memspace MEM,*MEMB; struct iguana_bundle *bp; if ( arg != 0 && (argjson= cJSON_Parse(arg)) != 0 ) - helpername = jstr(argjson,"name"); - if ( helpername == 0 ) - { - sprintf(name,"%d",rand()); - helpername = name; - } - type = (name[0] % 2); - sprintf(fname,"%s/%s",GLOBALTMPDIR,helpername); + helperid = juint(argjson,"helperid"); + type = (helperid % 2); + /*sprintf(fname,"%s/%s",GLOBALTMPDIR,helpername); OS_compatible_path(fname); - fp = fopen(fname,"wb"); + fp = fopen(fname,"wb");*/ if ( argjson != 0 ) free_json(argjson); + printf("HELPER.%d started arg.(%s)\n",helperid,(char *)(arg!=0?arg:0)); memset(&MEM,0,sizeof(MEM)); MEMB = mycalloc('b',IGUANA_MAXBUNDLESIZE,sizeof(*MEMB)); while ( 1 ) { - //iguana_jsonQ(); + //iguana_jsonQ(); cant do this here flag = 0; + allcurrent = 1; if ( ((ptr= queue_dequeue(&emitQ,0)) != 0 || (ptr= queue_dequeue(&helperQ,0)) != 0) ) { if ( ptr->bp != 0 && (coin= ptr->coin) != 0 ) @@ -404,9 +392,15 @@ void iguana_helper(void *arg) else if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) { idle = 0; - if ( ptr->bp != 0 && ptr->coin != 0 ) - flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,ptr->bp,ptr->timelimit); - else printf("helper missing param? %p %p %u\n",ptr->coin,ptr->bp,ptr->timelimit); + if ( (bp= ptr->bp) != 0 && (coin= ptr->coin) != 0 ) + { + coin->numbundlesQ--; + if ( coin->started != 0 && time(NULL) >= bp->nexttime ) + flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit); + else iguana_bundleQ(ptr->coin,bp,1000); + if ( coin->current != 0 && coin->current->hdrsi != coin->bundlescount-1 ) + allcurrent = 0; + } else printf("helper missing param? %p %p %u\n",ptr->coin,bp,ptr->timelimit); myfree(ptr,ptr->allocsize); flag++; } @@ -422,61 +416,17 @@ void iguana_helper(void *arg) } } if ( flag == 0 ) - usleep(1000000); - else usleep(100000); - } -} - -void iguana_coinflush(struct iguana_info *coin,int32_t forceflag) -{ - int32_t hdrsi,blen; struct iguana_bundle *bp; char fname[1024],fname2[1024]; FILE *fp,*fp2=0; - memset(coin->bundlebits,0,sizeof(coin->bundlebits)); - for (hdrsi=0; hdrsibundlescount; hdrsi++) - if ( (bp= coin->bundles[hdrsi]) != 0 && bp->validated != 0 ) - SETBIT(coin->bundlebits,hdrsi); - blen = (int32_t)hconv_bitlen(coin->bundlescount); - for (hdrsi=0; hdrsibundlescount; hdrsi++) - { - if ( (bp= coin->bundles[hdrsi]) != 0 && (forceflag != 0 || (bp->dirty != 0 && time(NULL) > bp->dirty+60)) && bp->ramchain.H.data != 0 && bp->ramchain.A != 0 && bp->ramchain.Uextras != 0 ) - { - if ( forceflag == 0 ) - { - sprintf(fname,"accounts/%s/debits.%d",coin->symbol,bp->bundleheight); - sprintf(fname2,"accounts/%s/lastspends.%d",coin->symbol,bp->bundleheight); - } - else - { - sprintf(fname,"DB/%s/accounts/debits_%d.%d",coin->symbol,coin->bundlescount,bp->bundleheight); - sprintf(fname2,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,coin->bundlescount,bp->bundleheight); - } - //printf("save (%s) and (%s) %p %p\n",fname,fname2,bp,bp->ramchain.H.data);//,bp->ramchain.H.data->numpkinds,bp->ramchain.H.data->numunspents); - if ( (fp= fopen(fname,"wb")) != 0 && (fp2= fopen(fname2,"wb")) != 0 ) - { - if ( fwrite(&coin->bundlescount,1,sizeof(coin->bundlescount),fp) == sizeof(coin->bundlescount) && fwrite(&coin->bundlescount,1,sizeof(coin->bundlescount),fp2) == sizeof(coin->bundlescount) && fwrite(coin->bundlebits,1,blen,fp) == blen && fwrite(coin->bundlebits,1,blen,fp2) == blen ) - { - if ( fwrite(bp->ramchain.A,sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds,fp) == bp->ramchain.H.data->numpkinds ) - { - if ( fwrite(bp->ramchain.Uextras,sizeof(*bp->ramchain.Uextras),bp->ramchain.H.data->numunspents,fp2) == bp->ramchain.H.data->numunspents ) - { - bp->dirty = 0; - printf("saved (%s) and (%s)\n",fname,fname2); - } - } - } - fclose(fp), fclose(fp2); - if ( bp->dirty != 0 ) - printf("error writing %s\n",fname); - } - else if ( fp != 0 ) - fclose(fp); - } + usleep(100000); + else if ( allcurrent != 0 ) + usleep(25000); + else usleep(2500); } } void iguana_coinloop(void *arg) { struct iguana_info *coin,**coins = arg; - struct iguana_bundle *bp; int32_t flag,i,n,bundlei; bits256 zero; char str[1024]; + struct iguana_bundle *bp; int32_t flag,i,n,bundlei; bits256 zero; char str[2065]; uint32_t now; n = (int32_t)(long)coins[0]; coins++; @@ -485,14 +435,14 @@ void iguana_coinloop(void *arg) { if ( (coin= coins[i]) != 0 && coin->started == 0 ) { + iguana_rwiAddrind(coin,0,0,0); iguana_coinstart(coin,coin->initialheight,coin->mapflags); - printf("init.(%s) maxpeers.%d maxrecvcache.%s services.%llx MAXMEM.%s polltimeout.%d\n",coin->symbol,coin->MAXPEERS,mbstr(str,coin->MAXRECVCACHE),(long long)coin->myservices,mbstr(str,coin->MAXMEM),coin->polltimeout); + printf("init.(%s) maxpeers.%d maxrecvcache.%s services.%llx MAXMEM.%s polltimeout.%d cache.%d pend.(%d -> %d)\n",coin->symbol,coin->MAXPEERS,mbstr(str,coin->MAXRECVCACHE),(long long)coin->myservices,mbstr(str,coin->MAXMEM),coin->polltimeout,coin->enableCACHE,coin->startPEND,coin->endPEND); coin->started = coin; coin->chain->minconfirms = coin->minconfirms; } } coin = coins[0]; - iguana_rwiAddrind(coin,0,0,0); iguana_possible_peer(coin,"127.0.0.1"); memset(zero.bytes,0,sizeof(zero)); if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 ) @@ -508,7 +458,7 @@ void iguana_coinloop(void *arg) now = (uint32_t)time(NULL); if ( coin->active != 0 ) { - if ( coin->isRT == 0 && now > coin->startutc+600 && coin->numsaved >= (coin->longestchain/coin->chain->bundlesize)*coin->chain->bundlesize && coin->blocks.hwmchain.height >= coin->longestchain-30 ) + if ( coin->isRT == 0 && now > coin->startutc+77 && coin->numsaved >= (coin->longestchain/coin->chain->bundlesize)*coin->chain->bundlesize && coin->blocks.hwmchain.height >= coin->longestchain-30 ) { fprintf(stderr,">>>>>>> %s isRT blockrecv.%d vs longest.%d\n",coin->symbol,coin->blocksrecv,coin->longestchain); coin->isRT = 1; @@ -518,13 +468,13 @@ void iguana_coinloop(void *arg) } if ( coin->isRT != 0 && coin->current != 0 && coin->numverified >= coin->current->hdrsi ) { - static int32_t saved; - if ( saved++ == 0 ) - iguana_coinflush(coin,1); + //static int32_t saved; + //if ( saved++ == 0 ) + // iguana_coinflush(coin,1); } if ( coin->bindsock >= 0 ) { - if ( coin->peers.numranked < 8 && now > coin->lastpossible+60 ) + if ( coin->peers.numranked < coin->MAXPEERS/2 && now > coin->lastpossible ) { //fprintf(stderr,"possible\n"); coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers @@ -542,10 +492,8 @@ void iguana_coinloop(void *arg) { //fprintf(stderr,"metrics\n"); coin->peers.lastmetrics = iguana_updatemetrics(coin); // ranks peers + iguana_bundlestats(coin,str); } - //fprintf(stderr,"call stats\n"); - iguana_bundlestats(coin,str); - //fprintf(stderr,"call process\n"); flag += iguana_processrecv(coin); if ( coin->longestchain+10000 > coin->blocks.maxbits ) iguana_recvalloc(coin,coin->longestchain + 100000); @@ -553,7 +501,7 @@ void iguana_coinloop(void *arg) } } if ( flag == 0 ) - usleep(10000); + usleep(100000); } } @@ -573,7 +521,7 @@ void iguana_coinargs(char *symbol,int64_t *maxrecvcachep,int32_t *minconfirmsp,i struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxpending,int32_t maxbundles,cJSON *json) { struct iguana_chain *iguana_createchain(cJSON *json); - struct iguana_info *coin; int32_t j,m,mapflags; char dirname[512]; cJSON *peers; + struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char dirname[512]; cJSON *peers; mapflags = IGUANA_MAPRECVDATA | maphash*IGUANA_MAPTXIDITEMS | maphash*IGUANA_MAPPKITEMS | maphash*IGUANA_MAPBLOCKITEMS | maphash*IGUANA_MAPPEERITEMS; coin = iguana_coinadd(symbol,json); coin->launched = launched; @@ -582,12 +530,12 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, if ( (coin->MAXRECVCACHE= maxrecvcache) == 0 ) coin->MAXRECVCACHE = IGUANA_MAXRECVCACHE; if ( (coin->MAXPENDING= maxpending) <= 0 ) - coin->MAXPENDING = (strcmp(symbol,"BTC") == 0) ? _IGUANA_MAXPENDING : 64*_IGUANA_MAXPENDING; - if ( (coin->MAXBUNDLES= maxbundles) <= 0 ) - coin->MAXBUNDLES = (strcmp(symbol,"BTC") == 0) ? IGUANA_MAXPENDBUNDLES : IGUANA_MAXPENDBUNDLES * 64; + coin->MAXPENDING = (strcmp(symbol,"BTC") == 0) ? _IGUANA_MAXPENDING : 4*_IGUANA_MAXPENDING; coin->myservices = services; printf("ensure directories\n"); sprintf(dirname,"accounts/%s",symbol), OS_ensure_directory(dirname); + sprintf(dirname,"DB/ro/%s",symbol), OS_ensure_directory(dirname); + sprintf(dirname,"DB/ro"), OS_ensure_directory(dirname); sprintf(dirname,"DB/%s",symbol), OS_ensure_directory(dirname); sprintf(dirname,"DB/%s/accounts",symbol), OS_ensure_directory(dirname); sprintf(dirname,"DB/%s/spends",symbol), OS_ensure_directory(dirname); @@ -596,13 +544,33 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, sprintf(dirname,"%s/%s",GLOBALTMPDIR,symbol), OS_ensure_directory(dirname); coin->initialheight = initialheight; coin->mapflags = mapflags; + mult = (strcmp("BTC",coin->symbol) != 0) ? 512 : 1; + maxval = (strcmp("BTC",coin->symbol) != 0) ? 2048 : 64; coin->MAXMEM = juint(json,"RAM"); if ( coin->MAXMEM == 0 ) coin->MAXMEM = IGUANA_DEFAULTRAM; - coin->MAXMEM *= (1024 * 1024 * 1024); + if ( strcmp("BTC",coin->symbol) == 0 && coin->MAXMEM <= 4 ) + maxval = (int32_t)coin->MAXMEM; + coin->MAXMEM *= (1024L * 1024 * 1024); + if ( (coin->startPEND= juint(json,"startpend")) == 0 ) + coin->startPEND = IGUANA_MAXPENDBUNDLES * mult; + if ( coin->startPEND > maxval ) + coin->startPEND = maxval; + else if ( coin->startPEND < 2 ) + coin->startPEND = 2; + coin->MAXBUNDLES = coin->startPEND; + if ( (coin->endPEND= juint(json,"endpend")) == 0 ) + coin->endPEND = IGUANA_MINPENDBUNDLES * mult; + if ( coin->endPEND > maxval ) + coin->endPEND = maxval; + else if ( coin->endPEND < 2 ) + coin->endPEND = 2; + coin->enableCACHE = (strcmp("BTC",coin->symbol) != 0); + if ( jobj(json,"cache") != 0 ) + coin->enableCACHE = juint(json,"cache"); if ( (coin->polltimeout= juint(json,"poll")) <= 0 ) coin->polltimeout = 10; - char str[65]; printf("MAXMEM.%s\n",mbstr(str,coin->MAXMEM)); + char str[65]; printf("MAXMEM.%s enablecache.%d\n",mbstr(str,coin->MAXMEM),coin->enableCACHE); coin->active = juint(json,"active"); if ( (coin->minconfirms = minconfirms) == 0 ) coin->minconfirms = (strcmp(symbol,"BTC") == 0) ? 3 : 10; @@ -611,6 +579,8 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, printf("cant initialize chain.(%s)\n",jstr(json,0)); return(0); } else iguana_chainparms(coin->chain,json); + coin->RELAYNODE = juint(json,"RELAY"); + coin->VALIDATENODE = juint(json,"VALIDATE"); if ( (peers= jarray(&m,json,"peers")) != 0 ) { for (j=0; j canonical 32bit inds and ledgerhashes -struct iguana_unspent20 { uint64_t value; uint32_t scriptpos,txidind:28,type:4; uint16_t scriptlen,ipbits; uint8_t rmd160[20]; } __attribute__((packed)); -struct iguana_spend256 { bits256 prevhash2; uint32_t sequenceid,scriptpos; int16_t prevout; uint16_t vinscriptlen,spendind,ipbits; } __attribute__((packed)); +// ramchain temp file structures +struct iguana_unspent20 { uint64_t value; uint32_t scriptpos,txidind:28,type:4; uint16_t scriptlen,fileid; uint8_t rmd160[20]; } __attribute__((packed)); +struct iguana_spend256 { bits256 prevhash2; uint32_t sequenceid,scriptpos; int16_t prevout; uint16_t vinscriptlen,spendind,fileid; } __attribute__((packed)); +// permanent readonly structs struct iguana_txid { bits256 txid; uint32_t txidind,firstvout,firstvin,locktime,version,timestamp,extraoffset; uint16_t numvouts,numvins; } __attribute__((packed)); -struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind,scriptpos,ipbits; uint16_t hdrsi,type:4,scriptlen:14; int16_t vout; } __attribute__((packed)); +struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind,scriptpos; uint16_t fileid,scriptlen; uint16_t hdrsi:11,type:5; int16_t vout; } __attribute__((packed)); -struct iguana_spend { uint32_t spendtxidind,sequenceid,scriptpos,ipbits; int16_t prevout; uint16_t scriptlen:15,external:1; } __attribute__((packed)); // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 +struct iguana_spend { uint32_t spendtxidind,sequenceid,scriptpos; int16_t prevout; uint16_t fileid,scriptlen:15,external:1; } __attribute__((packed)); // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind; } __attribute__((packed)); //firstunspentind,pubkeyoffset // dynamic -struct iguana_account { int64_t total; uint32_t lastind; } __attribute__((packed)); -struct iguana_utxo { uint32_t prevspendind,height:31,spentflag:1; } __attribute__((packed)); +struct iguana_account { int64_t total; uint32_t lastunspentind; } __attribute__((packed)); +struct iguana_utxo { uint32_t fromheight,prevunspentind:31,spentflag:1; } __attribute__((packed)); +struct iguana_hhaccount { UT_hash_handle hh; uint8_t buf[6]; struct iguana_account a; } __attribute__((packed)); +struct iguana_hhutxo { UT_hash_handle hh; uint8_t buf[6]; struct iguana_utxo u; } __attribute__((packed)); // GLOBAL one zero to non-zero write (unless reorg) -struct iguana_spendvector { uint32_t ind,height; uint16_t hdrsi; } __attribute__((packed)); // unspentind +struct iguana_spendvector { uint64_t value; uint32_t pkind,unspentind; uint16_t hdrsi,bundlei; } __attribute__((packed)); // unspentind //struct iguana_pkextra { uint32_t firstspendind; } __attribute__((packed)); // pkind struct iguana_txblock @@ -371,11 +376,14 @@ struct iguana_ramchain_hdr struct iguana_ramchain { - struct iguana_ramchain_hdr H; bits256 lasthash2; uint64_t datasize; + struct iguana_ramchain_hdr H; bits256 lasthash2; uint64_t datasize,allocatedA,allocatedU; uint32_t numblocks:31,expanded:1,pkind,externalind,height,numXspends; struct iguana_kvitem *txids,*pkhashes; - struct OS_memspace *hashmem; long filesize,sigsfilesize; void *fileptr,*sigsfileptr,*Xspendptr; - struct iguana_account *A,*creditsA; struct iguana_spendvector *Xspendinds; struct iguana_utxo *Uextras; + struct OS_memspace *hashmem; long filesize,sigsfilesize,debitsfilesize,lastspendsfilesize; + void *fileptr,*sigsfileptr,*Xspendptr,*debitsfileptr,*lastspendsfileptr; + char from_ro,from_roX,from_roA,from_roU; + struct iguana_account *A,*creditsA; struct iguana_spendvector *Xspendinds; + struct iguana_utxo *Uextras; //struct iguana_Uextra *U2,*roU2; struct iguana_pkextra *P2,*roP2; }; @@ -395,7 +403,8 @@ struct iguana_peer struct OS_memspace RAWMEM,TXDATA,HASHMEM; struct iguana_ramchain ramchain; struct iguana_fileitem *filehash2; int32_t numfilehash2,maxfilehash2; - struct iguana_bundle *bp; FILE *voutsfp,*vinsfp; + //struct iguana_bundle *bp; + FILE *voutsfp,*vinsfp; #ifdef IGUANA_PEERALLOC struct OS_memspace *SEROUT[128]; #endif @@ -418,8 +427,8 @@ struct iguana_bundle { struct queueitem DL; struct iguana_info *coin; struct iguana_bundle *nextbp; struct iguana_bloom16 bloom; uint32_t rawscriptspace; - uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,utxofinish,balancefinish,validated,lastspeculative,dirty,nexttime,currenttime; - int32_t numhashes,numrecv,numsaved,numcached,rank,generrs,checkedtmp,currentflag; + uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,utxofinish,balancefinish,validated,lastspeculative,dirty,nexttime,currenttime,lastprefetch; + int32_t numhashes,numrecv,numsaved,numcached,generrs,checkedtmp,currentflag; int32_t minrequests,n,hdrsi,bundleheight,numtxids,numspends,numunspents,numspec; double avetime,threshold,metric; uint64_t datasize,estsize; struct iguana_block *blocks[IGUANA_MAXBUNDLESIZE]; uint32_t issued[IGUANA_MAXBUNDLESIZE]; @@ -451,36 +460,33 @@ struct iguana_info struct iguana_peers peers; uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime; int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,estsize,activebundles; - int32_t MAXPEERS,MAXPENDING,MAXBUNDLES,active,closestbundle,numemitted,lastsweep,startutc,newramchain,numcached,cachefreed,helperdepth; - uint32_t longestchain,lastsync,parsetime,numiAddrs,firstblock,lastpossible,bundlescount,savedblocks; + int32_t MAXPEERS,MAXPENDING,MAXBUNDLES,active,closestbundle,numemitted,lastsweep,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,RELAYNODE,VALIDATENODE,balanceswritten,RTheight; bits256 balancehash; + uint32_t lastsync,parsetime,numiAddrs,firstblock,lastpossible,bundlescount,savedblocks,backlog; + int32_t longestchain,badlongestchain,longestchain_strange; struct tai starttime; double startmillis; struct iguana_chain *chain; struct iguana_iAddr *iAddrs; - //struct iguanakv *txids,*spends,*unspents,*pkhashes; - //struct iguana_txid *T; - //struct iguana_unspent *U; struct iguana_Uextra *Uextras; - //struct iguana_spend *S; struct iguana_Sextra *Sextras; - //struct iguana_pkhash *P; struct iguana_account *accounts; struct iguana_pkextra *pkextras; - //struct iguana_counts latest; - //struct iguana_ledger LEDGER,loadedLEDGER; struct iguana_bitmap screen; //struct pollfd fds[IGUANA_MAXPEERS]; struct iguana_peer bindaddr; int32_t numsocks; struct OS_memspace TXMEM; - queue_t acceptQ,hdrsQ,blocksQ,priorityQ,possibleQ,TerminateQ,cacheQ,recvQ; + queue_t acceptQ,hdrsQ,blocksQ,priorityQ,possibleQ,cacheQ,recvQ; double parsemillis,avetime; uint32_t Launched[8],Terminated[8]; portable_mutex_t peers_mutex,blocks_mutex; portable_mutex_t scripts_mutex[2]; FILE *scriptsfp[2]; void *scriptsptr[2]; long scriptsfilesize[2]; //struct scriptinfo *scriptstable[2]; struct iguana_bundle *bundles[IGUANA_MAXBUNDLES],*current,*lastpending; + struct iguana_ramchain RTramchain; struct OS_memspace RTmem,RThashmem; int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle,numsaved,pendbalances,numverified; - uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime; + uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp,RTgenesis; double backstopmillis; bits256 backstophash2; int64_t spaceused; int32_t initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,polltimeout,numreqtxids,allhashes; bits256 reqtxids[64]; void *launched,*started; - uint64_t bloomsearches,bloomhits,bloomfalse,collisions; uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192],bundlebits[IGUANA_MAXBUNDLES/8+1]; struct OS_memspace blockMEM; + uint64_t bloomsearches,bloomhits,bloomfalse,collisions; + uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192]; struct OS_memspace blockMEM; struct iguana_blocks blocks; bits256 APIblockhash,APItxid; char *APIblockstr; struct iguana_waccount *wallet; + struct iguana_hhutxo *utxotable; struct iguana_hhaccount *accountstable; char lastdispstr[2048]; }; struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; @@ -785,8 +791,8 @@ uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8 int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *suffixp,uint8_t *vinscript,int32_t scriptlen); void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len); int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp); -int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp); -int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp); +int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp); +int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp); void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp); struct iguana_bloominds iguana_calcbloom(bits256 hash2); @@ -794,16 +800,28 @@ int32_t iguana_bloomfind(struct iguana_info *coin,struct iguana_bloom16 *bloom,i struct iguana_bloominds iguana_bloomset(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp); void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp); -void iguana_coinflush(struct iguana_info *coin,int32_t forceflag); +int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist); int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti,int32_t max); -void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp); +int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority); int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp); +void iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain); +int32_t iguana_realtime_update(struct iguana_info *coin); +int32_t iguana_mapvolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain); +void iguana_purgevolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain); +int32_t iguana_volatileinit(struct iguana_info *coin); +int64_t iguana_ramchainopen(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2); +int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t deleteflag); +void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block,struct iguana_ramchain * ramchain); +int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp); +void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei); +int32_t iguana_mapchaininit(struct iguana_info *coin,struct iguana_ramchain *mapchain,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block,void *ptr,long filesize); +void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp); extern int32_t HDRnet,netBLOCKS; -extern queue_t bundlesQ,validateQ,emitQ,balancesQ; +extern queue_t bundlesQ,validateQ,emitQ,balancesQ,TerminateQ; extern char GLOBALTMPDIR[]; #include "../includes/iguana_api.h" diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index a4a836d69..4504292a3 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -77,7 +77,7 @@ void iguana_acceptloop(void *args) if ( poll(&pfd,1,100) <= 0 ) continue; clilen = sizeof(cli_addr); - printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",coin->chain->portp2p,coin->bindsock); + //printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",coin->chain->portp2p,coin->bindsock); sock = accept(coin->bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( sock < 0 ) { @@ -86,7 +86,6 @@ void iguana_acceptloop(void *args) } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); expand_ipbits(ipaddr,ipbits); - printf("NEWSOCK.%d for %x (%s)\n",sock,ipbits,ipaddr); for (i=0; ipeers.active[i].ipbits == (uint32_t)ipbits && coin->peers.active[i].usock >= 0 ) @@ -101,6 +100,7 @@ void iguana_acceptloop(void *args) } if ( sock < 0 ) continue; + printf("NEWSOCK.%d for %x (%s)\n",sock,ipbits,ipaddr); /*if ( (uint32_t)ipbits == myinfo->myaddr.myipbits ) { @@ -119,6 +119,7 @@ void iguana_acceptloop(void *args) { printf("LAUNCH DEDICATED THREAD for %s\n",ipaddr); addr->usock = sock; + addr->dead = 0; strcpy(addr->symbol,coin->symbol); iguana_launch(coin,"accept",iguana_dedicatedglue,addr,IGUANA_CONNTHREAD); //iguana_dedicatedloop(coin,addr); diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 4c00ce9e3..219fe020b 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -270,10 +270,12 @@ int32_t iguana_blockunmain(struct iguana_info *coin,struct iguana_block *block) struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_block *newblock) { int32_t valid,bundlei,height=-1; struct iguana_block *hwmchain,*block = 0,*prev=0,*next; - bits256 *hash2p=0; double prevPoW = 0.; + bits256 *hash2p=0; double prevPoW = 0.; struct iguana_bundle *bp; if ( newblock == 0 ) return(0); hwmchain = &coin->blocks.hwmchain; + if ( hwmchain->height > 0 && ((bp= coin->current) == 0 || hwmchain->height/coin->chain->bundlesize > bp->hdrsi) ) + return(0); if ( (block= iguana_blockfind(coin,newblock->RO.hash2)) != 0 ) { if ( memcmp(coin->chain->genesis_hashdata,block->RO.hash2.bytes,sizeof(bits256)) == 0 ) @@ -303,6 +305,7 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl else { char str[65]; printf("chainlink error: cant find prev.(%s)\n",bits256_str(str,block->RO.prev_block)); + memset(&block->RO.prev_block.bytes,0,sizeof(block->RO.prev_block)); //getchar(); return(0); } @@ -356,10 +359,13 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl printf("ERROR: need to fix up bundle for height.%d\n",block->height); //getchar(); } - bp->hashes[block->height % coin->chain->bundlesize] = block->RO.hash2; - bp->blocks[block->height % coin->chain->bundlesize] = block; + iguana_bundlehash2add(coin,0,bp,block->height % coin->chain->bundlesize,block->RO.hash2); + /* bp->hashes[block->height % coin->chain->bundlesize] = block->RO.hash2; + if ( bp->speculative != 0 ) + bp->speculative[block->height % coin->chain->bundlesize] = block->RO.hash2; + bp->blocks[block->height % coin->chain->bundlesize] = block;*/ } - if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == 10 ) + if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == 10 && block->height > coin->longestchain-coin->chain->bundlesize*2 ) { //printf("savehdrs\n"); iguana_savehdrs(coin); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 512df107e..041923d8e 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -143,17 +143,17 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu { char str2[65],str3[65]; bits256_str(str2,*orighash2p), bits256_str(str3,newhash2); - printf("WARNING iguana_hash2set REFUSE overwrite [%s] %s with %s [%d:%d]\n",debugstr,str2,str3,bp->hdrsi,bundlei); - //*orighash2p = newhash2; + printf("WARNING iguana_hash2set overwrite [%s] %s with %s [%d:%d]\n",debugstr,str2,str3,bp->hdrsi,bundlei); + *orighash2p = newhash2; // getchar(); - return(-1); + // return(-1); } if ( isinside != 0 ) { bit = iguana_calcbloom(newhash2); if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 ) { - //printf("bloomset (%s) -> [%d:%d]\n",bits256_str(str,newhash2),bp->hdrsi,bundlei); + // printf("bloomset (%s) -> [%d:%d]\n",bits256_str(str,newhash2),bp->hdrsi,bundlei); iguana_bloomset(coin,&bp->bloom,0,bit); if ( 0 ) { @@ -180,7 +180,18 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu retval = 0; } else retval = (bundlei >= 0 && bundlei < coin->chain->bundlesize) ? 0 : 1; //printf("set [%d] <- %s\n",bundlei,bits256_str(str,newhash2)); - *orighash2p = newhash2; + if ( bits256_cmp(*orighash2p,newhash2) != 0 ) + { + if ( bits256_nonz(*orighash2p) != 0 && bp->bundleheight+bundlei <= coin->blocks.hwmchain.height ) + { + printf("changing [%d:%d] -> %d < hwmheight %d\n",bp->hdrsi,bundlei,bp->bundleheight+bundlei,coin->blocks.hwmchain.height); + if ( bp->bundleheight+bundlei > 0 ) + { + printf("REORG %d blocks\n",coin->blocks.hwmchain.height - (bp->bundleheight+bundlei)); + } + } + *orighash2p = newhash2; + } return(retval); } @@ -216,11 +227,16 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo } else { -//char str[65]; printf(">>>>>>>>>>>>>> bundlehash2.(%s) ht.(%d %d)\n",bits256_str(str,hash2),bp->bundleheight,bundlei); + char str[65]; block->hdrsi = bp->hdrsi; block->bundlei = bundlei; bp->hashes[bundlei] = block->RO.hash2; - bp->blocks[bundlei] = block; + if ( bp->speculative != 0 && bundlei < bp->numspec ) + bp->speculative[bundlei] = bp->hashes[bundlei]; + if ( bp->blocks[bundlei] == 0 ) + bp->blocks[bundlei] = block; + else if ( bp->blocks[bundlei] != block ) + printf(">>>>>>>>>>>>>> bundlehash2.(%s) ht.(%d %d) block.%p there\n",bits256_str(str,hash2),bp->bundleheight,bundlei,bp->blocks[bundlei]); otherbp = 0; if ( (otherbp= iguana_bundlefind(coin,&otherbp,&otherbundlei,hash2)) != 0 || (bundlei % (bundlesize-1)) == 0) { @@ -277,7 +293,10 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund if ( iguana_bundlefind(coin,&bp,bundleip,bundlehash2) != 0 ) { if ( bp->bundleheight >= 0 && bp->bundleheight != (bundleheight - *bundleip) ) + { printf("bundlecreate warning: bp->bundleheight %d != %d (bundleheight %d - %d bundlei)\n",bp->bundleheight,(bundleheight - *bundleip),bundleheight,*bundleip); + return(0); + } else if ( bits256_nonz(bp->allhash) == 0 ) bp->allhash = allhash; return(bp); @@ -323,22 +342,26 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund struct iguana_txid *iguana_bundletx(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_txid *tx,int32_t txidind) { static bits256 zero; - int32_t hdrsi; int64_t Toffset; char fname[1024]; FILE *fp; struct iguana_ramchaindata rdata; - iguana_peerfname(coin,&hdrsi,"DB",fname,0,bp->hashes[0],zero,bp->n); - if ( (fp= fopen(fname,"rb")) != 0 ) + int32_t hdrsi,iter; int64_t Toffset; char fname[1024]; FILE *fp; struct iguana_ramchaindata rdata; + for (iter=0; iter<2; iter++) { - fseek(fp,(long)&rdata.Toffset - (long)&rdata,SEEK_SET); - if ( fread(&Toffset,1,sizeof(Toffset),fp) == sizeof(Toffset) ) + iguana_peerfname(coin,&hdrsi,iter==0?"DB/ro":"DB",fname,0,bp->hashes[0],zero,bp->n); + if ( (fp= fopen(fname,"rb")) != 0 ) { - fseek(fp,Toffset + sizeof(struct iguana_txid) * txidind,SEEK_SET); - if ( fread(tx,1,sizeof(*tx),fp) == sizeof(*tx) ) + fseek(fp,(long)&rdata.Toffset - (long)&rdata,SEEK_SET); + if ( fread(&Toffset,1,sizeof(Toffset),fp) == sizeof(Toffset) ) { - fclose(fp); - return(tx); - } else printf("bundletx read error\n"); - } else printf("bundletx Toffset read error\n"); - fclose(fp); - } else printf("bundletx couldnt open.(%s)\n",fname); + fseek(fp,Toffset + sizeof(struct iguana_txid) * txidind,SEEK_SET); + if ( fread(tx,1,sizeof(*tx),fp) == sizeof(*tx) ) + { + fclose(fp); + return(tx); + } else printf("bundletx read error\n"); + } else printf("bundletx Toffset read error\n"); + fclose(fp); + } + } + printf("bundletx couldnt open.(%s)\n",fname); return(0); } @@ -367,7 +390,7 @@ void iguana_bundlepurge(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t max,int32_t timelimit) { - int32_t i,j,k,len,starti,lag,doneval,nonz,total=0,maxval,numpeers,laggard,flag=0,finished,peercounts[IGUANA_MAXPEERS],donecounts[IGUANA_MAXPEERS],priority,counter = 0; + int32_t i,j,k,len,forceflag,saved,starti,lag,doneval,nonz,total=0,maxval,numpeers,laggard,flag=0,finished,peercounts[IGUANA_MAXPEERS],donecounts[IGUANA_MAXPEERS],priority,counter = 0; struct iguana_peer *addr; uint32_t now; struct iguana_block *block; bits256 hashes[50]; uint8_t serialized[sizeof(hashes) + 256]; if ( bp == 0 ) @@ -378,24 +401,23 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( coin->current != 0 ) starti = coin->current->hdrsi; else starti = 0; - priority = (bp->hdrsi < starti+8); - lag = (bp->hdrsi - starti); - lag *= lag; - if ( (i= sqrt(bp->hdrsi)) < 2 ) - i = 2; - if ( lag < i ) - lag = i; - else if ( lag > 10*i ) - lag = 10*i; - if ( (numpeers= coin->peers.numranked) > 8 )//&& bp->currentflag < bp->n ) + priority = (bp->hdrsi < starti + coin->peers.numranked); + if ( strcmp("BTC",coin->symbol) == 0 ) + lag = 10 + (bp->hdrsi - starti); + else lag = 3 + (bp->hdrsi - starti)/10; + if ( coin->current != bp ) + lag *= 3; + if ( (numpeers= coin->peers.numranked) > 3 )//&& bp->currentflag < bp->n ) { + if ( numpeers > 0xff ) + numpeers = 0xff; // fit into 8 bitfield if ( bp->currentflag == 0 ) bp->currenttime = now; - if ( bp->numhashes >= bp->n ) + if ( bp->numhashes >= 1 ) { for (j=0; jpeers.ranked[j]) != 0 && addr->dead == 0 && addr->usock >= 0 ) + if ( (addr= coin->peers.ranked[j]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 ) { now = (uint32_t)time(NULL); for (i=j,k=doneval=maxval=0; in&&kfpipbits == 0 ) { hashes[k++] = bp->hashes[i]; - bp->issued[i] = now; - block->issued = now; + bp->issued[i] = block->issued = now; block->peerid = j + 1; block->numrequests++; } @@ -476,23 +497,29 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { for (i=0; i threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag ) + if ( peercounts[i] > threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag && addr->dead == 0 ) { - if ( numpeers > 64 || addr->laggard++ > 3 ) + if ( (numpeers > 64 || addr->laggard++ > 13) && coin->current == bp ) + { addr->dead = (uint32_t)time(NULL); + addr->rank = 0; + } for (j=0; jn; j++) { if ( (block= bp->blocks[j]) != 0 && block->peerid == i && block->fpipbits == 0 ) { - printf("%d ",j); + if ( bp == coin->current ) + printf("%d ",j); flag++; counter++; block->peerid = 0; iguana_blockQ("kick",coin,bp,j,block->RO.hash2,bp == coin->current); - bp->issued[i] = block->issued = now; + if ( bp == coin->current ) + bp->issued[i] = block->issued = now; } } - printf("kill peer.%d %s reissued\n",i,addr->ipaddr); + if ( flag != 0 && bp == coin->current ) + printf("slow peer.%d dead.%u (%s) reissued.%d [%d]\n",i,addr->dead,addr->ipaddr,flag,bp->hdrsi); } } } @@ -506,67 +533,99 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int } for (i=0; in; i++) { - if ( (block= bp->blocks[i]) != 0 && block->fpipbits == 0 ) + if ( (block= bp->blocks[i]) != 0 && (bits256_nonz(block->RO.prev_block) == 0 || block->RO.recvlen == 0 || block->fpipbits == 0 || block->fpos < 0) ) { if ( now > block->issued+lag ) { counter++; + saved = block->issued; + if ( bp == coin->current ) + forceflag = (now > block->issued + lag); + else forceflag = (now > block->issued + 10*lag); if ( priority != 0 ) { - //if ( (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) - // iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current); - printf("[%d:%d] ",bp->hdrsi,i); - } else iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0); + //printf("[%d:%d] ",bp->hdrsi,i); + iguana_blockQ("kicka",coin,bp,i,block->RO.hash2,forceflag); + if ( forceflag != 0 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) + iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); + } + else if ( forceflag != 0 ) + iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,0); + if ( forceflag != 0 ) + bp->issued[i] = block->issued = now; + else bp->issued[i] = block->issued = saved; flag++; } //else printf("%d ",now - block->issued); } } - if ( flag != 0 && priority != 0 && laggard != 0 ) - printf("currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); - } + if ( flag != 0 && priority != 0 && laggard != 0 && coin->current == bp ) + printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); + } + if ( bp == coin->current ) + return(counter); } - if ( bp == coin->current ) - return(counter); for (i=0; in; i++) { if ( (block= bp->blocks[i]) != 0 ) { - if ( block->fpipbits == 0 || block->RO.recvlen == 0 ) + if ( block->fpipbits == 0 || block->RO.recvlen == 0 || block->fpos < 0 || ((bp->hdrsi != 0 || i > 0) && bits256_nonz(block->RO.prev_block) == 0) ) { if ( block->issued == 0 || now > block->issued+lag ) { block->numrequests++; if ( bp == coin->current ) - printf("[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0); + printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); + iguana_blockQ("kickc",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag); bp->issued[i] = block->issued = now; counter++; if ( --max <= 0 ) break; } - //else if ( block->fpipbits != 0 && ((bp->hdrsi == 0 && i == 0) || bits256_nonz(block->RO.prev_block) != 0) ) - // n++; } - } //else printf("iguana_bundleiters[%d] unexpected null block[%d]\n",bp->bundleheight,i); + } + else if ( bits256_nonz(bp->hashes[i]) != 0 && now > bp->issued[i]+lag ) + { + if ( bp == coin->current ) + printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); + iguana_blockQ("kickd",coin,bp,i,bp->hashes[i],bp == coin->current && now > bp->issued[i]+lag*3); + bp->issued[i] = now; + counter++; + } + else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+lag ) + { + if ( bp == coin->current ) + printf("[%d:%d] ",bp->hdrsi,i); + iguana_blockQ("kicke",coin,bp,i,bp->speculative[i],0); + bp->issued[i] = now; + counter++; + } } return(counter); } int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) { - int32_t i,ready,valid; struct iguana_block *block; + int32_t i,ready,valid,hdrsi,checki; struct iguana_block *block; char fname[1024]; static bits256 zero; for (i=ready=0; in; i++) { if ( (block= bp->blocks[i]) != 0 ) { //printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]); - if ( block->fpipbits == 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(coin,&valid,block,1) < 0 ) + if ( iguana_blockvalidate(coin,&valid,block,1) < 0 || block->fpipbits == 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) ) { - char str[65]; printf(">>>>>>> ipbits.%x null prevblock error at ht.%d patch.(%s) and reissue\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block)); - iguana_blockQ("null retry",coin,bp,i,block->RO.hash2,1); + fname[0] = 0; + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,block->RO.hash2,zero,1)) != i ) + printf("checki.%d vs %d mismatch?\n",checki,i); + if ( fname[0] != 0 ) + OS_removefile(fname,0); + printf(">>>>>>> block contents error at ht.%d (%s)\n",bp->bundleheight+i,fname); + //char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); + block->fpipbits = 0; + block->fpos = -1; + block->queued = 0; + block->RO.recvlen = 0; } else ready++; - } else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,iguana_blockfind(coin,bp->hashes[i])); + } else printf("error getting block (%d:%d) %p\n",bp->hdrsi,i,block); } return(ready); } @@ -574,13 +633,33 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti) { int32_t counter=0; - //if ( bp->speculative != 0 ) - // printf("hdr ITERATE bundle.%d vs %d: h.%d n.%d r.%d s.%d finished.%d speculative.%p\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,bp->speculative); - if ( strcmp(coin->symbol,"BTC") != 0 && bp->speculative == 0 && bp->numhashes < bp->n ) + int32_t i; uint32_t now; + if ( coin->enableCACHE != 0 && bp->speculative == 0 && bp->numhashes < bp->n ) { char str[64]; + if ( 0 && bp == coin->current ) + printf("hdr ITERATE bundle.%d vs %d: h.%d n.%d r.%d s.%d finished.%d speculative.%p\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,bp->speculative); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); } + if ( bp->speculative != 0 ) + { + now = (uint32_t)time(NULL); + for (i=0; inumspec; i++) + { + if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) != 0 ) + { + if ( now > bp->issued[i]+60 ) + { + bp->issued[i] = now; + //printf("speculative.[%d:%d]\n",bp->hdrsi,i); + iguana_blockQ("speculative",coin,0,-1,bp->speculative[i],0); + } + //break; + } + //else if ( bp->blocks[i] == 0 ) + // break; + } + } return(counter); } @@ -591,11 +670,11 @@ int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp) coin->current = coin->bundles[bp->hdrsi+1]; if ( (lastbp= coin->lastpending) != 0 && lastbp->hdrsi < coin->bundlescount-1 ) coin->lastpending = coin->bundles[lastbp->hdrsi + 1]; - if ( (rand() % 2) == 0 ) + if ( (rand() % 3) == 0 ) { - if ( coin->MAXBUNDLES > IGUANA_MINPENDBUNDLES ) + if ( coin->MAXBUNDLES > coin->endPEND ) coin->MAXBUNDLES--; - else if ( coin->MAXBUNDLES < IGUANA_MINPENDBUNDLES ) + else if ( coin->MAXBUNDLES < coin->endPEND ) coin->MAXBUNDLES++; } return(coin->MAXBUNDLES); @@ -603,72 +682,97 @@ int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp) int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) { - FILE *fp; int32_t bundlei,checki,hdrsi,numhashes,numsaved,numcached,numrecv,minrequests; - int64_t datasize; struct iguana_block *block; char fname[1024]; static bits256 zero; + int32_t bundlei,checki,hdrsi,numhashes,numsaved,numcached,numrecv,minrequests; FILE *fp; + int64_t datasize; struct iguana_block *block; uint32_t now; char fname[1024]; static bits256 zero; if ( bp->emitfinish > coin->startutc ) { bp->numhashes = bp->numsaved = bp->numcached = bp->numrecv = bp->n; return(bp->datasize); } + now = (uint32_t)time(NULL); datasize = numhashes = numsaved = numcached = numrecv = minrequests = 0; for (bundlei=0; bundlein; bundlei++) { - if ( bits256_nonz(bp->hashes[bundlei]) > 0 && (block= bp->blocks[bundlei]) != 0 ) + block = bp->blocks[bundlei]; + if ( bits256_nonz(bp->hashes[bundlei]) > 0 && block != 0 ) { - if ( block == iguana_blockfind(coin,bp->hashes[bundlei]) ) + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); + if ( bits256_cmp(block->RO.hash2,bp->hashes[bundlei]) == 0 ) { - if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + if ( checki != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) { printf("iguana_bundlecalcs.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); continue; } - if ( 1 && bp->checkedtmp < bp->n && (fp= fopen(fname,"rb")) != 0 ) + if ( coin->current == bp ) { - fseek(fp,0,SEEK_END); - if ( block->RO.recvlen == 0 ) + if ( (fp= fopen(fname,"rb")) != 0 ) { + fseek(fp,0,SEEK_END); block->RO.recvlen = (uint32_t)ftell(fp); block->fpipbits = 1; block->fpos = 0; - //printf("[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); + //printf("fp.[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); + fclose(fp); + } + else + { + //char str[65]; printf("missing.(%s) issue.%s\n",fname,bits256_str(str,bp->hashes[bundlei])); + block->RO.recvlen = 0; + block->fpipbits = 0; + block->fpos = -1; + //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); } - fclose(fp); } - bp->blocks[bundlei] = block; block->hdrsi = bp->hdrsi, block->bundlei = bundlei; if ( bp->minrequests == 0 || (block->numrequests > 0 && block->numrequests < bp->minrequests) ) bp->minrequests = block->numrequests; if ( (bp->hdrsi == 0 && bundlei == 0) || bits256_nonz(block->RO.prev_block) > 0 ) { - if ( block->fpipbits != 0 ) //block->fpos >= 0 && + if ( block->queued != 0 ) + numcached++; + if ( block->fpipbits != 0 && block->fpos >= 0 ) numsaved++; - if ( block->RO.recvlen != 0 || block->fpipbits != 0 || block->fpos >= 0 )//|| block->queued != 0 ) + if ( block->RO.recvlen != 0 || block->fpipbits != 0 || block->fpos >= 0 ) { numrecv++; datasize += block->RO.recvlen; - if ( block->queued != 0 ) - numcached++; - } + } } - /*else //if ( 0 ) + else if ( bp == coin->current ) { - printf("cleared block?\n"); - //block->RO.recvlen = 0; - //block->fpipbits = 0; - //block->fpos = -1; - //block->issued = bp->issued[bundlei] = 0; - }*/ + char str[65]; printf("missing prev_block [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei])); + if ( block != 0 ) + { + block->RO.recvlen = 0; + block->fpipbits = 0; + block->fpos = -1; + } + //else if ( now > bp->issued[bundlei]+1 ) + iguana_blockQ("missing",coin,bp,bundlei,bp->hashes[bundlei],1); + } } - else if ( 0 ) + /*else { - bp->blocks[bundlei] = iguana_blockfind(coin,bp->hashes[bundlei]); - bp->hashes[bundlei] = bp->blocks[bundlei]->RO.hash2; - if ( (block= bp->blocks[bundlei]) != 0 ) - block->fpipbits = block->queued = 0; - } + char str[65],str2[65]; printf(" mismatched [%d:%d] %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2)); + //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); + bp->issued[bundlei] = 0; + bp->blocks[bundlei] = 0; + memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); + OS_removefile(fname,0); + }*/ numhashes++; bp->checkedtmp++; } + else if ( bp == coin->current ) + { + if ( bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei]) != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+60 ) + { + //char str[65]; printf(" mismatched [%d:%d] %s block.%p\n",bp->hdrsi,bundlei,bits256_str(str,bp->speculative[bundlei]),block); + iguana_blockQ("missing",coin,0,-1,bp->speculative[bundlei],0); + bp->issued[bundlei] = (uint32_t)time(NULL); + } + } } bp->datasize = datasize; bp->numhashes = numhashes; @@ -682,52 +786,78 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { - struct iguana_bundle *prevbp; int32_t prevdone = 0; - if ( (prevbp= coin->bundles[bp->hdrsi-1]) != 0 && prevbp->balancefinish > 1 ) - prevdone = 1; - else if ( coin->current != 0 && prevbp != 0 && coin->current->hdrsi >= prevbp->hdrsi && prevbp->emitfinish > 1 && time(NULL) > prevbp->emitfinish+3 ) - prevdone = 1; - if ( bp->hdrsi == 0 || prevdone != 0 ) + struct iguana_bundle *prevbp; int32_t i,retval; +#ifdef IGUANA_SERIALIZE_SPENDVECTORGEN + //if ( coin->MAXMEM <= 4*(1024L * 1024 * 1024) ) + { + if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-0*coin->MAXBUNDLES ) + return(0); + } +#endif + for (i=0; ihdrsi; i++) + if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) + break; + if ( i == bp->hdrsi ) { if ( bp->startutxo == 0 ) { bp->startutxo = (uint32_t)time(NULL); - if ( iguana_utxogen(coin,bp) >= 0 ) + if ( (retval= iguana_spendvectors(coin,bp)) >= 0 ) { - printf("GENERATED UTXO.%d for ht.%d duration %d seconds\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo); - bp->utxofinish = (uint32_t)time(NULL); - iguana_balancesQ(coin,bp); + if ( retval > 0 ) + { + printf("GENERATED UTXO.%d for ht.%d duration %d seconds\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo); + bp->utxofinish = (uint32_t)time(NULL); + bp->balancefinish = 0; + } + if ( bp->balancefinish == 0 ) + iguana_balancesQ(coin,bp); return(1); } else printf("UTXO gen.[%d] utxo error\n",bp->hdrsi); } + else if ( bp->utxofinish != 0 ) + { + if ( bp->balancefinish == 0 ) + iguana_balancesQ(coin,bp); + return(1); + } } // else printf("%u notready postfinish.%d startutxo.%u prevbp.%d %u current.%d\n",(uint32_t)time(NULL),bp->hdrsi,bp->startutxo,prevbp!=0?prevbp->hdrsi:-1,prevbp!=0?prevbp->emitfinish:0,coin->current!=0?coin->current->hdrsi:-1); return(0); } int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit) { - int32_t range,starti,lasti,retval=0,max,counter = 0; struct iguana_bundle *currentbp,*lastbp; - bp->nexttime = (uint32_t)time(NULL) + 1; + int32_t range,starti,lasti,retval=0,max,counter = 0; struct iguana_bundle *currentbp,*lastbp; if ( coin->started == 0 ) { + printf("%s not ready yet\n",coin->symbol); + bp->nexttime = (uint32_t)time(NULL) + 3; iguana_bundleQ(coin,bp,1000); return(retval); } if ( coin->current == 0 ) coin->current = coin->bundles[0]; - if ( (range= coin->peers.numranked) > coin->MAXBUNDLES ) - range = coin->MAXBUNDLES; + range = coin->MAXBUNDLES; currentbp = coin->current; lastbp = coin->lastpending; starti = currentbp == 0 ? 0 : currentbp->hdrsi; lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; - coin->numbundlesQ--; - iguana_bundlecalcs(coin,bp); - //printf("ITERATE.%d bundle.%d h.%d n.%d r.%d s.%d F.%d T.%d counter.%d\n",bp->rank,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter); + if ( bp != coin->current || bp->dirty != 0 ) + { + iguana_bundlecalcs(coin,bp); + bp->dirty = 0; + } + if ( bp->hdrsi == coin->bundlescount-1 ) + { + iguana_autoextend(coin,bp); + //printf("ITER now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); + } + bp->nexttime = (uint32_t)(time(NULL) + 1);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); else if ( bp->emitfinish != 0 ) { + bp->nexttime += 10; if ( bp->emitfinish > 1 ) { if ( (retval= iguana_bundlefinish(coin,bp)) > 0 ) @@ -742,7 +872,12 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { if ( iguana_bundleready(coin,bp) == bp->n ) { - printf(">>>>>>>>>>>>>>>>>>>>>>> EMIT bundle.%d | 1st.%d h.%d s.[%d] maxbundles.%d NET.(h%d b%d)\n",bp->bundleheight,coin->current!=0?coin->current->hdrsi:-1,coin->current!=0?coin->current->numhashes:-1,coin->current!=0?coin->current->numsaved:-1,coin->MAXBUNDLES,HDRnet,netBLOCKS); + printf(">>>>>>>>>>>>>>>>>>>>>>> EMIT.%s bundle.%d | 1st.%d h.%d s.[%d] maxbundles.%d NET.(h%d b%d)\n",coin->symbol,bp->bundleheight,coin->current!=0?coin->current->hdrsi:-1,coin->current!=0?coin->current->numhashes:-1,coin->current!=0?coin->current->numsaved:-1,coin->MAXBUNDLES,HDRnet,netBLOCKS); + if ( bp->emitfinish != 0 ) + { + printf("already EMIT for bundle.%d\n",bp->hdrsi); + return(0); + } bp->emitfinish = 1; iguana_bundletweak(coin,bp); sleep(1); // just in case data isnt totally sync'ed to HDD @@ -752,7 +887,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) { - fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d\n",coin,bp->hdrsi,bp->bundleheight); + //fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d\n",coin,bp->hdrsi,bp->bundleheight); bp->emitfinish = (uint32_t)time(NULL) + 1; coin->numemitted++; } @@ -769,14 +904,16 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { max = bp->n; counter = iguana_bundleissue(coin,bp,max,timelimit); - if ( 0 && counter > 0 ) - printf("ITERATE.%d max.%d bundle.%d h.%d n.%d r.%d s.%d F.%d T.%d counter.%d\n",bp->rank,max,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter); + if ( bp == coin->current && coin->isRT == 0 ) + bp->nexttime--; + if ( bp->hdrsi == starti && counter > 0 ) + printf("ITER now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); } iguana_bundleQ(coin,bp,1000); return(retval); } -static int _decreasing_double(const void *a,const void *b) +/*static int _decreasing_double(const void *a,const void *b) { #define double_a (*(double *)a) #define double_b (*(double *)b) @@ -793,22 +930,85 @@ static int32_t revsortds(double *buf,uint32_t num,int32_t size) { qsort(buf,num,size,_decreasing_double); return(0); -} +}*/ void iguana_bundlestats(struct iguana_info *coin,char *str) { - static uint32_t lastdisp; - int32_t i,n,m,numv,count,pending,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; - int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; double *sortbuf; struct iguana_peer *addr; - dispflag = (rand() % 1000) == 0; + int32_t i,n,m,j,numv,r,count,pending,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; + int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; struct iguana_block *block,*prev; uint32_t now; struct iguana_peer *addr; + now = (uint32_t)time(NULL); + dispflag = 1;//(rand() % 1000) == 0; numrecv = numhashes = numcached = numsaved = numemit = done = numutxo = numbalances = 0; count = coin->bundlescount; - sortbuf = calloc(count,sizeof(*sortbuf)*2); + //sortbuf = calloc(count,sizeof(*sortbuf)*2); for (i=n=m=numv=pending=0; ibundles[i]) != 0 ) { - bp->rank = 0; + if ( bp->emitfinish > 1 ) + { + for (j=0; jn; j++) + if ( bp->blocks[j] == 0 ) + bp->blocks[j] = iguana_blockfind(coin,bp->hashes[j]); + } + //if ( iguana_blockfind(coin,bp->hashes[0]) == 0 ) + // printf("UNEXPECTED null block for bundlehash.%d\n",bp->hdrsi); + if ( bp->numhashes < bp->n && bp->speculative != 0 ) + { + //for (j=1; jnumspec&&jn; j++) + // iguana_blockhashset(coin,-1,bp->speculative[j],1); + //char str[65],str2[65]; + for (j=1; jnumspec&&jn; j++) + { + if ( (block= bp->blocks[j]) == 0 ) + { + if ( bits256_nonz(bp->hashes[j]) != 0 ) + block = iguana_blockfind(coin,bp->hashes[j]); + else if ( bits256_nonz(bp->speculative[j]) != 0 ) + { + if ( (block= iguana_blockfind(coin,bp->speculative[j])) == 0 ) + block = iguana_blockhashset(coin,-1,bp->speculative[j],1); + } + } + else if ( bits256_nonz(block->RO.prev_block) != 0 && block->fpipbits != 0 ) + continue; + prev = bp->blocks[j-1]; + //printf("[%d:%d] prev.%p nonz.%d speculative.%d block.%p\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bp->blocks[j]); + if ( block != 0 && bp->blocks[j] == 0 ) //prev != 0 && + { + //char str2[65]; printf("[%d:%d] prev.%p nonz.%d speculative.%d prev.%s vs %s ipbits.%x q.%d\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bits256_str(str,prev->RO.hash2),bits256_str(str2,block->RO.prev_block),block->fpipbits,block->queued); + if ( block->fpipbits == 0 && block->queued == 0 ) + { + if ( block->req != 0 ) + { + block->queued = 1; + queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); + block->req = 0; + //printf("submit cached [%d:%d]\n",bp->hdrsi,j); + } + else if ( now > block->issued+10 ) + { + block->issued = now; + //printf("submit speculative [%d:%d]\n",bp->hdrsi,j); + iguana_blockQ("spec",coin,0,-1,block->RO.hash2,0); + } + } + } // else break; + } + } + else if ( bp == coin->current ) + { + for (j=0; jn; j++) + if ( (block= bp->blocks[j]) != 0 && (block->RO.recvlen == 0 || block->fpipbits == 0 || block->fpos < 0) && time(NULL) > block->issued+3 && (rand() % 10) == 0 ) + { + if ( (r= coin->peers.numranked) != 0 && (addr= coin->peers.ranked[rand() % r]) != 0 && addr->dead == 0 && addr->usock >= 0 ) + iguana_sendblockreqPT(coin,addr,bp,j,block->RO.hash2,0); printf("current stop [%d:%d]\n",bp->hdrsi,j); + iguana_blockQ("currentstop",coin,bp,j,block->RO.hash2,1); + block->issued = (uint32_t)time(NULL); + break; + } + } + //bp->rank = 0; estsize += bp->estsize;//iguana_bundlecalcs(coin,bp,done); //bp->metric = bp->numhashes; bp->metric = coin->bundlescount - bp->hdrsi; @@ -828,28 +1028,32 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) { done++; numemit++; - iguana_bundlepurge(coin,bp); + if ( firstgap != 0 && bp->hdrsi > firstgap->hdrsi-3 ) + iguana_bundlepurge(coin,bp); } else { - if ( ++pending == coin->MAXBUNDLES ) + if ( firstgap == 0 && (bp->emitfinish == 0 || bp->n < coin->chain->bundlesize) ) { - lastpending = bp; - //printf("SET MAXBUNDLES.%d pend.%d\n",bp->hdrsi,pending); - } - if ( firstgap == 0 ) + //printf("firstgap <- [%d] emit.%u bp->n.%d\n",bp->hdrsi,bp->emitfinish,bp->n); firstgap = bp; + } if ( bp->emitfinish == 0 ) { + if ( ++pending == coin->MAXBUNDLES ) + { + lastpending = bp; + //printf("SET MAXBUNDLES.%d pend.%d\n",bp->hdrsi,pending); + } spaceused += bp->estsize; - sortbuf[m*2] = bp->metric; - sortbuf[m*2 + 1] = i; + //sortbuf[m*2] = bp->metric; + //sortbuf[m*2 + 1] = i; m++; } } } } - if ( m > 0 ) + /*if ( m > 0 ) { revsortds(sortbuf,m,sizeof(*sortbuf)*2); for (i=0; inumremain = n; coin->blocksrecv = numrecv; char str2[65]; uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now(); @@ -875,24 +1079,28 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) tmp %= 1000000000; difft.millis = ((double)tmp / 1000000.); if ( (coin->current= firstgap) == 0 ) - coin->current = coin->bundlescount > 0 ? coin->bundles[coin->bundlescount-1] : coin->bundles[0]; + { + firstgap = coin->current = (coin->bundlescount > 0) ? coin->bundles[coin->bundlescount-1] : coin->bundles[0]; + //printf("bundlescount.%d %p[%d]\n",coin->bundlescount,coin->current,coin->current->hdrsi); + } if ( lastpending != 0 ) coin->lastpending = lastpending; else coin->lastpending = coin->bundles[coin->bundlescount - 1]; coin->numsaved = numsaved; coin->spaceused = spaceused; coin->numverified = numv; - char str4[65]; - sprintf(str,"u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d M.%d L.%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d)",numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:0,firstgap!=0?firstgap->hdrsi:0,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->blocks.hwmchain.height,coin->longestchain,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); + char str4[65],str5[65]; + sprintf(str,"%s.RT%d u.%d b.%d v.%d/%d (%d/%d 1st.%d) to %d N[%d] h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s peers.%d/%d Q.(%d %d) L.%d [%d:%d] M.%d %s",coin->symbol,coin->RTheight,numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->numhashes:-1,firstgap!=0?firstgap->hdrsi:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,coin->blocks.hwmchain.height/coin->chain->bundlesize,coin->blocks.hwmchain.height%coin->chain->bundlesize,coin->blocks.hwmchain.height,bits256_str(str5,coin->blocks.hwmchain.RO.hash2)); //sprintf(str+strlen(str),"%s.%-2d %s time %.2f files.%d Q.%d %d\n",coin->symbol,flag,str,(double)(time(NULL)-coin->starttime)/60.,coin->peers.numfiles,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); - if ( time(NULL) > lastdisp+10 ) + if ( time(NULL) > coin->lastdisp+3 && strcmp(str,coin->lastdispstr) != 0 ) { - printf("%s\n",str); + printf("\n%s bQ.%d %d:%02d:%02d %03.3f\n",str,coin->numbundlesQ,(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis); + strcpy(coin->lastdispstr,str); if ( (rand() % 100) == 0 ) myallocated(0,0); - lastdisp = (uint32_t)time(NULL); - //if ( firstgap != 0 && firstgap->queued == 0 ) - // iguana_bundleQ(coin,firstgap,1000); + coin->lastdisp = (uint32_t)time(NULL); + if ( firstgap != 0 && firstgap->queued == 0 ) + iguana_bundleQ(coin,firstgap,1000); } strcpy(coin->statusstr,str); coin->estsize = estsize; diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 9cb31693f..5426e17a7 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -32,7 +32,6 @@ void iguana_initQs(struct iguana_info *coin) iguana_initQ(&coin->priorityQ,"priorityQ"); iguana_initQ(&coin->possibleQ,"possibleQ"); iguana_initQ(&coin->cacheQ,"cacheQ"); - iguana_initQ(&coin->TerminateQ,"TerminateQ"); iguana_initQ(&coin->recvQ,"recvQ"); for (i=0; ipeers.active[i].sendQ,"addrsendQ"); @@ -43,7 +42,7 @@ void iguana_initpeer(struct iguana_info *coin,struct iguana_peer *addr,uint64_t memset(addr,0,sizeof(*addr)); addr->ipbits = ipbits; addr->usock = -1; - expand_ipbits(addr->ipaddr,addr->ipbits); + expand_ipbits(addr->ipaddr,(uint32_t)addr->ipbits); //addr->pending = (uint32_t)time(NULL); strcpy(addr->symbol,coin->symbol); strcpy(addr->coinstr,coin->name); @@ -52,9 +51,9 @@ void iguana_initpeer(struct iguana_info *coin,struct iguana_peer *addr,uint64_t void iguana_initcoin(struct iguana_info *coin,cJSON *argjson) { - int32_t i; - //sprintf(dirname,"%s/%s",GLOBALTMPDIR,coin->symbol), OS_portable_path(dirname); - //OS_portable_rmdir(dirname,0); + int32_t i; char dirname[1024]; + sprintf(dirname,"%s/%s",GLOBALTMPDIR,coin->symbol), OS_portable_path(dirname); + sprintf(dirname,"tmp/%s",coin->symbol), OS_portable_path(dirname); portable_mutex_init(&coin->peers_mutex); portable_mutex_init(&coin->blocks_mutex); portable_mutex_init(&coin->scripts_mutex[0]); @@ -276,13 +275,6 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) bp->emitfinish = (uint32_t)time(NULL) + 1; if ( coin->current != 0 && coin->current->hdrsi+1 == bp->hdrsi ) coin->current = bp; - //printf("LOADED bundle.%d %p current %p\n",bp->bundleheight,bp,coin->current); - //if ( bp->hdrsi == 0 || coin->bundles[bp->hdrsi-1]->emitfinish != 0 ) - { - //bp->startutxo = (uint32_t)time(NULL); - //printf("GENERATE UTXO, verify sigs, etc for ht.%d\n",bp->bundleheight); - iguana_bundleQ(coin,bp,1000); - } } else { @@ -308,16 +300,25 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) } if ( iter == 1 ) { - for (i=0; ibundlescount; i++) - if ( coin->bundles[i] == 0 ) - break; - printf("INIT bundles i.%d\n",i); - if ( i > 0 ) + if ( coin->balanceswritten > 0 ) + coin->balanceswritten = iguana_volatileinit(coin); + if ( coin->balanceswritten > 0 ) { - //iguana_spentsfile(coin,i); + for (i=0; ibalanceswritten; i++) + iguana_validateQ(coin,coin->bundles[i]); + } + if ( coin->balanceswritten < coin->bundlescount ) + { + for (i=coin->balanceswritten; ibundlescount; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->queued == 0 ) + { + printf("%d ",i); + iguana_bundleQ(coin,bp,1000); + } + } + printf("BALANCESQ\n"); } - char buf[1024]; - iguana_bundlestats(coin,buf); } } @@ -359,7 +360,6 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei #ifndef IGUANA_DEDICATED_THREADS coin->peers.peersloop = iguana_launch("peersloop",iguana_peersloop,coin,IGUANA_PERMTHREAD); #endif - coin->MAXBUNDLES = IGUANA_MAXPENDBUNDLES; printf("started.%s\n",coin->symbol); return(coin); } diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index dad820714..4bdc8f9d9 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -170,9 +170,15 @@ void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct addr->dead = (uint32_t)time(NULL); if ( (vers->nServices & (1<<7)) == (1<<7) ) addr->supernet = 1; - else printf("nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet); + printf("nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet); if ( vers->nStartingHeight > coin->longestchain ) - coin->longestchain = vers->nStartingHeight; + { + if ( coin->badlongestchain != 0 && vers->nStartingHeight >= coin->badlongestchain ) + { + printf("peer.(%s) gives badlongestchain.%d\n",addr->ipaddr,vers->nStartingHeight); + addr->dead = 1; + } else coin->longestchain = (vers->nStartingHeight + coin->longestchain + 1) >> 1; + } iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); } diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 4de289c0b..2b5aef7aa 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -18,7 +18,7 @@ #define _iguana_hashfind(coin,ipbits) _iguana_hashset(coin,ipbits,-1) struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbits,int32_t createflag); -struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint64_t ipbits,int32_t itemind) +struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint32_t ipbits,int32_t itemind) { struct iguana_iAddr *ptr = 0; int32_t allocsize; char str[65]; struct OS_memspace *mem = 0; expand_ipbits(str,ipbits); @@ -61,15 +61,15 @@ struct iguana_iAddr *iguana_iAddrhashset(struct iguana_info *coin,struct iguana_ return(0); } portable_mutex_lock(&coin->peers_mutex); - if ( (item= _iguana_hashfind(coin,iA->ipbits)) == 0 ) + if ( (item= _iguana_hashfind(coin,(uint32_t)iA->ipbits)) == 0 ) { tmp = mycalloc('i',1,sizeof(*iA)); *tmp = *iA; iA = tmp; if ( ind <= 0 ) ind = coin->numiAddrs + 1; - //printf("coin->iAddrs.%p call set.(%x) ind.%d\n",coin->iAddrs,iA->ipbits,iA->ind); - if ( (item= _iguana_hashset(coin,iA->ipbits,ind)) != 0 && item->hh.itemind == coin->numiAddrs+1 ) + printf("coin->iAddrs.%p call set.(%x) ind.%d\n",coin->iAddrs,(uint32_t)iA->ipbits,ind); + if ( (item= _iguana_hashset(coin,(uint32_t)iA->ipbits,ind)) != 0 && item->hh.itemind == coin->numiAddrs+1 ) { *item = *iA; iA = item; @@ -93,11 +93,11 @@ struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbi portable_mutex_lock(&coin->peers_mutex); if ( ipbits != 0 ) { - if ( (item= _iguana_hashfind(coin,ipbits)) == 0 && createflag != 0 ) + if ( (item= _iguana_hashfind(coin,(uint32_t)ipbits)) == 0 && createflag != 0 ) { ind = coin->numiAddrs + 1; - _iguana_hashset(coin,ipbits,ind); - if ( (item= _iguana_hashfind(coin,ipbits)) != 0 ) + _iguana_hashset(coin,(uint32_t)ipbits,ind); + if ( (item= _iguana_hashfind(coin,(uint32_t)ipbits)) != 0 ) coin->numiAddrs++; } } @@ -107,7 +107,7 @@ struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbi uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana_iAddr *iA,uint32_t ind) { - FILE *fp; char fname[512],hexstr[65]; int32_t i,n,m,retval = 0; struct iguana_iAddr tmp,*ptr; + FILE *fp; char fname[512],hexstr[65]; uint32_t ipbits; int32_t i,n,m,retval = 0; struct iguana_iAddr tmp,*ptr; sprintf(fname,"DB/%s_peers.dat",coin->symbol); OS_compatible_path(fname); if ( rwflag < 0 || iA == 0 ) @@ -117,13 +117,14 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana { fseek(fp,0,SEEK_END); n = (int32_t)(ftell(fp) / sizeof(*iA)); - for (i=m=0; ipeers_mutex); - HASH_FIND(hh,coin->iAddrs,&tmp.ipbits,sizeof(tmp.ipbits),ptr); + ipbits = (uint32_t)tmp.ipbits; + HASH_FIND(hh,coin->iAddrs,&ipbits,sizeof(ipbits),ptr); if ( ptr == 0 ) { ptr = mycalloc('t',1,sizeof(*ptr)); @@ -131,19 +132,25 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana printf("fatal alloc error in hashset\n"), exit(-1); ptr->hh.itemind = m; ptr->ipbits = tmp.ipbits; - HASH_ADD(hh,coin->iAddrs,ipbits,sizeof(tmp.ipbits),ptr); - if ( i != m ) - { - tmp.hh.itemind = m; - fseek(fp,m*sizeof(tmp),SEEK_SET); - fwrite(&tmp,1,sizeof(tmp),fp); - } - //printf("m.%d %x\n",m,tmp.ipbits); + HASH_ADD(hh,coin->iAddrs,ipbits,sizeof(ipbits),ptr); + tmp.hh.itemind = m; + fseek(fp,m*sizeof(tmp),SEEK_SET); + fwrite(&tmp,1,sizeof(tmp),fp); + expand_ipbits(hexstr,ipbits); + //printf("create rwiAddrind m.%-4d %08x %s\n",m,(uint32_t)tmp.ipbits,hexstr); m++; coin->numiAddrs = m; - expand_ipbits(hexstr,tmp.ipbits); iguana_possible_peer(coin,hexstr); } + /*else + { + expand_ipbits(hexstr,ipbits); + //printf("status.%d ipbits.%x\n",tmp.status,(uint32_t)ipbits); + tmp.status = 0; + fseek(fp,i * sizeof(tmp),SEEK_SET); + if ( fwrite(&tmp,1,sizeof(tmp),fp) != sizeof(tmp) ) + printf("error writing peer.%d\n",i); + }*/ portable_mutex_unlock(&coin->peers_mutex); } } @@ -180,6 +187,15 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana fp = fopen(fname,"wb"); if ( fp != 0 ) { + ipbits = (uint32_t)iA->ipbits; + HASH_FIND(hh,coin->iAddrs,&ipbits,sizeof(ipbits),ptr); + if ( ptr != 0 && ptr->hh.itemind != ind ) + { + printf("mismatch iAddr ind.%d != %d\n",ptr->hh.itemind,ind); + ind = ptr->hh.itemind; + } + if ( ind <= 0 ) + ind = coin->numiAddrs++; fseek(fp,ind * sizeof(*iA),SEEK_SET); if ( ftell(fp) == ind * sizeof(*iA) ) { @@ -191,7 +207,7 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana if ( (iA= iguana_iAddrhashset(coin,iA,ind)) != 0 ) { retval = iA->hh.itemind+1; - //printf("W %p ipbits.%x ind.%d saved iA->ind.%d retval.%d\n",iA,iA->ipbits,ind,iA->hh. itemind,retval); + //printf("W status.%d ipbits.%x ind.%d saved iA->ind.%d retval.%d numiAddrs.%d\n",iA->status,(uint32_t)ipbits,ind,iA->hh.itemind,retval,coin->numiAddrs); } } } else printf("iAddr: error seeking.[%d] %ld vs %ld\n",ind,ftell(fp),ind * sizeof(*iA)); @@ -247,8 +263,8 @@ void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t mar } else printf("killconnection cant get ind for ipaddr.%s\n",addr->ipaddr); memset(addr,0,sizeof(*addr)); addr->usock = -1; - if ( rank > 0 ) - iguana_possible_peer(coin,ipaddr); + //if ( rank > 0 ) + // iguana_possible_peer(coin,ipaddr); } int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) @@ -302,7 +318,9 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) if ( result != 0 ) { if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) - printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + { + //printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + } if ( sock >= 0 ) closesocket(sock); return(-1); @@ -558,8 +576,8 @@ void iguana_gotdata(struct iguana_info *coin,struct iguana_peer *addr,int32_t he //iguana_set_iAddrheight(coin,addr->ipbits,height); addr->height = height; } - if ( height > coin->longestchain ) - coin->longestchain = height; + if ( height > 0 && height > coin->longestchain ) + coin->longestchain = (height + coin->longestchain + 1) >> 1; } int32_t iguana_iAddrheight(struct iguana_info *coin,uint64_t ipbits) @@ -622,7 +640,7 @@ void iguana_startconnection(void *arg) n++; iguana_iAconnected(coin,addr); coin->peers.numconnected++; - printf("PEER CONNECTED.%d:%d of max.%d! %s:%d usock.%d\n",coin->peers.numconnected,n,coin->MAXPEERS,addr->ipaddr,coin->chain->portp2p,addr->usock); + printf("%s.PEER CONNECTED.%d:%d of max.%d! %s:%d usock.%d\n",coin->symbol,coin->peers.numconnected,n,coin->MAXPEERS,addr->ipaddr,coin->chain->portp2p,addr->usock); if ( strcmp("127.0.0.1",addr->ipaddr) == 0 ) coin->peers.localaddr = addr; else if ( coin->peers.numranked == 0 ) @@ -688,9 +706,9 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) { //printf("%x\n",iA->ipbits); //portable_mutex_unlock(&coin->peers_mutex); - if ( (addr= iguana_peerslot(coin,iA->ipbits,0)) != 0 )//i < coin->MAXPEERS && i < IGUANA_MAXPEERS && addr != 0 ) + if ( (addr= iguana_peerslot(coin,iA->ipbits,0)) != 0 ) { - //printf("pend.%d status.%d possible peer.(%s).%x threads %d %d %d %d\n",addr->pending,iA->status,addr->ipaddr,addr->ipbits,iguana_numthreads(coin,0),iguana_numthreads(coin,1),iguana_numthreads(coin,2),iguana_numthreads(coin,3)); + //printf("pend.%d status.%d possible peer.(%s).%x threads %d %d %d %d\n",addr->pending,iA->status,addr->ipaddr,(uint32_t)addr->ipbits,iguana_numthreads(coin,0),iguana_numthreads(coin,1),iguana_numthreads(coin,2),iguana_numthreads(coin,3)); if ( addr->pending == 0 && iA->status != IGUANA_PEER_CONNECTING ) { if ( iguana_rwiAddrind(coin,1,iA,iA->hh.itemind) > 0 ) @@ -739,7 +757,7 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) { if ( strcmp(ipaddr,coin->peers.active[i].ipaddr) == 0 ) { - printf("(%s) already active\n",ipaddr); + //printf("(%s) already active\n",ipaddr); free_queueitem(ipaddr); return((uint32_t)time(NULL)); } @@ -941,8 +959,8 @@ int64_t iguana_peerallocated(struct iguana_info *coin,struct iguana_peer *addr) void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) { static uint32_t lastping; - struct pollfd fds; struct iguana_bundlereq *req; char fname[1024]; uint8_t *buf;//,serialized[64]; - uint32_t ipbits; int32_t bufsize,flag,run,timeout = coin->polltimeout == 0 ? 10 : coin->polltimeout; + struct pollfd fds; struct iguana_bundlereq *req; char fname[1024]; uint8_t *buf; uint32_t ipbits; + int32_t bufsize,flag,run,timeout = coin->polltimeout == 0 ? 10 : coin->polltimeout; #ifdef IGUANA_PEERALLOC int32_t i; int64_t remaining; struct OS_memspace *mem[sizeof(addr->SEROUT)/sizeof(*addr->SEROUT)]; for (i=0; iSEROUT)/sizeof(*addr->SEROUT); i++) @@ -958,16 +976,19 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) } #endif addr->addrind = (int32_t)(((long)addr - (long)&coin->peers.active[0]) / sizeof(*addr)); - ipbits = (uint32_t)addr->ipbits; - sprintf(fname,"DB/%s/vouts/%08x.vouts",coin->symbol,ipbits); + sprintf(fname,"DB/%s/vouts/%04d.vouts",coin->symbol,addr->addrind); if ( (addr->voutsfp= fopen(fname,"rb+")) != 0 ) fseek(addr->voutsfp,0,SEEK_END); else addr->voutsfp = fopen(fname,"wb+"); - sprintf(fname,"purgeable/%s/%08x.vins",coin->symbol,ipbits); - if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) - fseek(addr->vinsfp,0,SEEK_END); - else addr->vinsfp = fopen(fname,"wb+"); + if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) + { + sprintf(fname,"purgeable/%s/%04d.vins",coin->symbol,addr->addrind); + if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) + fseek(addr->vinsfp,0,SEEK_END); + else addr->vinsfp = fopen(fname,"wb+"); + } //addr->pubkey = GENESIS_PUBKEY; + ipbits = (uint32_t)addr->ipbits; vcalc_sha256(0,addr->iphash.bytes,(uint8_t *)&ipbits,sizeof(ipbits)); //char str[65]; printf("start dedicatedloop.%s addrind.%d %s\n",addr->ipaddr,addr->addrind,bits256_str(str,addr->iphash)); addr->maxfilehash2 = IGUANA_MAXFILEITEMS; @@ -992,7 +1013,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) { if ( req->datalen != 0 ) { - char str[65]; printf("CACHE.%p parse[%d] %s %s\n",req,req->recvlen,req->H.command,bits256_str(str,req->block.RO.hash2)); + //char str[65]; printf("CACHE.%p parse[%d] %s %s\n",req,req->recvlen,req->H.command,bits256_str(str,req->block.RO.hash2)); iguana_parsebuf(coin,addr,&req->H,req->serialized,req->recvlen); } else printf("CACHE error no datalen\n"); coin->cachefreed++; @@ -1047,8 +1068,8 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) usleep(100000); } else if ( addr->rank != 1 ) - usleep(coin->polltimeout*3000 + 1*(rand() % (coin->polltimeout*3000))); - else usleep(1000); + usleep(coin->polltimeout*5000 + 1*(rand() % (coin->polltimeout*3000))); + else usleep(10000 + coin->backlog); } else run >>= 2; } if ( flag != 0 ) @@ -1076,13 +1097,13 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) } } } - else if ( coin->isRT != 0 && addr->rank > coin->MAXPEERS && (rand() % 100) == 0 ) + else if ( coin->isRT != 0 && addr->rank > coin->MAXPEERS && (rand() % 10) == 0 ) { - printf("isRT and low rank.%d ",addr->rank); + //printf("isRT and low rank.%d ",addr->rank); addr->dead = 1; } } - printf(">>>>>>>>>>>>>> finish dedicatedloop.%s\n",addr->ipaddr); + //printf(">>>>>>>>>>>>>> finish %s dedicatedloop.%s\n",coin->symbol,addr->ipaddr); if ( addr->vinsfp != 0 ) fclose(addr->vinsfp); if ( addr->voutsfp != 0 ) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 7deaf1675..8d610a5a6 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -168,7 +168,7 @@ uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tabl if ( setind == 0 ) sparsehits++; else if ( setind != x ) - printf("sparseadd index collision setind.%d != x.%d\n",setind,x); + printf("sparseadd index collision setind.%d != x.%d refsize.%d keylen.%d\n",setind,x,refsize,keylen); return(x); } } @@ -177,14 +177,25 @@ uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tabl uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits256 txid,struct iguana_txid *T,uint32_t txidind) { - uint32_t ind; + uint32_t ind,retval; + //char str[65]; printf("sparseaddtx %s txidind.%d bits.%p\n",bits256_str(str,txid),txidind,bits); ind = (txid.ulongs[0] ^ txid.ulongs[1] ^ txid.ulongs[2] ^ txid.ulongs[3]) % tablesize; + if ( (retval= iguana_sparseadd(bits,ind,width,tablesize,txid.bytes,sizeof(txid),0,T,sizeof(*T))) != 0 ) + { + char str[65]; + if ( txidind != 0 && retval != txidind ) + printf("sparse tx collision %s %u vs %u\n",bits256_str(str,txid),retval,txidind); + return(retval); + } return(iguana_sparseadd(bits,ind,width,tablesize,txid.bytes,sizeof(txid),txidind,T,sizeof(*T))); } uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8_t rmd160[20],struct iguana_pkhash *P,uint32_t pkind) { uint32_t ind,key2; uint64_t key0,key1; + //int32_t i; for (i=0; i<20; i++) + // printf("%02x",rmd160[i]); + //char str[65]; printf(" sparseaddpk pkind.%d bits.%p\n",pkind,bits); memcpy(&key0,rmd160,sizeof(key0)); memcpy(&key1,&rmd160[sizeof(key0)],sizeof(key1)); memcpy(&key2,&rmd160[sizeof(key0) + sizeof(key1)],sizeof(key2)); @@ -249,27 +260,31 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, { struct iguana_bundle *bp = 0; int32_t bundlei = -2; char str[65]; *hdrsip = -1; ipbits = 0; + fname[0] = 0; //if ( ipbits == 0 ) // printf("illegal ipbits.%d\n",ipbits), getchar(); if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) == 0 ) { if ( bits256_nonz(prevhash2) == 0 || (bp= iguana_bundlefind(coin,&bp,&bundlei,prevhash2)) == 0 || bundlei >= coin->chain->bundlesize-1 ) + { + printf("iguana_peerfname error finding.(%s) spec.%p bp.%p\n",bits256_str(str,hash2),bp!=0?bp->speculative:0,bp); return(-2); + } else bundlei++; } hash2 = bp->hashes[0], *hdrsip = bp->hdrsi; if ( numblocks == 1 ) { if ( bits256_nonz(bp->hashes[bundlei]) != 0 ) - sprintf(fname,"%s/%s/%d/%s_%u.%d",dirname,coin->symbol,bp->bundleheight,bits256_str(str,bp->hashes[bundlei]),ipbits!=0?ipbits:*hdrsip,bundlei); + sprintf(fname,"%s/%s/%d/%s_%u.%d",dirname,coin->symbol,bp->bundleheight,bits256_str(str,bp->hashes[bundlei]),ipbits>1?ipbits:*hdrsip,bundlei); else { printf("no hash for [%d:%d]\n",bp->hdrsi,bundlei); return(-3); } } - else if ( strcmp("DB",dirname) == 0 ) - sprintf(fname,"%s/%s/%s_%d.%u",dirname,coin->symbol,bits256_str(str,hash2),numblocks,ipbits!=0?ipbits:*hdrsip); + else if ( strncmp("DB",dirname,strlen("DB")) == 0 ) + sprintf(fname,"%s/%s/%s_%d.%u",dirname,coin->symbol,bits256_str(str,hash2),numblocks,ipbits>1?ipbits:*hdrsip); else sprintf(fname,"%s/%s.%u",dirname,bits256_str(str,hash2),bp->bundleheight); OS_compatible_path(fname); return(bundlei); @@ -457,7 +472,7 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee V.spendlen = iguana_scriptgen(coin,&V.M,&V.N,V.coinaddr,V.spendscript,asmstr,u->rmd160,type,(const struct vin_info *)&V,vout); if ( (V.spendlen != scriptlen || memcmp(V.spendscript,script,scriptlen) != 0) && addr != 0 && addr->voutsfp != 0 ) { - u->ipbits = (uint32_t)addr->ipbits; + u->fileid = (uint32_t)addr->addrind; u->scriptpos = (uint32_t)ftell(addr->voutsfp); if ( fwrite(script,1,scriptlen,addr->voutsfp) != scriptlen ) printf("error writing scriptlen.%d\n",scriptlen); @@ -466,7 +481,7 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee else { u->scriptpos = 0; - u->ipbits = 0; + u->fileid = 0; } } else u->scriptpos = 0; u->txidind = ramchain->H.txidind; @@ -474,7 +489,7 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee return(unspentind); } -uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint64_t value,uint16_t hdrsi,uint8_t *rmd160,uint16_t vout,uint8_t type,uint32_t ipbits,uint32_t fpos,int32_t scriptlen) +uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint64_t value,uint16_t hdrsi,uint8_t *rmd160,uint16_t vout,uint8_t type,uint16_t fileid,uint32_t fpos,int32_t scriptlen) { uint32_t unspentind; struct iguana_unspent *u; struct iguana_kvitem *ptr; int32_t pkind;//,checklen,metalen; uint8_t _script[IGUANA_MAXSCRIPTSIZE],*checkscript; unspentind = ramchain->H.unspentind++; @@ -498,9 +513,9 @@ uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint6 printf("script mismatch len.%d vs %d or cmp error.%d\n",scriptlen,checklen,(checkscript != 0 && script != 0) ? memcmp(checkscript,script,scriptlen):0); } //else printf("RO spendscript match.%d\n",scriptlen); }*/ - if ( u->ipbits != ipbits || u->scriptpos != fpos || u->scriptlen != scriptlen || u->value != value || u->pkind != pkind || u->value != value || u->txidind != ramchain->H.txidind || (pkind != 0 && u->prevunspentind != A[pkind].lastind) || u->vout != vout || u->hdrsi != hdrsi ) + if ( u->fileid != fileid || u->scriptpos != fpos || u->scriptlen != scriptlen || u->value != value || u->pkind != pkind || u->value != value || u->txidind != ramchain->H.txidind || (pkind != 0 && u->prevunspentind != A[pkind].lastunspentind) || u->vout != vout || u->hdrsi != hdrsi ) { - printf("iguana_ramchain_addunspent: (%d %d %d) vs (%d %d %d) mismatched values.(%d %.8f %d %d %d %d) vs (%d %.8f %d %d %d %d)\n",u->ipbits,u->scriptpos,u->scriptlen,ipbits,fpos,scriptlen,u->pkind,dstr(u->value),u->txidind,u->prevunspentind,u->vout,u->hdrsi,pkind,dstr(value),ramchain->H.txidind,A[pkind].lastind,vout,hdrsi); + printf("iguana_ramchain_addunspent: (%d %d %d) vs (%d %d %d) mismatched values.(%d %.8f %d %d %d %d) vs (%d %.8f %d %d %d %d)\n",u->fileid,u->scriptpos,u->scriptlen,fileid,fpos,scriptlen,u->pkind,dstr(u->value),u->txidind,u->prevunspentind,u->vout,u->hdrsi,pkind,dstr(value),ramchain->H.txidind,A[pkind].lastunspentind,vout,hdrsi); exit(-1); return(0); } @@ -513,15 +528,15 @@ uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint6 //else pubkeyoffset = 0; u->vout = vout, u->hdrsi = hdrsi; u->txidind = ramchain->H.txidind, u->pkind = pkind; - u->prevunspentind = A[pkind].lastind; - u->ipbits = ipbits; + u->prevunspentind = A[pkind].lastunspentind; + u->fileid = fileid; u->scriptlen = scriptlen; u->scriptpos = fpos; u->type = type; } //printf("%p A[%d] last <- U%d\n",&A[pkind],pkind,unspentind); A[pkind].total += value; - A[pkind].lastind = unspentind; + A[pkind].lastunspentind = unspentind; return(unspentind); } @@ -575,7 +590,7 @@ int32_t iguana_ramchain_txid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 *txi return(-2); } -uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint32_t sequence,int32_t hdrsi,uint32_t ipbits,uint32_t scriptpos,int32_t vinscriptlen) +uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint32_t sequence,int32_t hdrsi,uint16_t fileid,uint32_t scriptpos,int32_t vinscriptlen) { struct iguana_spend *s; struct iguana_kvitem *ptr = 0; bits256 txid; uint32_t spendind,unspentind,txidind=0,pkind,external=0; uint64_t value = 0; @@ -653,7 +668,7 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 s->sequenceid = sequence; s->external = external, s->spendtxidind = txidind, s->prevout = prev_vout; - s->ipbits = ipbits; + s->fileid = fileid; s->scriptpos = scriptpos; s->scriptlen = vinscriptlen; /*static uint64_t good,bad; @@ -720,7 +735,7 @@ uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,struct iguana_peer s->spendind = spendind; if ( (s->vinscriptlen= vinscriptlen) > 0 && vinscript != 0 && addr != 0 && addr->vinsfp != 0 && vinscriptlen < IGUANA_MAXSCRIPTSIZE) { - s->ipbits = (uint32_t)addr->ipbits; + s->fileid = (uint32_t)addr->addrind; s->scriptpos = (uint32_t)ftell(addr->vinsfp); if ( fwrite(vinscript,1,vinscriptlen,addr->vinsfp) != vinscriptlen ) printf("error writing vinscriptlen.%d\n",vinscriptlen); @@ -801,6 +816,46 @@ void *iguana_ramchain_offset(void *dest,uint8_t *lhash,FILE *fp,uint64_t fpos,vo return((void *)(long)((long)destptr + fpos)); } +void iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + struct iguana_pkhash *P,p; struct iguana_unspent *U,u; struct iguana_txid *T,txid; uint32_t i,numpkinds,numtxids,numunspents,tlen,plen,nonz=0; uint8_t *PKbits,*TXbits,*ptr; + if ( ramchain->H.data != 0 ) + { + ptr = ramchain->fileptr; + for (i=0; ifilesize; i++) + if ( ptr[i] != 0 ) + nonz++; + //printf("nonz.%d of %d\n",nonz,(int32_t)ramchain->filesize); + return; + U = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Uoffset); + T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); + TXbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->TXoffset); + PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset); + numpkinds = ramchain->H.data->numpkinds; + numunspents = ramchain->H.data->numunspents; + numtxids = ramchain->H.data->numtxids; + tlen = ramchain->H.data->numtxsparse * ramchain->H.data->txsparsebits; + plen = ramchain->H.data->numpksparse * ramchain->H.data->pksparsebits; + if ( 0 ) + { + for (i=1; itotalsize); + printf("NEED %ld realloc for totalsize %ld\n",(long)offset,(long)mem->totalsize); getchar(); exit(-1); iguana_mempurge(mem); @@ -1216,7 +1271,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * { if ( memcmp(&ramchain->A[k],&ramchain->creditsA[k],sizeof(ramchain->A[k])) != 0 ) { - printf("k.%d balance.(%.8f vs %.8f) lastU.(%d %d)\n",k,dstr(ramchain->A[k].total),dstr(ramchain->creditsA[k].total),ramchain->A[k].lastind,ramchain->creditsA[k].lastind); + printf("k.%d balance.(%.8f vs %.8f) lastU.(%d %d)\n",k,dstr(ramchain->A[k].total),dstr(ramchain->creditsA[k].total),ramchain->A[k].lastunspentind,ramchain->creditsA[k].lastunspentind); //return(-14); } //if ( memcmp(&ramchain->P2[k],&ramchain->roP2[k],sizeof(ramchain->P2[k])) != 0 ) @@ -1229,7 +1284,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * return(0); } -int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag) +int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t deleteflag) { struct iguana_kvitem *item,*tmp; if ( ramchain->H.ROflag != 0 && ramchain->hashmem == 0 ) @@ -1282,14 +1337,15 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag ramchain->numXspends = 0; ramchain->Xspendinds = 0; } + iguana_purgevolatiles(coin,ramchain); if ( deleteflag != 0 ) memset(ramchain,0,sizeof(*ramchain)); return(0); } -void iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) +int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) { - RAMCHAIN_DECLARE; char fname[1024]; //long filesize; + RAMCHAIN_DECLARE; int32_t err=0; if ( ramchain->expanded != 0 ) { _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); @@ -1301,75 +1357,52 @@ void iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ram ramchain->A = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_account) * ramchain->H.data->numpkinds,1) : mycalloc('p',ramchain->H.data->numpkinds,sizeof(struct iguana_account)); ramchain->Uextras = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents,1) : mycalloc('p',ramchain->H.data->numunspents,sizeof(*ramchain->Uextras)); } - else - { - if ( 1 && extraflag == 2 ) - { - sprintf(fname,"accounts/%s/debits.%d",coin->symbol,ramchain->H.data->height); - //ramchain->A = OS_filestr(&filesize,fname); - //if ( filesize != sizeof(*ramchain->A)*ramchain->H.data->numpkinds ) - // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->A)*ramchain->H.data->numpkinds); - sprintf(fname,"accounts/%s/lastspends.%d",coin->symbol,ramchain->H.data->height); - //ramchain->Uextras = OS_filestr(&filesize,fname); - //if ( filesize != sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds ) - // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds); - //if ( ramchain->A == 0 ) - ramchain->A = myaligned_alloc(sizeof(*ramchain->A) * ramchain->H.data->numpkinds); - //if ( ramchain->Uextras == 0 ) - ramchain->Uextras = myaligned_alloc(sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); - } - else - { - //if ( ramchain->A == 0 ) - ramchain->A = myaligned_alloc(sizeof(*ramchain->A) * ramchain->H.data->numpkinds); - //if ( ramchain->Uextras == 0 ) - ramchain->Uextras = myaligned_alloc(sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); - } - //printf("ALLOC RAMCHAIN A.%p Uextras.%p | extraflag.%d hashmem.%p\n",ramchain->A,ramchain->Uextras,extraflag,ramchain->hashmem); - } - //printf("hashmem.%p A allocated.%p numpkinds.%d %ld\n",hashmem,ramchain->A,ramchain->H.data->numpkinds,sizeof(struct iguana_account)*ramchain->H.data->numpkinds); - //ramchain->P2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_pkextra) * ramchain->H.data->numpkinds,1) : mycalloc('2',ramchain->H.data->numpkinds,sizeof(struct iguana_pkextra)); - ///ramchain->U2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_Uextra) * ramchain->H.data->numunspents,1) : mycalloc('3',ramchain->H.data->numunspents,sizeof(struct iguana_Uextra)); - //printf("iguana_ramchain_extras A.%p:%p U2.%p:%p P2.%p:%p\n",ramchain->A,ramchain->roA,ramchain->U2,ramchain->roU2,ramchain->P2,ramchain->roP2); - //memcpy(ramchain->U2,ramchain->roU2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); - //memcpy(ramchain->P2,ramchain->roP2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); + else err = iguana_mapvolatiles(coin,ramchain); } + return(err); } int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) { - int32_t hdrsi; bits256 sha256; char fname[1024],dirname[128]; void *ptr; long filesize; static bits256 zero; - sprintf(dirname,"DB/%s/spends",coin->symbol); - if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) + int32_t iter; bits256 sha256; char str[65],fname[1024]; void *ptr; long filesize; + for (iter=0; iter<2; iter++) { - if ( (ptr= OS_mapfile(fname,&filesize,0)) != 0 ) + sprintf(fname,"DB/%s%s/spends/%s.%d",iter==0?"ro/":"",coin->symbol,bits256_str(str,bp->hashes[0]),bp->bundleheight); + //sprintf(dirname,"DB/%s%s/spends",iter==0?"ro/":"",coin->symbol); + //if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) { - ramchain->Xspendinds = (void *)((long)ptr + sizeof(sha256)); - vcalc_sha256(0,sha256.bytes,(void *)ramchain->Xspendinds,(int32_t)(filesize - sizeof(sha256))); - if ( memcmp(sha256.bytes,ptr,sizeof(sha256)) == 0 ) - { - ramchain->Xspendptr = ptr; - ramchain->numXspends = (int32_t)((filesize - sizeof(sha256)) / sizeof(*ramchain->Xspendinds)); - //int32_t i; for (i=0; inumXspends; i++) - // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); - //printf("filesize %ld Xspendptr.%p %p num.%d\n",ftell(fp),ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); - //printf("mapped utxo vector[%d] from (%s)\n",ramchain->numXspends,fname); - } - else + if ( (ptr= OS_mapfile(fname,&filesize,0)) != 0 ) { - char str[65]; printf("hash cmp error.%d vs (%s)\n",memcmp(sha256.bytes,ptr,sizeof(sha256)),bits256_str(str,sha256)); - munmap(ptr,filesize); - ramchain->Xspendinds = 0; - } - } //else printf("no Xspendfile\n"); - } else printf("couldnt open.(%s)\n",fname); + ramchain->Xspendinds = (void *)((long)ptr + sizeof(sha256)); + vcalc_sha256(0,sha256.bytes,(void *)ramchain->Xspendinds,(int32_t)(filesize - sizeof(sha256))); + if ( memcmp(sha256.bytes,ptr,sizeof(sha256)) == 0 ) + { + bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); + ramchain->Xspendptr = ptr; + ramchain->numXspends = (int32_t)((filesize - sizeof(sha256)) / sizeof(*ramchain->Xspendinds)); + ramchain->from_roX = (iter == 0); + return(ramchain->numXspends); + //int32_t i; for (i=0; inumXspends; i++) + // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); + //printf("filesize %ld Xspendptr.%p %p num.%d\n",ftell(fp),ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); + //printf("mapped utxo vector[%d] from (%s)\n",ramchain->numXspends,fname); + } + else + { + char str[65]; printf("hash cmp error.%d vs (%s)\n",memcmp(sha256.bytes,ptr,sizeof(sha256)),bits256_str(str,sha256)); + munmap(ptr,filesize); + ramchain->Xspendinds = 0; + } + } //else printf("no Xspendfile.(%s)\n",fname); + } + } return(ramchain->numXspends); } struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded) { - RAMCHAIN_DECLARE; int32_t valid,i,checki,hdrsi; - char str[65],str2[65]; long filesize; void *ptr; struct iguana_block *block; + RAMCHAIN_DECLARE; int32_t valid,iter,i,checki,hdrsi; + char str[65],str2[65],*dirstr; long filesize; void *ptr; struct iguana_block *block; /*if ( ramchain->expanded != 0 && (ramchain->sigsfileptr == 0 || ramchain->sigsfilesize == 0) ) { sprintf(sigsfname,"sigs/%s/%s",coin->symbol,bits256_str(str,hash2)); @@ -1381,18 +1414,26 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname }*/ if ( ramchain->fileptr == 0 || ramchain->filesize <= 0 ) { - if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?"DB":GLOBALTMPDIR,fname,ipbits,hash2,prevhash2,numblocks)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + for (iter=0; iter<2; iter++) { - printf("iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d %s\n",fname,hdrsi,bundlei,bits256_str(str,hash2)); - return(0); + dirstr = (iter == 0) ? "DB/ro" : "DB"; + if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?dirstr:GLOBALTMPDIR,fname,ipbits,hash2,prevhash2,numblocks)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + { + printf("iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d %s\n",fname,hdrsi,bundlei,bits256_str(str,hash2)); + continue; + } + memset(ramchain,0,sizeof(*ramchain)); + if ( (ptr= OS_mapfile(fname,&filesize,0)) == 0 ) + continue; + ramchain->from_ro = (iter == 0); + ramchain->fileptr = ptr; + ramchain->filesize = (long)filesize; + if ( (ramchain->hashmem= hashmem) != 0 ) + iguana_memreset(hashmem); + break; } - memset(ramchain,0,sizeof(*ramchain)); - if ( (ptr= OS_mapfile(fname,&filesize,0)) == 0 ) + if ( ramchain->fileptr == 0 ) return(0); - ramchain->fileptr = ptr; - ramchain->filesize = (long)filesize; - if ( (ramchain->hashmem= hashmem) != 0 ) - iguana_memreset(hashmem); } if ( ramchain->fileptr != 0 && ramchain->filesize > 0 ) { @@ -1401,7 +1442,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname ramchain->H.ROflag = 1; ramchain->expanded = expanded; ramchain->numblocks = (bp == 0) ? 1 : bp->n; - //printf("ptr.%p %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); + //printf("ptr.%p exp.%d extra.%d %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,expanded,allocextras,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); if ( 0 && bp != 0 ) { /*blocksRO = (struct iguana_blockRO *)ramchain->H.data; @@ -1451,7 +1492,13 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname else if ( ramchain->expanded != 0 ) { if ( allocextras > 0 ) - iguana_ramchain_extras(coin,ramchain,ramchain->hashmem,allocextras); + { + if ( iguana_ramchain_extras(coin,ramchain,ramchain->hashmem,allocextras) == 0 && bp != 0 ) + { + bp->balancefinish = (uint32_t)time(NULL); + //printf("found balances for %d\n",bp->hdrsi); + } //else printf("error with extras\n"); + } } if ( B != 0 && bp != 0 ) { @@ -1578,7 +1625,7 @@ int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B, int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) { RAMCHAIN_DECLARE; RAMCHAIN_DESTDECLARE; - int32_t j,hdrsi,prevout,scriptlen; uint32_t scriptpos,ipbits,sequenceid,destspendind=0,desttxidind=0; + int32_t j,hdrsi,prevout,scriptlen; uint32_t scriptpos,sequenceid,destspendind=0,desttxidind=0; uint16_t fileid; bits256 prevhash; uint64_t value; uint8_t type; struct iguana_unspent *u; struct iguana_txid *tx; struct iguana_ramchaindata *rdata; uint8_t *rmd160; //if ( dest != 0 ) @@ -1590,7 +1637,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain } if ( dest != 0 ) _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - //else fprintf(stderr,"iterate %d/%d dest.%p ramchain.%p rdata.%p\n",bp->bundleheight,bp->n,dest,ramchain,rdata); + //fprintf(stderr,"iterate %d/%d dest.%p ramchain.%p rdata.%p\n",bp->bundleheight,bp->n,dest,ramchain,rdata); _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); ramchain->H.ROflag = 1; ramchain->H.unspentind = ramchain->H.spendind = ramchain->pkind = rdata->firsti; @@ -1604,21 +1651,21 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) { if ( 0 && ramchain->expanded == 0 && dest != 0 ) - printf("ITER TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); + printf("ITER [%d] TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",ramchain->H.data->height,ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); tx = &T[ramchain->H.txidind]; if ( iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp) == 0 ) return(-1); if ( dest != 0 ) { - char str[65]; + //char str[65]; if ( 0 && ramchain->expanded == 0 ) - printf("add hdrsi.%d dest.%p txidind.%d %s\n",dest->H.hdrsi,ramchain,dest->H.txidind,bits256_str(str,tx->txid)); + printf("ITER [%d] TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",ramchain->H.data->height,ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); if ( iguana_ramchain_addtxid(coin,RAMCHAIN_DESTARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp) == 0 ) return(-2); } for (j=0; jnumvouts; j++) { - ipbits = 0; + fileid = 0; scriptpos = 0; scriptlen = 0; if ( ramchain->H.unspentind < rdata->numunspents ) @@ -1629,7 +1676,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain value = u->value; hdrsi = u->hdrsi; type = u->type; - ipbits = u->ipbits; + fileid = u->fileid; scriptpos = u->scriptpos; scriptlen = u->scriptlen; if ( u->pkind < rdata->numpkinds ) @@ -1641,7 +1688,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain scriptdata = iguana_ramchain_scriptdecode(&metalen,&scriptlen,Kspace,type,_script,u->scriptoffset,P[u->pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[u->pkind].pubkeyoffset : 0); }*/ //fprintf(stderr,"iter add %p[%d] type.%d\n",scriptdata,scriptlen,type); - if ( iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,value,hdrsi,rmd160,j,type,ipbits,scriptpos,scriptlen) == 0 ) + if ( iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,value,hdrsi,rmd160,j,type,fileid,scriptpos,scriptlen) == 0 ) return(-3); } } @@ -1651,7 +1698,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain value = U[ramchain->H.unspentind].value; rmd160 = U[ramchain->H.unspentind].rmd160; type = U[ramchain->H.unspentind].type & 0xf; - ipbits = U[ramchain->H.unspentind].ipbits; + fileid = U[ramchain->H.unspentind].fileid; scriptpos = U[ramchain->H.unspentind].scriptpos; scriptlen = U[ramchain->H.unspentind].scriptlen; /*if ( U[ramchain->H.unspentind].scriptoffset != 0 ) @@ -1674,7 +1721,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain if ( dest != 0 ) { //fprintf(stderr,"dest add %p[%d] type.%d offset.%d vs %d\n",scriptdata,scriptlen,type,dest->H.scriptoffset,dest->H.data->scriptspace); - if ( iguana_ramchain_addunspent(coin,RAMCHAIN_DESTARG,value,hdrsi,rmd160,j,type,ipbits,scriptpos,scriptlen) == 0 ) + if ( iguana_ramchain_addunspent(coin,RAMCHAIN_DESTARG,value,hdrsi,rmd160,j,type,fileid,scriptpos,scriptlen) == 0 ) return(-5); } //else printf("addunspent20 done\n"); } else return(-6); @@ -1697,19 +1744,19 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain tx = &T[ramchain->H.txidind]; for (j=0; jnumvins; j++) { - ipbits = 0; + fileid = 0; scriptpos = 0; scriptlen = 0; if ( ramchain->expanded != 0 ) { - ipbits = Sx[ramchain->H.spendind].ipbits; + fileid = Sx[ramchain->H.spendind].fileid; scriptpos = Sx[ramchain->H.spendind].scriptpos; scriptlen = Sx[ramchain->H.spendind].scriptlen; //scriptlen = iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[ramchain->H.data->scriptspace],Kspace,&Sx[ramchain->H.spendind]); //scriptdata = _script; prevout = iguana_ramchain_txid(coin,RAMCHAIN_ARG,&prevhash,&Sx[ramchain->H.spendind]); //fprintf(stderr,"from expanded iter\n"); - if ( iguana_ramchain_addspend(coin,RAMCHAIN_ARG,prevhash,prevout,Sx[ramchain->H.spendind].sequenceid,bp->hdrsi,ipbits,scriptpos,scriptlen) == 0 ) + if ( iguana_ramchain_addspend(coin,RAMCHAIN_ARG,prevhash,prevout,Sx[ramchain->H.spendind].sequenceid,bp->hdrsi,fileid,scriptpos,scriptlen) == 0 ) { char str[65]; printf("hdrsi.%d txidind.%d spendind.%d spendtxid.%x %d vin.%d %s vout.%d\n",bp->bundleheight,ramchain->H.txidind,ramchain->H.spendind,Sx[ramchain->H.spendind].spendtxidind,Sx[ramchain->H.spendind].spendtxidind&0xfffffff,j,bits256_str(str,prevhash),prevout); @@ -1726,7 +1773,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain sequenceid = S[ramchain->H.spendind].sequenceid; prevhash = S[ramchain->H.spendind].prevhash2; prevout = S[ramchain->H.spendind].prevout; - ipbits = S[ramchain->H.spendind].ipbits; + fileid = S[ramchain->H.spendind].fileid; scriptpos = S[ramchain->H.spendind].scriptpos; scriptlen = S[ramchain->H.spendind].vinscriptlen; /*if ( S[ramchain->H.spendind].scriptoffset != 0 ) @@ -1745,7 +1792,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain } if ( dest != 0 ) { - if ( iguana_ramchain_addspend(coin,RAMCHAIN_DESTARG,prevhash,prevout,sequenceid,bp->hdrsi,ipbits,scriptpos,scriptlen) == 0 ) + if ( iguana_ramchain_addspend(coin,RAMCHAIN_DESTARG,prevhash,prevout,sequenceid,bp->hdrsi,fileid,scriptpos,scriptlen) == 0 ) return(-9); //printf("from dest iter scriptspace.%d\n",dest->H.stacksize); } @@ -1915,7 +1962,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru origtxdata->datalen = (int32_t)ramchain->H.data->allocsize; ramchain->H.ROflag = 0; flag = 1; - if ( 1 ) + if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) { if ( addr->dirty[0] != 0 && addr->voutsfp != 0 ) fflush(addr->voutsfp); @@ -1935,7 +1982,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru { ptr = mapchain->fileptr; fsize = mapchain->filesize; mapchain->fileptr = 0, mapchain->filesize = 0; - iguana_ramchain_free(mapchain,1); + iguana_ramchain_free(coin,mapchain,1); memset(&R,0,sizeof(R)); R.H.data = (void *)(long)((long)ptr + fpos), R.filesize = fsize; iguana_ramchain_link(&R,block->RO.hash2,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); @@ -1959,7 +2006,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru bp->numspends += ramchain->H.data->numspends; bp->rawscriptspace += ramchain->H.data->scriptspace; } - iguana_ramchain_free(&R,1); + iguana_ramchain_free(coin,&R,1); } else { @@ -1977,7 +2024,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru block->fpos = -1, block->fpipbits = block->RO.recvlen = 0; //fprintf(stderr,"finished with hdrsi.%d ht.%d scripts.%u:%u\n",bp->hdrsi,bp->bundleheight,ramchain->H.scriptoffset,ramchain->H.data->scriptspace); ramchain->H.ROflag = 0; - iguana_ramchain_free(ramchain,0); + iguana_ramchain_free(coin,ramchain,0); return(fpos); } @@ -2050,28 +2097,37 @@ int32_t iguana_oldbundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **p return(num); } +void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei) +{ + int32_t checki,hdrsi; void *ptr = 0; static bits256 zero; + *filesizep = 0; + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + { + printf("B iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); + return(0); + } + if ( (ptr= OS_mapfile(fname,filesizep,0)) == 0 ) + { + //printf("error mapping.(%s) bundlei.%d\n",fname,bundlei); + return(0); + } + return(ptr); +} + int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs,long *filesizes,struct iguana_bundle *bp,int32_t starti,int32_t endi) { - int32_t bundlei,checki,hdrsi,num = 0; char fname[1024]; static bits256 zero; + int32_t bundlei,num = 0; char fname[1024]; for (bundlei=starti; bundlei<=endi; bundlei++) { - if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) - { - printf("B iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); - return(0); - } - if ( (ptrs[num]= OS_mapfile(fname,&filesizes[num],0)) == 0 ) - { - printf("error mapping.(%s) bundlei.%d\n",fname,bundlei); - return(0); - } + if ( (ptrs[num]= iguana_bundlefile(coin,fname,&filesizes[num],bp,bundlei)) != 0 ) + num++; + else return(bp == coin->current ? num : 0); //printf("%s mapped ptrs[%d] filesize.%ld bundlei.%d ipbits.%x fpos.%d\n",fname,num,(long)filesizes[num],bundlei,fpipbits,bp->fpos[bundlei]); - num++; } return(num); } -void iguana_bundlemapfree(struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t *ipbits,void **ptrs,long *filesizes,int32_t num,struct iguana_ramchain *R,int32_t starti,int32_t endi) +void iguana_bundlemapfree(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t *ipbits,void **ptrs,long *filesizes,int32_t num,struct iguana_ramchain *R,int32_t starti,int32_t endi) { int32_t j,n = (endi - starti + 1); for (j=0; j (long)srcoffset ) printf("smashed stack? dest.%ld vs src %ld offset.%u stacksize.%u space.%u\n",(long)destoffset,(long)srcoffset,(uint32_t)ramchain->H.scriptoffset,(uint32_t)ramchain->H.stacksize,(uint32_t)ramchain->H.scriptoffset); } - printf("%d SAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d gap.%ld RO.%d\n",bp->bundleheight,(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize,(long)destoffset - (long)srcoffset,ramchain->H.ROflag); + //printf("%d SAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d gap.%ld RO.%d\n",bp->bundleheight,(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize,(long)destoffset - (long)srcoffset,ramchain->H.ROflag); scriptspace = ramchain->H.data->scriptspace; scriptoffset = ramchain->H.scriptoffset; stacksize = ramchain->H.stacksize; @@ -2177,8 +2233,8 @@ int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,stru } int32_t i; for (i=0; iH.data->lhashes[i].uints[0]); - printf("%llx ht.%d bundlehashes\n",(long long)mapchain->H.data->sha256.txid,mapchain->height); - iguana_ramchain_free(mapchain,cmpflag); + printf("%llx ht.%d bundlehashes.%s\n",(long long)mapchain->H.data->sha256.txid,mapchain->height,coin->symbol); + iguana_ramchain_free(coin,mapchain,cmpflag); } iguana_mempurge(hashmem); } @@ -2242,88 +2298,129 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana return(mapchain); } +int64_t iguana_ramchainopen(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2) +{ + RAMCHAIN_DECLARE; int32_t i,numblocks = coin->chain->bundlesize; uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int64_t hashsize,allocsize; + B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; + mem->alignflag = sizeof(uint32_t); + hashmem->alignflag = sizeof(uint32_t); + scriptspace = numexternaltxids = numtxids = coin->chain->bundlesize * 2; + numunspents = numspends = numpkinds = numtxids * 2; + for (i=0; ibundlescount; i++) + if ( (bp= coin->bundles[i]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) + { + if ( rdata->numtxids > numtxids ) + numtxids = rdata->numtxids; + if ( rdata->numpkinds > numpkinds ) + numpkinds = rdata->numpkinds; + if ( rdata->numspends > numspends ) + numspends = rdata->numspends; + if ( rdata->numunspents > numunspents ) + numunspents = rdata->numunspents; + if ( rdata->numexternaltxids > numexternaltxids ) + numexternaltxids = rdata->numexternaltxids; + if ( rdata->scriptspace > scriptspace ) + scriptspace = rdata->scriptspace; + } + numtxids *= 1.5; numexternaltxids *= 1.5, scriptspace *= 1.5; + numunspents *= 1.5, numspends *= 1.5, numpkinds *= 1.5; + if ( mem->ptr == 0 ) + { + allocsize = _iguana_rdata_action(0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks); + iguana_meminit(mem,coin->symbol,0,allocsize + 65536*3,0); + } + if ( hashmem->ptr == 0 ) + { + hashsize = iguana_hashmemsize(numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace); + iguana_meminit(hashmem,coin->symbol,0,hashsize + 65536*3,0); + } + if ( iguana_ramchain_init(ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,1,numblocks) > 0 ) + { + iguana_ramchain_link(ramchain,hash2,hash2,bundleheight/coin->chain->bundlesize,bundleheight,0,0,1,0); + ramchain->expanded = 1; + ramchain->H.scriptoffset = 1; + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); + iguana_ramchain_extras(coin,ramchain,hashmem,0); + } + return(ramchain->H.data->allocsize); +} + +int32_t iguana_mapchaininit(struct iguana_info *coin,struct iguana_ramchain *mapchain,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block,void *ptr,long filesize) +{ + int32_t firsti = 1; RAMCHAIN_DECLARE; + memset(mapchain,0,sizeof(*mapchain)); + mapchain->fileptr = ptr; + mapchain->filesize = filesize; + mapchain->H.data = (void *)(long)((long)ptr + block->fpos); + mapchain->H.ROflag = 1; + if ( block->fpos > filesize ) + { + printf("fpos error %ld > %ld mapping hdrsi.%d bundlei.%d\n",block->fpos,filesize,bp->hdrsi,bundlei); + return(-1); + } + _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); + if ( block->fpos+mapchain->H.data->allocsize > filesize || iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace) != mapchain->H.data->allocsize ) + { + printf("iguana_mapchaininit.%d ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d soff.%d\n",bp->bundleheight,block->fpipbits,(long)iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace),(long)mapchain->H.data->allocsize,(long)filesize,(long)block->fpos,bundlei,mapchain->expanded,mapchain->H.data->scriptspace); + return(-1); + } + else if ( memcmp(bp->hashes[bundlei].bytes,mapchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) + { + char str[65],str2[65]; printf("iguana_bundlesaveHT.[%d:%d] hash2 mismatch %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,mapchain->H.data->firsthash2)); + return(-1); + } + iguana_ramchain_link(mapchain,bp->hashes[bundlei],bp->hashes[bundlei],bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + if ( bp->blocks[bundlei]->RO.txn_count == 0 ) + bp->blocks[bundlei]->RO.txn_count = mapchain->H.data->numtxids - 1; + return(0); +} + // helper threads: NUM_HELPERS int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime) // helper thread { static int depth; static bits256 zero; RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; - void **ptrs,*ptr; long *filesizes,filesize; uint32_t *ipbits; char fname[1024]; + void **ptrs; long *filesizes; uint32_t *ipbits; char fname[1024]; struct iguana_ramchain *R,*mapchain,*dest,newchain; uint32_t fpipbits; int32_t i,starti,endi,bp_n,numtxids,valid,sigspace,pubkeyspace,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_block *block; long fpos; struct OS_memspace HASHMEM; int32_t err,j,num,hdrsi,bundlei,firsti= 1,retval = -1; memset(&HASHMEM,0,sizeof(HASHMEM)); starti = 0, endi = bp->n - 1; - bp_n = (endi - starti + 1); B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; R = mycalloc('s',bp->n,sizeof(*R)); ptrs = mycalloc('w',bp->n,sizeof(*ptrs)); ipbits = mycalloc('w',bp->n,sizeof(*ipbits)); filesizes = mycalloc('f',bp->n,sizeof(*filesizes)); - if ( (num= iguana_bundlefiles(coin,ipbits,ptrs,filesizes,bp,starti,endi)) == 0 ) + if ( (num= iguana_bundlefiles(coin,ipbits,ptrs,filesizes,bp,starti,endi)) != bp->n ) { - iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); printf("iguana_bundlesaveHT: no bundlefiles error\n"); return(-1); } + if ( bp == coin->current ) + endi = num-1; + bp_n = (endi - starti + 1); scriptspace = 1; sigspace = pubkeyspace = 0; - for (bundlei=starti,numtxids=numunspents=numspends=scriptspace=0; bundlei<=endi; bundlei++) + for (bundlei=starti,numtxids=numunspents=scriptspace=numspends=0; bundlei<=endi; bundlei++) { - if ( (block= bp->blocks[bundlei]) != 0 ) - fpipbits = block->fpipbits, fpos = block->fpos; - else fpipbits = fpos = 0; - mapchain = &R[bundlei]; - /*for (j=0; jfileptr = ptr; - mapchain->filesize = filesize; - mapchain->H.data = (void *)(long)((long)ptr + fpos); - mapchain->H.ROflag = 1; - if ( fpos > filesize ) - { - iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,starti,endi); - printf("fpos error %ld > %ld mapping hdrsi.%d bundlei.%d\n",fpos,filesize,bp->hdrsi,bundlei); - break; - } - if ( fpos+mapchain->H.data->allocsize > filesize || iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace) != mapchain->H.data->allocsize ) + if ( (block= bp->blocks[bundlei]) == 0 || bits256_nonz(block->RO.hash2) == 0 || block != iguana_blockfind(coin,block->RO.hash2) || memcmp(block->RO.hash2.bytes,bp->hashes[bundlei].bytes,sizeof(bits256)) != 0 ) { - printf("iguana_bundlesaveHT.%d ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d soff.%d\n",bp->bundleheight,fpipbits,(long)iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace),(long)mapchain->H.data->allocsize,(long)filesize,(long)fpos,bundlei,mapchain->expanded,mapchain->H.data->scriptspace); - //getchar(); + printf("block.%p error vs %p\n",block,iguana_blockfind(coin,block->RO.hash2)); break; } - else if ( memcmp(bp->hashes[bundlei].bytes,mapchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) - { - char str[65],str2[65]; printf("iguana_bundlesaveHT.[%d:%d] hash2 mismatch %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,mapchain->H.data->firsthash2)); + fpipbits = block->fpipbits, fpos = block->fpos; + mapchain = &R[bundlei]; + if ( iguana_mapchaininit(coin,mapchain,bp,bundlei,block,ptrs[bundlei],filesizes[bundlei]) < 0 ) break; - } - iguana_ramchain_link(mapchain,bp->hashes[bundlei],bp->hashes[bundlei],bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); - _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); numtxids += (mapchain->H.data->numtxids - 1); numunspents += (mapchain->H.data->numunspents - 1); numspends += (mapchain->H.data->numspends - 1); scriptspace += 1;//iguana_ramchain_scriptspace(coin,&sigsize,&pubkeysize,mapchain); //sigspace += sigsize; //pubkeyspace += pubkeysize; - if ( (block= bp->blocks[bundlei]) == 0 || bits256_nonz(block->RO.hash2) == 0 || block != iguana_blockfind(coin,block->RO.hash2) || memcmp(block->RO.hash2.bytes,bp->hashes[bundlei].bytes,sizeof(bits256)) != 0 ) - { - printf("block.%p error vs %p\n",block,iguana_blockfind(coin,block->RO.hash2)); - break; - } //printf("%x ",(uint32_t)block->RO.hash2.ulongs[3]); - if ( bp->blocks[bundlei]->RO.txn_count == 0 ) - bp->blocks[bundlei]->RO.txn_count = mapchain->H.data->numtxids - 1; + // _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); //printf("(%d %d).%d ",mapchain->H.data->numtxids,bp->blocks[bundlei]->RO.txn_count,numtxids); //printf("%d ",numtxids); } @@ -2339,7 +2436,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str block->RO.recvlen = 0; bp->issued[bundlei] = 0; } - iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); printf("error mapping hdrsi.%d bundlei.%d\n",bp->hdrsi,bundlei); return(-1); } @@ -2353,7 +2450,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace+sigspace,bp->bundleheight+starti,bp_n) < 0 ) { printf("error iguana_ramchain_alloc for bundleheight.%d\n",bp->bundleheight); - iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); return(-1); } iguana_ramchain_link(dest,bp->hashes[starti],bp->hashes[endi],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,0); @@ -2374,10 +2471,10 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str block->fpipbits = 0; bp->issued[i] = 0; block->issued = 0; - iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); return(-1); } - //destB[i] = block->RO; + destB[i] = block->RO; } else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,iguana_blockfind(coin,bp->hashes[i])); } dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; @@ -2423,12 +2520,12 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str //char str[65]; printf("d.%d ht.%d %s saved lag.%d elapsed.%ld\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); retval = 0; } else bp->generrs++; - iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); if ( retval == 0 )//|| bp->generrs > 3 ) { char dirname[1024]; //printf("delete %d files hdrs.%d retval.%d\n",num,bp->hdrsi,retval); - if ( bp_n == bp->n && bp->n == coin->chain->bundlesize ) + if ( bp_n == bp->n && bp->n == coin->chain->bundlesize && bp->hdrsi < coin->bundlescount-3 ) { for (j=starti; j<=endi; j++) { @@ -2441,18 +2538,18 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str iguana_bundleload(coin,&newchain,bp,0); newchain.A = 0; } - iguana_ramchain_free(dest,0); + iguana_ramchain_free(coin,dest,0); bp->ramchain = newchain; //printf("finished bundlesave.%d\n",bp->bundleheight); return(retval); } -void iguana_mergefree(struct OS_memspace *mem,struct iguana_ramchain *A,struct iguana_ramchain *B,struct OS_memspace *hashmem,struct OS_memspace *hashmemA,struct OS_memspace *hashmemB) +void iguana_mergefree(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_ramchain *A,struct iguana_ramchain *B,struct OS_memspace *hashmem,struct OS_memspace *hashmemA,struct OS_memspace *hashmemB) { if ( A != 0 ) - iguana_ramchain_free(A,0); + iguana_ramchain_free(coin,A,0); if ( B != 0 ) - iguana_ramchain_free(B,0); + iguana_ramchain_free(coin,B,0); if ( mem != 0 ) iguana_mempurge(mem); if ( hashmemA != 0 ) @@ -2485,7 +2582,7 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st if ( A == 0 || B == 0 || A->H.data == 0 || B->H.data == 0 || (A->H.data->allocsize + B->H.data->allocsize) > IGUANA_MAXRAMCHAINSIZE ) { printf("MERGE error %d[%d] %d[%d]\n",A->height,A->numblocks,B->height,B->numblocks); - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); return(-1); } if ( A->H.data != 0 && B->H.data != 0 && B->height == A->height+A->numblocks ) @@ -2493,7 +2590,7 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,(A->H.data->numtxids+B->H.data->numtxids),(A->H.data->numunspents+B->H.data->numunspents),(A->H.data->numspends+B->H.data->numspends),(A->H.data->numpkinds+B->H.data->numpkinds),(A->H.data->numexternaltxids+B->H.data->numexternaltxids),A->H.data->scriptspace,A->height,A->numblocks + B->numblocks) < 0 ) { printf("depth.%d ht.%d fsize.%s ERROR alloc lag.%d elapsed.%ld\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); return(-1); } depth++; @@ -2510,7 +2607,7 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st { printf("merging isnt setup to save the blockROs\n"); printf("depth.%d ht.%d fsize.%s MERGED %d[%d] and %d[%d] lag.%d elapsed.%ld bp.%d -> %d\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),A->height,A->numblocks,B->height,B->numblocks,now-starttime,time(NULL)-now,bp->bundleheight,nextbp->bundleheight); - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); bp->mergefinish = 0; nextbp->mergefinish = (uint32_t)time(NULL); bp->nextbp = nextbp->nextbp; @@ -2523,9 +2620,9 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st else { bp->mergefinish = nextbp->mergefinish = 0; - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); } - iguana_ramchain_free(dest,0); + iguana_ramchain_free(coin,dest,0); depth--; } else printf("error merging A.%d [%d] and B.%d [%d]\n",A->height,A->numblocks,B->height,B->numblocks); coin->merging--; diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index b84613fb7..918f47737 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -38,11 +38,13 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, if ( addr == 0 || memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) { //printf("duplicate req %s or null addr.%p\n",bits256_str(hexstr,hash2),addr); - return(0); + if ( (rand() % 10 ) != 0 ) + return(0); } if ( addr->msgcounts.verack == 0 ) { - //printf("iguana_sendblockreq (%s) hasn't verack'ed yet\n",addr->ipaddr); + //printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); + //iguana_send_version(coin,addr,coin->myservices); return(-1); } lastreq2 = lastreq; @@ -189,12 +191,25 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i { printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); return; - } //else printf("validated prev.%s\n",bits256_str(str,origtxdata->block.RO.prev_block)); - copyflag = 1 * (strcmp(coin->symbol,"BTC") != 0); + } + else if ( 0 && coin->enableCACHE != 0 ) + printf("cache.%d validated.(%s)\n",coin->enableCACHE,bits256_str(str,origtxdata->block.RO.hash2)); + copyflag = coin->enableCACHE; bp = 0, bundlei = -2; - if ( copyflag != 0 && recvlen != 0 && ((bp= iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2)) == 0 || (bp->blocks[bundlei] != 0 && bp->blocks[bundlei]->fpipbits == 0)) ) + bp = iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2); + if ( bp != 0 ) + { + if ( bp->emitfinish != 0 ) + { + //printf("got [%d:%d] with emitfinish.%u\n",bp->hdrsi,bundlei,bp->emitfinish); + return; + } + bp->dirty++; + } + if ( copyflag != 0 && recvlen != 0 && (bp == 0 || (bp->blocks[bundlei] != 0 && bp->blocks[bundlei]->fpipbits == 0)) ) { req = iguana_bundlereq(coin,addr,'B',copyflag * recvlen); + req->copyflag = 1; //printf("copy %p serialized[%d]\n",req,req->recvlen); memcpy(req->serialized,data,recvlen); } @@ -235,7 +250,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i if ( iguana_ramchain_data(coin,addr,origtxdata,txarray,origtxdata->block.RO.txn_count,data,recvlen) >= 0 ) { txdata->block.fpipbits = (uint32_t)addr->ipbits; - txdata->block.fpipbits = recvlen; + txdata->block.RO.recvlen = recvlen; txdata->block.fpos = 0; req->datalen = txdata->datalen; req->ipbits = txdata->block.fpipbits; @@ -253,7 +268,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } req->block = txdata->block; - //printf("recvlen.%d prev.(%s)\n",req->recvlen,bits256_str(str,txdata->block.RO.prev_block)); + //printf("recvlen.%d ipbits.%x prev.(%s)\n",req->block.RO.recvlen,req->block.fpipbits,bits256_str(str,txdata->block.RO.prev_block)); req->block.RO.txn_count = req->numtx = txdata->block.RO.txn_count; coin->recvcount++; coin->recvtime = (uint32_t)time(NULL); @@ -299,7 +314,9 @@ void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bi } req = iguana_bundlereq(coin,addr,'S',0); req->hashes = blockhashes, req->n = n; - //printf("bundlesQ blockhashes.%p[%d]\n",blockhashes,n); + char str[65]; + if ( 0 && n > 2 ) + printf("bundlesQ blockhashes.%s [%d]\n",bits256_str(str,blockhashes[1]),n); queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } @@ -395,7 +412,7 @@ uint32_t iguana_allhashcmp(struct iguana_info *coin,struct iguana_bundle *bp,bit prev = block; } coin->allhashes++; - // if ( bp->hdrsi == 0 ) + if ( bp->hdrsi == 0 ) printf("ALLHASHES FOUND! %d allhashes.%d\n",bp->bundleheight,coin->allhashes); if ( bp->queued == 0 ) iguana_bundleQ(coin,bp,bp->n*5 + (rand() % 500)); @@ -462,7 +479,7 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl } else if ( bp->hdrsi > 0 && (bp= coin->bundles[bp->hdrsi-1]) != 0 ) iguana_bundlehash2add(coin,0,bp,coin->chain->bundlesize-1,prevhash2); - if ( strcmp(coin->symbol,"BTC") != 0 ) + if ( coin->enableCACHE != 0 ) iguana_bundlespeculate(coin,bp,bundlei,hash2,1); } prevbp = 0, prevbundlei = -2; @@ -485,7 +502,7 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl //printf("bundlehash2add next %d\n",prevbundlei); iguana_bundlehash2add(coin,0,prevbp,prevbundlei+1,hash2); } - if ( strcmp(coin->symbol,"BTC") != 0 ) + if ( coin->enableCACHE != 0 ) iguana_bundlespeculate(coin,prevbp,prevbundlei,prevhash2,2); } } @@ -494,9 +511,31 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl return(iguana_bundlefind(coin,&bp,bundleip,hash2)); } +void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp,int32_t num) +{ + int32_t i; struct iguana_peer *addr; + if ( num > 10 && num < bp->n && coin->longestchain > bp->bundleheight+num+3 ) + { + printf("strange.%d suspicious longestchain.%d vs [%d:%d] %d bp->n %d\n",coin->longestchain_strange,coin->longestchain,bp->hdrsi,num,bp->bundleheight+num,bp->n); + if ( coin->longestchain_strange++ > 10 ) + { + coin->badlongestchain = coin->longestchain; + coin->longestchain = bp->bundleheight+num; + coin->longestchain_strange = 0; + for (i=0; ipeers.numranked; i++) + if ( (addr= coin->peers.ranked[i]) != 0 && addr->height >= coin->badlongestchain ) + { + printf("blacklist addr.(%s) height %d\n",addr->ipaddr,addr->height); + addr->dead = 1; + addr->rank = 0; + } + } + } +} + struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct iguana_bundlereq *req,struct iguana_block *blocks,int32_t n,int32_t *newhwmp) { - int32_t i,bundlei,match; bits256 *blockhashes,allhash; struct iguana_block *block; struct iguana_bundle *bp,*firstbp = 0; + int32_t i,bundlei,match; struct iguana_block *block; struct iguana_bundle *bp,*firstbp = 0; if ( blocks == 0 ) { printf("iguana_recvblockhdrs null blocks?\n"); @@ -504,7 +543,7 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig } if ( blocks != 0 && n > 0 ) { - if ( 0 && n >= coin->chain->bundlesize ) + /*if ( 0 && n >= coin->chain->bundlesize ) { blockhashes = malloc(sizeof(*blockhashes) * coin->chain->bundlesize); for (i=0; ichain->bundlesize; i++) @@ -528,16 +567,20 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig } } free(blockhashes); - } + }*/ for (i=match=0; idirty++; //printf("{%d:%d} ",bp->hdrsi,bundlei); if ( i == 0 ) + { firstbp = bp; + iguana_checklongestchain(coin,bp,n); + } if ( bundlei == i+1 && bp == firstbp ) match++; else @@ -545,7 +588,9 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig if ( i != n-1 ) fprintf(stderr,"recvhdr: ht.%d[%d] vs i.%d\n",bp->bundleheight,bundlei,i); } - } else printf("blockhash[%d] cant be found\n",i); + } + else if ( bp != firstbp ) + printf("blockhash[%d] cant be found\n",i); } //char str[65]; printf("blockhdrs.%s hdrsi.%d\n",bits256_str(str,blocks[0].RO.hash2),firstbp!=0?firstbp->hdrsi:-1); if ( firstbp != 0 && match == coin->chain->bundlesize-1 && n == firstbp->n ) @@ -560,9 +605,26 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig return(req); } +void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp) +{ + char hashstr[65],str[65],str2[65]; struct iguana_bundle *newbp; int32_t bundlei; static bits256 zero; + if ( bp->hdrsi == coin->bundlescount-1 && bits256_nonz(bp->nextbundlehash2) != 0 ) + { + init_hexbytes_noT(hashstr,bp->nextbundlehash2.bytes,sizeof(bits256)); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + newbp = iguana_bundlecreate(coin,&bundlei,bp->bundleheight+coin->chain->bundlesize,bp->nextbundlehash2,zero,1); + if ( newbp != 0 ) + { + printf("EXTEND last bundle %s/%s ht.%d\n",bits256_str(str,newbp->hashes[0]),bits256_str(str2,bp->nextbundlehash2),newbp->bundleheight); + if ( newbp->queued == 0 ) + iguana_bundleQ(coin,newbp,1000); + } + } +} + struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) { - int32_t bundlei,i,len; struct iguana_bundle *bp; bits256 allhash,zero; char hashstr[65]; uint8_t serialized[512]; struct iguana_peer *addr; + int32_t bundlei,i,len; struct iguana_bundle *bp; bits256 allhash,zero; uint8_t serialized[512]; struct iguana_peer *addr; struct iguana_block *block; memset(zero.bytes,0,sizeof(zero)); bp = 0, bundlei = -2; if ( num < 2 ) @@ -571,42 +633,38 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //iguana_blockQ(coin,0,-1,blockhashes[1],0); //iguana_blockQ(coin,0,-4,blockhashes[1],1); char str[65]; - if ( num > 2 )//&& bp->hdrsi == coin->bundlescount-1 ) + if ( 0 && num > 2 ) printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( bp != 0 ) { + bp->dirty++; bp->hdrtime = (uint32_t)time(NULL); blockhashes[0] = bp->hashes[0]; iguana_blockQ("recvhash0",coin,bp,0,blockhashes[0],0); if ( num >= coin->chain->bundlesize ) { - iguana_blockQ("recvhash1",coin,0,-1,blockhashes[coin->chain->bundlesize],0); - //printf("call allhashes\n"); - if ( bp->hdrsi == coin->bundlescount-1 ) + if ( bits256_nonz(bp->nextbundlehash2) == 0 && num > coin->chain->bundlesize ) { - init_hexbytes_noT(hashstr,blockhashes[coin->chain->bundlesize].bytes,sizeof(bits256)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - bp = iguana_bundlecreate(coin,&bundlei,bp->bundleheight+coin->chain->bundlesize,blockhashes[coin->chain->bundlesize],zero,1); - if ( bp != 0 ) - { - char str2[65]; - printf("EXTEND last bundle %s/%s ht.%d\n",bits256_str(str,bp->hashes[0]),bits256_str(str2,blockhashes[coin->chain->bundlesize]),bp->bundleheight); - if ( bp->queued == 0 ) - iguana_bundleQ(coin,bp,1000); - } + bp->nextbundlehash2 = blockhashes[coin->chain->bundlesize]; + iguana_blockQ("recvhash1",coin,0,-1,bp->nextbundlehash2,0); } - else if ( iguana_allhashcmp(coin,bp,blockhashes,num) > 0 ) + //printf("call allhashes\n"); + if ( bp->hdrsi == coin->bundlescount-1 ) + iguana_autoextend(coin,bp); + if ( iguana_allhashcmp(coin,bp,blockhashes,num) > 0 ) return(req); //printf("done allhashes\n"); } - if ( bp != 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) + else if ( bp->hdrsi == coin->bundlescount-1 ) + iguana_checklongestchain(coin,bp,num); + if ( (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) { - printf("FOUND speculative.%p BLOCKHASHES[%d] ht.%d\n",bp->speculative,num,bp->bundleheight); - if ( bp->speculative != 0 ) - myfree(bp->speculative,sizeof(*bp->speculative) * bp->numspec); - bp->speculative = blockhashes; - bp->numspec = num; - req->hashes = 0; + //printf("FOUND speculative.%s BLOCKHASHES[%d] ht.%d\n",bits256_str(str,blockhashes[1]),num,bp->bundleheight); + if ( bp->speculative == 0 ) + bp->speculative = mycalloc('s',bp->n+1,sizeof(*bp->speculative)); + for (i=bp->numspec; in; i++) + bp->speculative[i] = blockhashes[i]; + bp->numspec = num <= bp->n+1 ? num : bp->n+1; //iguana_blockQ(coin,0,-1,blockhashes[2],1); } } @@ -627,8 +685,8 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct bp->hdrtime = (uint32_t)time(NULL); iguana_blockQ("recvhash2",coin,bp,1,blockhashes[1],0); iguana_blockQ("recvhash3",coin,bp,0,blockhashes[0],0); - iguana_blockQ("recvhash4",coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],0); - printf("matched bundle.%d\n",bp->bundleheight); + //iguana_blockQ("recvhash4",coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],0); + //printf("matched bundle.%d\n",bp->bundleheight); return(req); } else printf("unexpected mismatch??\n"); } @@ -636,9 +694,9 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct } //printf("no match to allhashes issue block1\n"); struct iguana_block *block; - if ( num == coin->chain->bundlesize+1 && (block= iguana_blockhashset(coin,-1,blockhashes[1],1)) != 0 ) + if ( (block= iguana_blockhashset(coin,-1,blockhashes[1],1)) != 0 ) { - block->blockhashes = blockhashes, req->hashes = 0; + //block->blockhashes = blockhashes, req->hashes = 0; //printf("set block->blockhashes[%d]\n",num); } if ( (addr= coin->peers.ranked[0]) != 0 ) @@ -646,18 +704,53 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&blockhashes[1],1)) > 0 ) { iguana_send(coin,addr,serialized,len); - char str[65]; printf("REQ.%s\n",bits256_str(str,blockhashes[1])); + //char str[65]; printf("REQ.%s\n",bits256_str(str,blockhashes[1])); } + } else iguana_blockQ("hdr1",coin,0,-1,blockhashes[1],1); + } + else + { + if ( (block= iguana_blockfind(coin,blockhashes[1])) == 0 ) + { + iguana_blockhashset(coin,-1,blockhashes[1],1); + if ( (block= iguana_blockfind(coin,blockhashes[1])) != 0 ) + { + block->newtx = 1; + iguana_blockQ("recvhash6",coin,0,-6,blockhashes[1],1); // should be RT block + } + } + else + { + block->newtx = 1; + iguana_blockQ("recvhash6",coin,0,-7,blockhashes[1],0); // should be RT block } - } else iguana_blockQ("recvhash6",coin,0,-6,blockhashes[1],0); // should be RT block + } return(req); } struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundlereq *req,struct iguana_block *origblock,int32_t numtx,int32_t datalen,int32_t recvlen,int32_t *newhwmp) { - struct iguana_bundle *bp=0; int32_t i,numsaved=0,bundlei = -2; struct iguana_block *block,*tmpblock; char str[65]; + struct iguana_bundle *bp=0; int32_t i,width,numsaved=0,bundlei = -2; struct iguana_block *block,*tmpblock,*prev; char str[65]; if ( (bp= iguana_bundleset(coin,&block,&bundlei,origblock)) == 0 ) { + if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,origblock->RO.hash2)) != 0 ) + { + printf("iguana_recvblock got block [%d:%d]\n",bp->hdrsi,bundlei); + /*if ( bits256_cmp(prev->RO.hash2,block->RO.prev_block) == 0 && bundlei < bp->n-1 ) + { + bundlei++; + iguana_bundlehash2add(coin,&tmpblock,bp,bundlei,block->RO.hash2); + if ( tmpblock == block ) + { + printf("[%d:%d] speculative block.%p\n",bp->hdrsi,bundlei,block); + bp->blocks[bundlei] = block; + bp->hashes[bundlei] = block->RO.hash2; + block->bundlei = bundlei; + block->hdrsi = bp->hdrsi; + block->mainchain = prev->mainchain; + } else printf("error adding speculative prev [%d:%d]\n",bp->hdrsi,bundlei); + }*/ + } for (i=coin->bundlescount-1; i>=0; i--) { //if ( coin->bundles[i] != 0 ) @@ -667,7 +760,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana bp = coin->bundles[i]; bundlei = 1; iguana_bundlehash2add(coin,&block,bp,bundlei,origblock->RO.hash2); - printf("[%d] bundlehashadd set.%d block.%p\n",i,bundlei,block); + printf("iguana_recvblock [%d] bundlehashadd set.%d block.%p\n",i,bundlei,block); if ( block != 0 ) { bp->blocks[bundlei] = block; @@ -677,9 +770,27 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana break; } } - printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); + //printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); } - if ( 0 && bp != 0 && bp->hdrsi == coin->bundlescount-1 ) + else if ( bp == coin->current && bp != 0 && block != 0 && bundlei >= 0 ) + { + if ( bp->speculative != 0 && bp->numspec <= bundlei ) + { + bp->speculative[bundlei] = block->RO.hash2; + bp->numspec = bundlei+1; + } + if ( block != 0 && bundlei > 0 && (prev= iguana_blockfind(coin,block->RO.prev_block)) != 0 ) + { + if ( bp->bundleheight+bundlei-1 >= coin->blocks.hwmchain.height ) + { + //printf("prev issue.%s\n",bits256_str(str,prev->RO.hash2)); + iguana_blockQ("previssue",coin,bp,bundlei-1,prev->RO.hash2,0); + } + } + } + if ( bp != 0 ) + bp->dirty++; + if ( 0 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) { int32_t i; static int32_t numrecv; numrecv++; @@ -689,24 +800,54 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana if ( (tmpblock= bp->blocks[i]) != 0 && tmpblock->fpipbits != 0 && tmpblock->fpos >= 0 && ((bp->hdrsi == 0 && i == 0) || bits256_nonz(tmpblock->RO.prev_block) != 0) ) numsaved++; } - fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,numsaved,numrecv); + fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d copy.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,numsaved,numrecv,req->copyflag); } - if ( bundlei == 1 && bp != 0 && bp->numhashes < bp->n && strcmp(coin->symbol,"BTC") != 0 ) + if ( 1 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && coin->enableCACHE != 0 ) { - printf("reissue hdrs request for [%d]\n",bp->hdrsi); + //printf("reissue hdrs request for [%d]\n",bp->hdrsi); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); } - if ( block != 0 ) + if ( (block= iguana_blockhashset(coin,-1,origblock->RO.hash2,1)) != 0 ) { - block->RO.txn_count = req->numtx; - //block->RO.recvlen = recvlen; - if ( req->copyflag != 0 && block->queued == 0 && bp != 0 ) + if ( block != origblock ) + iguana_blockcopy(coin,block,origblock); + if ( block->newtx != 0 ) { - char str[65]; fprintf(stderr,"req.%p %s copyflag.%d %d data %d %d\n",req,bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,recvlen); - coin->numcached++; - block->queued = 1; - queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); - return(0); + if ( (prev= iguana_blockfind(coin,block->RO.prev_block)) == 0 ) + prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); + width = sqrt(coin->chain->bundlesize); + while ( prev != 0 && width-- > 0 ) + { + if ( prev->mainchain != 0 ) + break; + if ( prev->fpipbits == 0 ) + { + //printf("width.%d auto prev newtx %s\n",width,bits256_str(str,prev->RO.hash2)); + prev->newtx = 1; + iguana_blockQ("autoprev",coin,0,-1,prev->RO.hash2,0); + } + if ( bits256_nonz(prev->RO.prev_block) != 0 ) + { + if ( (prev = iguana_blockhashset(coin,-1,prev->RO.prev_block,1)) != 0 ) + prev->newtx = 1; + } else prev = 0; + } + } + if ( req->copyflag != 0 ) + { + if ( block->queued == 0 && bp != 0 ) + { + //char str[65]; fprintf(stderr,"req.%p %s copyflag.%d %d data %d %d\n",req,bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,recvlen); + coin->numcached++; + block->queued = 1; + queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); + return(0); + } + else if ( block->req == 0 ) + { + block->req = req; + req = 0; + } //else printf("already have cache entry.(%s)\n",bits256_str(str,origblock->RO.hash2)); } //printf("datalen.%d ipbits.%x\n",datalen,req->ipbits); } else printf("cant create origblock.%p block.%p bp.%p bundlei.%d\n",origblock,block,bp,bundlei); @@ -715,6 +856,9 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana struct iguana_bundlereq *iguana_recvtxids(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *txids,int32_t n) { + char str[65]; + if ( n > 0 ) + printf("got txids[%d] %s\n",n,bits256_str(str,txids[0])); return(req); } @@ -785,7 +929,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) _iguana_chainlink(coin,next); else if ( next->queued == 0 && next->fpipbits == 0 && (rand() % 100) == 0 ) { - printf("HWM next %d\n",coin->blocks.hwmchain.height+1); + //printf("HWM next %d\n",coin->blocks.hwmchain.height+1); iguana_blockQ("reqblocks",coin,bp,bundlei,next->RO.hash2,0); } } @@ -825,7 +969,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) if ( (next= iguana_blockfind(coin,iguana_blockhash(coin,coin->blocks.hwmchain.height+1))) == 0 ) { if ( (block= iguana_blockfind(coin,coin->blocks.hwmchain.RO.hash2)) != 0 ) - next = block->hh.next, block->mainchain = 1; + next = block->hh.next; //, next/block->mainchain = 1; } if ( next == 0 && hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 && (next= bp->blocks[bundlei]) != 0 ) { @@ -836,7 +980,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) next = 0; } } - else if ( bp != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+60 ) + /*else if ( bp != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+60 ) { if ( bundlei > 0 && bits256_nonz(bp->hashes[bundlei+1]) != 0 ) { @@ -847,7 +991,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) iguana_blockQ("reqblocks1",coin,bp,bundlei,bp->hashes[bundlei],0); } } - } + }*/ if ( next != 0 ) { //printf("have next %d\n",coin->blocks.hwmchain.height); @@ -857,55 +1001,79 @@ int32_t iguana_reqblocks(struct iguana_info *coin) lflag++, flag++; //else printf("chainlink error for %d\n",coin->blocks.hwmchain.height+1); } - if ( strcmp(coin->symbol,"BTC") != 0 && queue_size(&coin->blocksQ) < _IGUANA_MAXPENDING ) + } + if ( 1 )//queue_size(&coin->blocksQ) < _IGUANA_MAXPENDING ) + { + /*double threshold,lag = OS_milliseconds() - coin->backstopmillis; + threshold = (10 + coin->longestchain - coin->blocksrecv); + if ( threshold < 1 ) + threshold = 1.; + if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) != 0 ) + threshold = (bp->avetime + coin->avetime) * .5; + else threshold = coin->avetime; + threshold *= 100. * sqrt(threshold) * .000777;*/ + double threshold,lag = OS_milliseconds() - coin->backstopmillis; + if ( coin->blocks.hwmchain.height >= coin->longestchain-1 ) + threshold = 1000; + else threshold = 300; + if ( strcmp(coin->symbol,"BTC") == 0 ) + threshold *= 10; + if ( coin->blocks.hwmchain.height < coin->longestchain && ((strcmp(coin->symbol,"BTC") != 0 && coin->backstop != coin->blocks.hwmchain.height+1) || lag > threshold) ) { - double threshold,lag = OS_milliseconds() - coin->backstopmillis; - threshold = (10 + coin->longestchain - coin->blocksrecv); - if ( threshold < 1 ) - threshold = 1.; - if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) != 0 ) - threshold = (bp->avetime + coin->avetime) * .5; - else threshold = coin->avetime; - threshold *= 100. * sqrt(threshold) * .000777; - if ( strcmp(coin->symbol,"BTC") != 0 ) - threshold = 1000; - else threshold = 10000; - if ( coin->blocks.hwmchain.height < coin->longestchain && (coin->backstop != coin->blocks.hwmchain.height+1 || lag > threshold) ) + coin->backstop = coin->blocks.hwmchain.height+1; + hash2 = iguana_blockhash(coin,coin->backstop); + bp = coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]; + bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; + if ( bp != 0 && bits256_nonz(hash2) == 0 ) { - coin->backstop = coin->blocks.hwmchain.height+1; - hash2 = iguana_blockhash(coin,coin->backstop); - bp = coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]; - bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; - if ( bp != 0 && bits256_nonz(hash2) == 0 ) - { - hash2 = bp->hashes[bundlei]; - if ( bits256_nonz(hash2) == 0 && bp->speculative != 0 ) - hash2 = bp->speculative[bundlei]; - } - if ( bits256_nonz(hash2) > 0 ) + hash2 = bp->hashes[bundlei]; + if ( bits256_nonz(hash2) == 0 && bp->speculative != 0 ) { - if ( bp != 0 && bits256_nonz(hash2) > 0 ) + hash2 = bp->speculative[bundlei]; + if ( bits256_nonz(hash2) > 0 ) { - coin->backstopmillis = OS_milliseconds(); - iguana_blockQ("mainchain",coin,bp,bundlei,hash2,0); - flag++; - char str[65]; - if ( 1 && (rand() % 1000) == 0 || bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) - printf("%s MAINCHAIN.%d threshold %.3f %.3f lag %.3f\n",bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,coin->backstopmillis,lag); + if ( (block= iguana_blockfind(coin,hash2)) != 0 && bits256_cmp(block->RO.prev_block,coin->blocks.hwmchain.RO.hash2) == 0 ) + { + //printf("speculative is next at %d\n",coin->backstop); + if ( _iguana_chainlink(coin,block) != 0 ) + lflag++, flag++;//, printf("NEWHWM.%d\n",coin->backstop); + } } } - /*else if ( bp != 0 && bundlei < bp->n-1 && bits256_nonz(bp->hashes[bundlei+1]) > 0 ) + } + if ( bits256_nonz(hash2) > 0 ) + { + coin->backstopmillis = OS_milliseconds(); + iguana_blockQ("mainchain",coin,0,-1,hash2,lag > threshold); + flag++; + char str[65]; + if ( 1 && (rand() % 10000) == 0 )//|| bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) + printf("%s %s MAIN.%d t %.3flag %.3f\n",coin->symbol,bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,lag); + } + else if ( bp != 0 && bundlei < bp->n-1 && (bits256_nonz(bp->hashes[bundlei+1]) != 0 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) + { + int32_t j; + //memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); + bp->blocks[bundlei] = 0; + for (j=0; j<1&&bundlei+j+1n; j++) { - printf("MAINCHAIN skip issue %d\n",bundlei+1); - iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); + if ( time(NULL) > bp->issued[bundlei+1+j]+10 ) + { + bp->issued[bundlei+1+j] = (uint32_t)time(NULL); + printf("MAINCHAIN skip issue %d\n",bp->bundleheight+bundlei+1+j); + if ( bits256_nonz(bp->hashes[bundlei+1+j]) != 0 ) + iguana_blockQ("mainskip",coin,bp,bundlei+1+j,bp->hashes[bundlei+1+j],0); + else if ( bp->speculative != 0 && bundlei+1+j < bp->numspec ) + iguana_blockQ("mainskip",coin,bp,bundlei+1+j,bp->speculative[bundlei+1+j],0); + } } - else if ( bp != 0 && time(NULL) > bp->hdrtime+10 ) - { - char str[65]; - printf("MAINCHAIN gethdr %d\n",bp->bundleheight); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); - bp->hdrtime = (uint32_t)time(NULL); - }*/ + } + else if ( bp != 0 && time(NULL) > bp->hdrtime+10 ) + { + char str[65]; + //printf("MAINCHAIN gethdr %d %s\n",bp->bundleheight,bits256_str(str,bp->hashes[0])); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + bp->hdrtime = (uint32_t)time(NULL); } } } @@ -972,21 +1140,24 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) int32_t i,lag,n = 0; struct iguana_bundle *bp; char hashstr[65]; if ( queue_size(&coin->hdrsQ) == 0 ) { - if ( iguana_needhdrs(coin) > 0 ) + //if ( iguana_needhdrs(coin) > 0 ) { for (i=0; ibundlescount; i++) { - if ( (bp= coin->bundles[i]) != 0 && (bp->numhashes < bp->n || i == coin->bundlescount-1) ) + if ( (bp= coin->bundles[i]) != 0 && (bp->hdrsi == coin->longestchain/coin->chain->bundlesize || i == coin->bundlescount-1 || bp->numhashes < bp->n) ) { - lag = 60; - if ( bp->bundleheight+bp->numhashes < coin->longestchain && time(NULL) > bp->issuetime+lag ) + if ( bp == coin->current ) + lag = 13; + else lag = 30; + if ( time(NULL) > bp->issuetime+lag ) { - //printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); + if ( 0 && bp == coin->current ) + printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); if ( bp->issuetime == 0 ) coin->numpendings++; init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); + //printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); if ( 1 ) { iguana_blockQ("reqhdrs0",coin,bp,0,bp->hashes[0],0); @@ -1010,10 +1181,11 @@ struct iguana_blockreq { struct queueitem DL; bits256 hash2,*blockhashes; struct int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority) { - queue_t *Q; char *str; int32_t height = -1; struct iguana_blockreq *req; struct iguana_block *block = 0; + queue_t *Q; char *str; int32_t n,height = -1; struct iguana_blockreq *req; struct iguana_block *block = 0; if ( bits256_nonz(hash2) == 0 ) { printf("cant queue zerohash bundlei.%d\n",bundlei); + //getchar(); return(-1); } block = iguana_blockfind(coin,hash2); @@ -1027,8 +1199,17 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle } if ( block != 0 ) { - if ( bits256_cmp(coin->APIblockhash,hash2) != 0 && block->fpipbits != 0 && block->fpos >= 0 ) + if ( bits256_cmp(coin->APIblockhash,hash2) != 0 && (block->fpipbits != 0 || block->req != 0 || block->queued != 0) ) + { + if ( block->fpipbits == 0 && block->queued == 0 && block->req != 0 ) + { + block->queued = 1; + queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); + block->req = 0; + //char str2[65]; printf("already have.(%s)\n",bits256_str(str2,block->RO.hash2)); + } return(0); + } height = block->height; } if ( bp != 0 && bp->emitfinish != 0 ) @@ -1048,8 +1229,15 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle req->height = height; req->bundlei = bundlei; char str2[65]; - if ( 0 && (bundlei % 250) == 0 ) - printf("%s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + if ( Q == &coin->blocksQ ) + { + if ( (n= queue_size(Q)) > 100000 ) + { + if ( n > 200000 ) + printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + coin->backlog = n*10; + } else coin->backlog >>= 1; + } if ( block != 0 ) { block->numrequests++; @@ -1095,7 +1283,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) else if ( bp->numhashes < bp->n ) z = 1; } - if ( bp == 0 || z != 0 ) + if ( bp == 0 || z != 0 || bp == coin->current ) { //printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0); iguana_send(coin,addr,serialized,datalen); @@ -1138,20 +1326,25 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) { hash2 = req->hash2; height = req->height; - block = 0; - if ( priority == 0 && (bp= req->bp) != 0 && req->bundlei >= 0 && req->bundlei < bp->n && req->bundlei < coin->chain->bundlesize && (block= bp->blocks[req->bundlei]) != 0 && (block->fpipbits != 0 || block->queued != 0) ) + if ( (bp= req->bp) != 0 && req->bundlei >= 0 && req->bundlei < bp->n ) + { + if ( bp->emitfinish != 0 ) + { + //printf("skip emitting bundle [%d:%d]\n",bp->hdrsi,req->bundlei); + return(0); + } + block = bp->blocks[req->bundlei]; + } else block = 0; + if ( priority == 0 && bp != 0 && req->bundlei >= 0 && req->bundlei < bp->n && req->bundlei < coin->chain->bundlesize && block != 0 && (block->fpipbits != 0 || block->queued != 0) ) { if ( 1 && priority != 0 ) printf("SKIP %p[%d] %d\n",bp,bp!=0?bp->bundleheight:-1,req->bundlei); } else { - char str[65]; if ( block != 0 ) block->numrequests++; - if ( 0 && priority != 0 ) - printf("sendreq %s [%d:%d]\n",bits256_str(str,hash2),bp!=0?bp->bundleheight:-1,req->bundlei); - iguana_sendblockreqPT(coin,addr,req->bp,req->bundlei,hash2,0); + iguana_sendblockreqPT(coin,addr,bp,req->bundlei,hash2,0); } flag++; myfree(req,sizeof(*req)); @@ -1161,12 +1354,11 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) int32_t iguana_processrecv(struct iguana_info *coin) // single threaded { - int32_t newhwm = 0,flag = 0; - //fprintf(stderr,"process coin->recvQ\n"); + int32_t newhwm = 0,hwmheight,flag = 0; + hwmheight = coin->blocks.hwmchain.height; flag += iguana_processrecvQ(coin,&newhwm); - //fprintf(stderr,"iguana_reqhdrs\n"); flag += iguana_reqhdrs(coin); - //fprintf(stderr,"iguana_reqblocks\n"); - //flag += iguana_reqblocks(coin); + if ( hwmheight != coin->blocks.hwmchain.height ) + flag = 1; return(flag); } diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 5fa71c192..07cc3e01c 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -16,6 +16,111 @@ #include "iguana777.h" #include "exchanges/bitcoin.h" +struct iguana_hhutxo *iguana_hhutxofind(struct iguana_info *coin,uint8_t *ubuf,uint16_t spent_hdrsi,uint32_t spent_unspentind) +{ + struct iguana_hhutxo *hhutxo; uint8_t buf[sizeof(spent_unspentind) + sizeof(spent_hdrsi)]; + memcpy(buf,ubuf,sizeof(buf)); + memcpy(&buf[sizeof(spent_unspentind)],(void *)&spent_hdrsi,sizeof(spent_hdrsi)); + memcpy(buf,(void *)&spent_unspentind,sizeof(spent_unspentind)); + HASH_FIND(hh,coin->utxotable,buf,sizeof(buf),hhutxo); + return(hhutxo); +} + +struct iguana_hhaccount *iguana_hhaccountfind(struct iguana_info *coin,uint8_t *pkbuf,uint16_t spent_hdrsi,uint32_t spent_pkind) +{ + struct iguana_hhaccount *hhacct; uint8_t buf[sizeof(spent_pkind) + sizeof(spent_hdrsi)]; + memcpy(buf,pkbuf,sizeof(buf)); + memcpy(&buf[sizeof(spent_pkind)],(void *)&spent_hdrsi,sizeof(spent_hdrsi)); + memcpy(buf,(void *)&spent_pkind,sizeof(spent_pkind)); + HASH_FIND(hh,coin->utxotable,buf,sizeof(buf),hhacct); + return(hhacct); +} + +int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight) +{ + struct iguana_hhutxo *hhutxo,*tmputxo; struct iguana_hhaccount *hhacct,*tmpacct; + uint8_t pkbuf[sizeof(spent_hdrsi) + sizeof(uint32_t)]; + uint8_t ubuf[sizeof(spent_hdrsi) + sizeof(uint32_t)]; + uint8_t buf[sizeof(spent_hdrsi) + sizeof(uint32_t)]; + if ( spent_hdrsi < 0 ) + { + if ( coin->utxotable != 0 ) + { + HASH_ITER(hh,coin->utxotable,hhutxo,tmputxo) + { + HASH_DEL(coin->utxotable,hhutxo); + free(hhutxo); + } + coin->utxotable = 0; + } + if ( coin->accountstable != 0 ) + { + HASH_ITER(hh,coin->accountstable,hhacct,tmpacct) + { + HASH_DEL(coin->accountstable,hhacct); + free(hhacct); + } + coin->accountstable = 0; + } + return(0); + } + //printf("utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),fromheight/coin->chain->bundlesize,fromheight%coin->chain->bundlesize,spendind); + if ( (hhutxo= iguana_hhutxofind(coin,ubuf,spent_hdrsi,spent_unspentind)) != 0 && hhutxo->u.spentflag != 0 ) + { + printf("hhutxo.%p spentflag.%d\n",hhutxo,hhutxo->u.spentflag); + return(-1); + } + hhutxo = calloc(1,sizeof(*hhutxo)); + memcpy(buf,ubuf,sizeof(buf)); + HASH_ADD(hh,coin->utxotable,buf,sizeof(buf),hhutxo); + if ( (hhacct= iguana_hhaccountfind(coin,pkbuf,spent_hdrsi,spent_pkind)) == 0 ) + { + hhacct = calloc(1,sizeof(*hhacct)); + memcpy(buf,pkbuf,sizeof(buf)); + HASH_ADD(hh,coin->accountstable,buf,sizeof(buf),hhacct); + } + //printf("create hhutxo.%p hhacct.%p from.%d\n",hhutxo,hhacct,fromheight); + hhutxo->u.spentflag = 1; + hhutxo->u.fromheight = fromheight; + hhutxo->u.prevunspentind = hhacct->a.lastunspentind; + hhacct->a.lastunspentind = spent_unspentind; + hhacct->a.total += spent_value; + return(0); +} + +int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_ramchain *spentchain,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight) +{ + struct iguana_account *A2; struct iguana_ramchaindata *rdata; struct iguana_utxo *utxo; + if ( (rdata= spentchain->H.data) != 0 ) + { + if ( incremental == 0 ) + { + A2 = spentchain->A; + if ( spentchain->Uextras != 0 && A2 != 0 ) + { + utxo = &spentchain->Uextras[spent_unspentind]; + if ( utxo->spentflag == 0 ) + { + utxo->prevunspentind = A2[spent_pkind].lastunspentind; + utxo->spentflag = 1; + utxo->fromheight = fromheight; + A2[spent_pkind].total += spent_value; + A2[spent_pkind].lastunspentind = spent_unspentind; + return(0); + } else printf("spent_unspentind[%d] in hdrs.[%d] is spent\n",spent_unspentind,spent_hdrsi); + } else printf("null ptrs.[%d] u.%u p.%u %.8f from ht.%d s.%u\n",spent_hdrsi,spent_unspentind,spent_pkind,dstr(spent_value),fromheight,spendind); + } + else // do the equivalent of historical, ie mark as spent, linked list, balance + { + if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight) == 0 ) + return(0); + } + printf("iguana_volatileupdate: [%d] spent.(u%u %.8f pkind.%d) double spend? at ht.%d [%d] spendind.%d\n",spent_hdrsi,spent_unspentind,dstr(spent_value),spent_pkind,fromheight,fromheight/coin->chain->bundlesize,spendind); + exit(-1); + } + return(-1); +} + struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,int64_t *balancep,uint32_t *lastunspentindp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi) { uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_account *ACCTS; @@ -36,7 +141,7 @@ struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_r { *ramchainp = ramchain; *balancep = ACCTS[pkind].total; - *lastunspentindp = ACCTS[pkind].lastind; + *lastunspentindp = ACCTS[pkind].lastunspentind; *p = P[pkind]; return(p); } //else printf("not found pkind.%d vs num.%d\n",pkind,ramchain->H.data->numpkinds); @@ -69,7 +174,7 @@ char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi) } return(clonestr("{\"error\":\"no bundle\"}")); } -struct iguana_bundle *iguana_spent(struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spend_hdrsi,struct iguana_spend *s) +struct iguana_bundle *iguana_externalspent(struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spend_hdrsi,struct iguana_spend *s) { int32_t prev_vout,height,hdrsi; uint32_t sequenceid,unspentind; char str[65]; struct iguana_bundle *spentbp=0; struct iguana_txid *T,TX,*tp; bits256 *X; bits256 prev_hash; @@ -109,7 +214,7 @@ struct iguana_bundle *iguana_spent(struct iguana_info *coin,bits256 *prevhashp,u if ( hdrsi > spend_hdrsi || (spentbp= coin->bundles[hdrsi]) == 0 ) printf("illegal hdrsi.%d when [%d] spentbp.%p\n",hdrsi,spend_hdrsi,spentbp);//, getchar(); //else if ( spentbp->ramchain.spents[unspentind].ind != 0 || hdrsi < 0 ) - // printf("DOUBLE SPEND? U%d %p bp.[%d] unspentind.%u already has %u, no room\n",unspentind,&spentbp->ramchain.spents[unspentind],hdrsi,unspentind,spentbp->ramchain.spents[unspentind].ind);//, getchar(); + // printf("DOUBLE SPEND? U%d %p bp.[%d] unspentind.%u already has %u, no room\n",unspentind,&spentbp->ramchain.spents[unspentind],hdrsi,unspentind,spentbp->ramchain.spents[unspentind].ind);//, getchar(); else if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) printf("illegal unspentind.%d vs max.%d spentbp.%p[%d]\n",unspentind,spentbp->ramchain.H.data->numunspents,spentbp,hdrsi);//, getchar(); else return(spentbp); @@ -237,253 +342,859 @@ uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array return(rmdarray); } -int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) +int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp) { static uint64_t total,emitted; - int32_t spendind,height,n,numtxid,errs=0,emit=0; uint32_t unspentind; struct iguana_bundle *spentbp; - FILE *fp; char fname[1024],str[65],dirname[128]; int32_t hdrsi,retval = -1; - bits256 prevhash,zero,sha256; struct iguana_unspent *u; long fsize; struct iguana_txid *nextT; + int32_t spendind,n,txidind,errs=0,emit=0,i,j,k,retval = -1; long fsize; + uint32_t spent_unspentind,spent_pkind,now; struct iguana_ramchaindata *rdata; + struct iguana_bundle *spentbp; struct iguana_blockRO *B; FILE *fp; char fname[1024],str[65]; + bits256 prevhash,zero,sha256; struct iguana_unspent *u,*spentU; struct iguana_txid *T; struct iguana_spend *S,*s; struct iguana_spendvector *ptr; struct iguana_ramchain *ramchain; ramchain = &bp->ramchain; - //printf("UTXO gen.%d ramchain data.%p\n",bp->bundleheight,ramchain->H.data); - if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) + //printf("iguana_spendvectors gen.%d ramchain data.%p\n",bp->bundleheight,ramchain->H.data); + if ( (rdata= ramchain->H.data) == 0 || (n= rdata->numspends) < 1 ) return(0); - S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); - nextT = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); - numtxid = 1; + B = (void *)(long)((long)rdata + rdata->Boffset); + S = (void *)(long)((long)rdata + rdata->Soffset); + T = (void *)(long)((long)rdata + rdata->Toffset); if ( ramchain->Xspendinds != 0 ) { - //printf("iguana_utxogen: already have Xspendinds[%d]\n",ramchain->numXspends); + //printf("iguana_spendvectors: already have Xspendinds[%d]\n",ramchain->numXspends); return(0); } ptr = mycalloc('x',sizeof(*ptr),n); total += n; - height = bp->bundleheight; //printf("start UTXOGEN.%d max.%d ptr.%p\n",bp->bundleheight,n,ptr); - for (spendind=ramchain->H.data->firsti; spendindfirsti; + iguana_ramchain_prefetch(coin,ramchain); + for (i=0; in; i++) { - s = &S[spendind]; - if ( spendind == nextT[numtxid].firstvin ) + if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin ) { - height = bp->bundleheight + numtxid; - //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); - numtxid++; + printf("utxogen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i); + myfree(ptr,sizeof(*ptr) * n); + return(-1); } - u = 0; - if ( s->external != 0 && s->prevout >= 0 ) + for (j=0; jhdrsi,s)) != 0 ) + now = (uint32_t)time(NULL); + if ( txidind != T[txidind].txidind || spendind != T[txidind].firstvin ) { - if ( (ptr[emit].ind= unspentind) != 0 && spentbp->hdrsi < bp->hdrsi ) - { - ptr[emit].hdrsi = spentbp->hdrsi; - ptr[emit].height = height; - //printf("(%d u%d).%d ",spentbp->hdrsi,unspentind,emit); - emit++; - } - else - { - printf("utxogen: null unspentind for spendind.%d hdrsi.%d [%d]\n",spendind,spentbp->hdrsi,bp->hdrsi); - errs++; - } - if ( spentbp == bp ) - { - char str[65]; - printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",height,spentbp->hdrsi,unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); - errs++; - } + printf("utxogen: txidind %u != %u nextT[txidind].firsttxidind || spendind %u != %u nextT[txidind].firstvin\n",txidind,T[txidind].txidind,spendind,T[txidind].firstvin); + myfree(ptr,sizeof(*ptr) * n); + return(-1); } - else + for (k=0; khdrsi); + s = &S[spendind]; + u = 0; + if ( s->external != 0 && s->prevout >= 0 ) + { + if ( (spentbp= iguana_externalspent(coin,&prevhash,&spent_unspentind,ramchain,bp->hdrsi,s)) != 0 && spentbp->ramchain.H.data != 0 ) + { + if ( spentbp == bp ) + { + char str[65]; + printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",bp->bundleheight+i,spentbp->hdrsi,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); + errs++; + } + if ( now > spentbp->lastprefetch+10 ) + { + //printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,&spentbp->ramchain); + spentbp->lastprefetch = now; + } + spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); + u = &spentU[spent_unspentind]; + if ( (spent_pkind= u->pkind) != 0 && spent_pkind < spentbp->ramchain.H.data->numpkinds ) + { + + if ( (ptr[emit].unspentind= spent_unspentind) != 0 && spentbp->hdrsi < bp->hdrsi ) + { + ptr[emit].hdrsi = spentbp->hdrsi; + ptr[emit].pkind = spent_pkind; + ptr[emit].value = u->value; + ptr[emit].bundlei = i; + //ptr[emit].txi = j; + //printf("(%d u%d).%d ",spentbp->hdrsi,unspentind,emit); + emit++; + } + else + { + printf("spendvectors: null unspentind for spendind.%d hdrsi.%d [%d]\n",spendind,spentbp->hdrsi,bp->hdrsi); + errs++; + } + } + else + { + errs++; + printf("spendvectors: unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); + break; + } + } + } } } } - if ( numtxid != bp->ramchain.H.data->numtxids ) + if ( txidind != bp->ramchain.H.data->numtxids ) + { + printf("numtxid.%d != bp numtxids %d\n",txidind,bp->ramchain.H.data->numtxids); + errs++; + } + if ( spendind != bp->ramchain.H.data->numspends ) { - printf("numtxid.%d != bp %d\n",numtxid,bp->ramchain.H.data->numtxids); + printf("spendind.%d != bp numspends %d\n",spendind,bp->ramchain.H.data->numspends); errs++; } if ( errs == 0 && emit >= 0 ) { emitted += emit; memset(zero.bytes,0,sizeof(zero)); - sprintf(dirname,"DB/%s/spends",coin->symbol); + sprintf(fname,"DB/%s/spends/%s.%d",coin->symbol,bits256_str(str,bp->hashes[0]),bp->bundleheight); vcalc_sha256(0,sha256.bytes,(void *)ptr,(int32_t)(sizeof(*ptr) * emit)); - if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) + if ( (fp= fopen(fname,"wb")) != 0 ) { - if ( (fp= fopen(fname,"wb")) != 0 ) + if ( fwrite(sha256.bytes,1,sizeof(sha256),fp) != sizeof(sha256) ) + printf("error writing hash for %ld -> (%s)\n",sizeof(*ptr) * emit,fname); + else if ( fwrite(ptr,sizeof(*ptr),emit,fp) != emit ) + printf("error writing %d of %d -> (%s)\n",emit,n,fname); + else retval = 0; + fsize = ftell(fp); + fclose(fp); + if ( iguana_Xspendmap(coin,ramchain,bp) < 0 ) { - if ( fwrite(sha256.bytes,1,sizeof(sha256),fp) != sizeof(sha256) ) - printf("error writing hash for %ld -> (%s)\n",sizeof(*ptr) * emit,fname); - else if ( fwrite(ptr,sizeof(*ptr),emit,fp) != emit ) - printf("error writing %d of %d -> (%s)\n",emit,n,fname); - else retval = 0; - fsize = ftell(fp); - fclose(fp); - if ( iguana_Xspendmap(coin,ramchain,bp) < 0 ) - { - printf("error mapping Xspendmap.(%s)\n",fname); - retval = -1; - } - //int32_t i; for (i=0; inumXspends; i++) - // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); - //printf("filesize %ld Xspendptr.%p %p num.%d\n",fsize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); - } else printf("Error creating.(%s)\n",fname); - } else printf("error getting utxo fname\n"); + printf("error mapping Xspendmap.(%s)\n",fname); + retval = -1; + } + //int32_t i; for (i=0; inumXspends; i++) + // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); + //printf("filesize %ld Xspendptr.%p %p num.%d\n",fsize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); + } else printf("Error creating.(%s)\n",fname); } if ( ptr != 0 ) myfree(ptr,sizeof(*ptr) * n); - printf("utxo %d spendinds.[%d] errs.%d [%.2f%%] emitted.%d %s of %d | ",spendind,bp->hdrsi,errs,100.*(double)emitted/(total+1),emit,mbstr(str,sizeof(*ptr) * emit),n); + printf("utxo %d spendinds.[%d] errs.%d [%.2f%%] emitted.%d %s of %d\n",spendind,bp->hdrsi,errs,100.*(double)emitted/(total+1),emit,mbstr(str,sizeof(*ptr) * emit),n); + if ( errs != 0 ) + exit(-1); return(-errs); } -int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) +int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) { - int32_t spendind,n,errs=0,emit=0; uint32_t unspentind,pkind,txidind; struct iguana_account *A2; - struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; - struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; int32_t hdrsi; - uint32_t numtxid,now,h,refheight; struct iguana_utxo *utxo; + uint32_t spent_unspentind,spent_pkind,txidind,h,i,j,k,now; uint64_t spent_value; + struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; + struct iguana_spendvector *spend; struct iguana_unspent *spentU,*u; + struct iguana_txid *T; struct iguana_blockRO *B; struct iguana_bundle *spentbp; + int32_t spent_hdrsi,spendind,n,errs=0,emit=0; struct iguana_spend *S,*s; ramchain = &bp->ramchain; - //printf("BALANCEGEN.%d\n",bp->bundleheight); - if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) - return(0); - S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); - nextT = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); - numtxid = 1; - refheight = bp->bundleheight; + if ( (rdata= ramchain->H.data) == 0 || (n= ramchain->H.data->numspends) < 1 ) + return(-1); + S = (void *)(long)((long)rdata + rdata->Soffset); + B = (void *)(long)((long)rdata + rdata->Boffset); + T = (void *)(long)((long)rdata + rdata->Toffset); if ( ramchain->Xspendinds == 0 ) { printf("iguana_balancegen.%d: no Xspendinds[%d]\n",bp->hdrsi,ramchain->numXspends); - return(0); + return(-1); } - for (spendind=ramchain->H.data->firsti; spendindbundleheight,bp->hdrsi); + txidind = spendind = rdata->firsti; + for (i=0; in; i++) { - if ( spendind == nextT[numtxid].firstvin ) + //printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); + if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin ) { - refheight = bp->bundleheight + numtxid; - //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); - numtxid++; + printf("balancegen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin errs.%d\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i,errs); + return(-1); } - s = &S[spendind]; - u = 0; - unspentind = 0; - hdrsi = -1; - if ( s->external != 0 && s->prevout >= 0 ) + for (j=0; j= ramchain->numXspends ) - errs++; - else + now = (uint32_t)time(NULL); + if ( txidind != T[txidind].txidind || spendind != T[txidind].firstvin ) + { + printf("balancegen: txidind %u != %u T[txidind].firsttxidind || spendind %u != %u T[txidind].firstvin errs.%d\n",txidind,T[txidind].txidind,spendind,T[txidind].firstvin,errs); + return(-1); + } + //printf("txidind.%d txi.%d numvins.%d spendind.%d\n",txidind,j,T[txidind].numvins,spendind); + for (k=0; kXspendinds[emit].height; - unspentind = ramchain->Xspendinds[emit].ind; - if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi <= bp->hdrsi ) - spentbp = coin->bundles[hdrsi]; + s = &S[spendind]; + h = spent_hdrsi = -1; + spent_value = 0; + spent_unspentind = spent_pkind = 0; + if ( s->external != 0 && s->prevout >= 0 ) + { + if ( emit >= ramchain->numXspends ) + errs++; + else + { + spend = &ramchain->Xspendinds[emit]; + spent_value = spend->value; + spent_pkind = spend->pkind; + spent_unspentind = spend->unspentind; + spent_hdrsi = spend->hdrsi; + h = spend->bundlei + (spent_hdrsi * coin->chain->bundlesize); + emit++; + } + } + else if ( s->prevout >= 0 ) + { + h = bp->bundleheight + i; + spent_hdrsi = bp->hdrsi; + if ( s->spendtxidind != 0 && s->spendtxidind < rdata->numtxids ) + { + spent_unspentind = T[s->spendtxidind].firstvout + s->prevout; + spentU = (void *)(long)((long)rdata + rdata->Uoffset); + u = &spentU[spent_unspentind]; + if ( (spent_pkind= u->pkind) != 0 && spent_pkind < rdata->numpkinds ) + spent_value = u->value; + //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); + } + else + { + printf("iguana_balancegen [%d] txidind overflow %u vs %u\n",bp->hdrsi,s->spendtxidind,rdata->numtxids); + errs++; + } + } + else continue; + if ( spent_unspentind > 0 && spent_pkind > 0 && (spentbp= coin->bundles[spent_hdrsi]) != 0 ) + { + if ( iguana_volatileupdate(coin,0,&spentbp->ramchain,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,h) < 0 ) + errs++; + } else { - printf("iguana_balancegen[%d] s.%d illegal hdrsi.%d emit.%d\n",bp->hdrsi,spendind,hdrsi,emit); errs++; + printf("iguana_balancegen: error with unspentind.%d [%d]\n",spent_unspentind,spent_hdrsi); } - //printf("%d of %d: [%d] X spendind.%d -> (%d u%d)\n",emit,ramchain->numXspends,bp->hdrsi,spendind,hdrsi,unspentind); - emit++; } } - else if ( s->prevout >= 0 ) + } + if ( txidind != bp->ramchain.H.data->numtxids ) + { + printf("numtxid.%d != bp numtxids %d\n",txidind,bp->ramchain.H.data->numtxids); + errs++; + } + if ( spendind != bp->ramchain.H.data->numspends ) + { + printf("spendind.%d != bp numspends %d\n",spendind,bp->ramchain.H.data->numspends); + errs++; + } + if ( emit != ramchain->numXspends ) + { + printf("iguana_balancegen: emit %d != %d ramchain->numXspends\n",emit,ramchain->numXspends); + errs++; + } + printf(">>>>>>>> balances.%d done errs.%d spendind.%d\n",bp->hdrsi,errs,n); + return(-errs); +} + +int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *RTramchain,int32_t bundlei) +{ + struct iguana_txid *T; int32_t height,spendind,txidind,j,k; bits256 prevhash; + struct iguana_bundle *spentbp; struct iguana_unspent *spentU,*u; + struct iguana_ramchaindata *RTdata,*rdata; + uint32_t spent_unspentind,now; struct iguana_blockRO *B; struct iguana_spend *S,*s; + if ( (RTdata= RTramchain->H.data) == 0 || RTdata->numspends < 1 ) + { + printf("iguana_RTutxo null data or no spends %p\n",RTramchain->H.data); + return(-1); + } + B = (void *)(long)((long)RTdata + RTdata->Boffset); + S = (void *)(long)((long)RTdata + RTdata->Soffset); + T = (void *)(long)((long)RTdata + RTdata->Toffset); + txidind = B[bundlei].firsttxidind; + spendind = B[bundlei].firstvin; + height = bp->bundleheight + bundlei; + now = (uint32_t)time(NULL); + iguana_ramchain_prefetch(coin,RTramchain); + for (j=0; jhdrsi,bundlei,B[bundlei].txn_count); + if ( txidind != T[txidind].txidind || spendind != T[txidind].firstvin ) + { + printf("RTutxogen: txidind %u != %u nextT[txidind].firsttxidind || spendind %u != %u nextT[txidind].firstvin\n",txidind,T[txidind].txidind,spendind,T[txidind].firstvin); + return(-1); + } + for (k=0; khdrsi; - h = refheight; - if ( (txidind= s->spendtxidind) != 0 && txidind < spentbp->ramchain.H.data->numtxids ) + s = &S[spendind]; + if ( s->external != 0 && s->prevout >= 0 ) { - T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); - unspentind = T[txidind].firstvout + s->prevout; - if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) + if ( (spentbp= iguana_externalspent(coin,&prevhash,&spent_unspentind,RTramchain,bp->hdrsi,s)) == 0 || spent_unspentind == 0 || spent_unspentind >= spentbp->ramchain.H.data->numunspents || spentbp->hdrsi < 0 || spentbp->hdrsi >= bp->hdrsi || spentbp == bp ) { - printf("iguana_balancegen unspentind overflow %u vs %u\n",unspentind,spentbp->ramchain.H.data->numunspents); - errs++; + char str[65]; + printf("RTutxo: unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",height,spentbp->hdrsi,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); + return(-1); + } + rdata = spentbp->ramchain.H.data; + if ( now > spentbp->lastprefetch+1 ) + { + //printf("RT prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,&spentbp->ramchain); + spentbp->lastprefetch = now; } - //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); + } + else if ( s->prevout >= 0 ) + { + spentbp = bp; + rdata = RTramchain->H.data; + if ( s->spendtxidind != 0 && s->spendtxidind < RTdata->numtxids ) + { + spent_unspentind = T[s->spendtxidind].firstvout + s->prevout; + //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); + } + else + { + printf("RTutxo txidind overflow %u vs %d\n",s->spendtxidind,RTdata->numtxids); + return(-1); + } + } + else continue; // coinbase always already spent + if ( spentbp != 0 && rdata != 0 && spent_unspentind != 0 && spent_unspentind < rdata->numunspents ) + { + spentU = (void *)(long)((long)rdata + rdata->Uoffset); + u = &spentU[spent_unspentind]; + if ( iguana_volatileupdate(coin,1,spentbp == bp ? RTramchain : &spentbp->ramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height) < 0 ) + return(-1); } else { - printf("iguana_balancegen txidind overflow %u vs %u\n",txidind,spentbp->ramchain.H.data->numtxids); - errs++; + printf("RTutxo error spentbp.%p u.%u vs %d\n",spentbp,spent_unspentind,rdata->numunspents); + return(-1); } - //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); } - else continue; - now = (uint32_t)time(NULL); - if ( unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) + } + return(0); +} + +void iguana_purgevolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + if ( ramchain->allocatedA != 0 && ramchain->A != 0 ) + free(ramchain->A); + ramchain->A = 0; + if ( ramchain->allocatedU != 0 && ramchain->Uextras != 0 ) + free(ramchain->Uextras); + ramchain->Uextras = 0; + if ( ramchain->debitsfileptr != 0 ) + { + munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); + ramchain->debitsfileptr = 0; + ramchain->debitsfilesize = 0; + } + if ( ramchain->lastspendsfileptr != 0 ) + { + munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); + ramchain->lastspendsfileptr = 0; + ramchain->lastspendsfilesize = 0; + } +} + +int32_t iguana_mapvolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + int32_t iter,numhdrsi,err = -1; char fname[1024]; bits256 balancehash; + for (iter=0; iter<2; iter++) + { + sprintf(fname,"DB/%s%s/accounts/debits.%d",iter==0?"ro/":"",coin->symbol,ramchain->H.data->height); + if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->A) * ramchain->H.data->numpkinds ) { - if ( spentbp->ramchain.Uextras == 0 ) + ramchain->from_roA = (iter == 0); + numhdrsi = *(int32_t *)ramchain->debitsfileptr; + memcpy(balancehash.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); + if ( coin->balanceswritten == 0 ) { - spentbp->ramchain.Uextras = calloc(sizeof(*spentbp->ramchain.Uextras),spentbp->ramchain.H.data->numunspents + 16); + coin->balanceswritten = numhdrsi; + coin->balancehash = balancehash; } - if ( spentbp->ramchain.A == 0 ) + if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) + { + ramchain->A = (void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + sizeof(bits256)); + sprintf(fname,"DB/%s%s/accounts/lastspends.%d",iter==0?"ro/":"",coin->symbol,ramchain->H.data->height); + if ( (ramchain->lastspendsfileptr= OS_mapfile(fname,&ramchain->lastspendsfilesize,0)) != 0 && ramchain->lastspendsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents ) + { + numhdrsi = *(int32_t *)ramchain->lastspendsfileptr; + memcpy(balancehash.bytes,(void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); + if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) + { + ramchain->Uextras = (void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + sizeof(bits256)); + ramchain->from_roU = (iter == 0); + err = 0; + } else printf("ramchain map error2 balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + } else printf("ramchain map error3 %s\n",fname); + } else printf("ramchain map error balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + } + if ( err == 0 ) + { + //printf("mapped extra.%s\n",fname); + break; + } + iguana_purgevolatiles(coin,ramchain); + } + return(err); +} + +void iguana_allocvolatile(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + if ( ramchain != 0 && ramchain->H.data != 0 ) + { + if ( ramchain->allocatedA == 0 ) + { + ramchain->A = calloc(sizeof(*ramchain->A),ramchain->H.data->numpkinds + 16); + ramchain->allocatedA = sizeof(*ramchain->A) * ramchain->H.data->numpkinds; + } + if ( ramchain->allocatedU == 0 ) + { + ramchain->Uextras = calloc(sizeof(*ramchain->Uextras),ramchain->H.data->numunspents + 16); + ramchain->allocatedU = sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents; + } + if ( ramchain->debitsfileptr != 0 ) + { + memcpy(ramchain->A,(void *)((long)ramchain->debitsfileptr + sizeof(int32_t) + sizeof(bits256)),sizeof(*ramchain->A) * ramchain->H.data->numpkinds); + munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); + ramchain->debitsfileptr = 0; + ramchain->debitsfilesize = 0; + } + if ( ramchain->lastspendsfileptr != 0 ) + { + memcpy(ramchain->Uextras,(void *)((long)ramchain->lastspendsfileptr + sizeof(int32_t) + sizeof(bits256)),sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); + munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); + ramchain->lastspendsfileptr = 0; + ramchain->lastspendsfilesize = 0; + } + } else printf("illegal ramchain.%p\n",ramchain); +} + +void iguana_truncatebalances(struct iguana_info *coin) +{ + int32_t i; struct iguana_bundle *bp; + for (i=0; ibalanceswritten; i++) + { + if ( (bp= coin->bundles[i]) != 0 ) + { + bp->balancefinish = 0; + iguana_purgevolatiles(coin,&bp->ramchain); + } + } + coin->balanceswritten = 0; +} + +int32_t iguana_volatileinit(struct iguana_info *coin) +{ + bits256 balancehash; struct iguana_utxo *Uptr; struct iguana_account *Aptr; + struct sha256_vstate vstate; int32_t i,from_ro,numpkinds,numunspents; struct iguana_bundle *bp; + uint32_t crc,filecrc; FILE *fp; char crcfname[512],str[65],str2[65],buf[2048]; + from_ro = 1; + for (i=0; ibalanceswritten; i++) + { + if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish <= 1 || bp->utxofinish <= 1 ) + { + printf("hdrsi.[%d] emitfinish.%u utxofinish.%u\n",i,bp->emitfinish,bp->utxofinish); + break; + } + if ( bp->ramchain.from_ro == 0 || bp->ramchain.from_roX == 0 || bp->ramchain.from_roA == 0 || bp->ramchain.from_roU == 0 ) + from_ro = 0; + } + if ( i != coin->balanceswritten ) + { + printf("TRUNCATE balances written.%d -> %d\n",coin->balanceswritten,i); + iguana_truncatebalances(coin); + } + else + { + vupdate_sha256(balancehash.bytes,&vstate,0,0); + filecrc = 0; + sprintf(crcfname,"DB/%s/balancecrc.%d",coin->symbol,coin->balanceswritten); + if ( (fp= fopen(crcfname,"rb")) != 0 ) + { + if ( fread(&filecrc,1,sizeof(filecrc),fp) != sizeof(filecrc) ) + filecrc = 0; + else if ( fread(&balancehash,1,sizeof(balancehash),fp) != sizeof(balancehash) ) + filecrc = 0; + else if ( memcmp(&balancehash,&coin->balancehash,sizeof(balancehash)) != 0 ) + filecrc = 0; + fclose(fp); + } + if ( filecrc != 0 ) + printf("have filecrc.%08x for %s milli.%.0f\n",filecrc,bits256_str(str,balancehash),OS_milliseconds()); + if ( from_ro == 0 ) + { + if ( filecrc == 0 ) + vupdate_sha256(balancehash.bytes,&vstate,0,0); + for (i=crc=0; ibalanceswritten; i++) { - spentbp->ramchain.A = calloc(sizeof(*spentbp->ramchain.A),spentbp->ramchain.H.data->numpkinds + 16); + numpkinds = numunspents = 0; + Aptr = 0, Uptr = 0; + if ( (bp= coin->bundles[i]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) + { + if ( filecrc == 0 ) + { + vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); + vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); + } + crc = calc_crc32(crc,(void *)Aptr,(int32_t)(sizeof(*Aptr) * numpkinds)); + crc = calc_crc32(crc,(void *)Uptr,(int32_t)(sizeof(*Uptr) * numunspents)); + } else printf("missing hdrs.[%d] data.%p num.(%u %d) %p %p\n",i,bp->ramchain.H.data,numpkinds,numunspents,Aptr,Uptr); } - if ( spentbp->ramchain.Uextras == 0 || (A2= spentbp->ramchain.A) == 0 ) + } else crc = filecrc; + printf("millis %.0f from_ro.%d written.%d crc.%08x/%08x balancehash.(%s) vs (%s)\n",OS_milliseconds(),from_ro,coin->balanceswritten,crc,filecrc,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); + if ( (filecrc != 0 && filecrc != crc) || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 ) + { + printf("balancehash or crc mismatch\n"); + iguana_truncatebalances(coin); + } + else + { + printf("MATCHED balancehash numhdrsi.%d crc.%08x\n",coin->balanceswritten,crc); + if ( (fp= fopen(crcfname,"wb")) != 0 ) { - printf("null ptrs %p %p\n",spentbp->ramchain.Uextras,spentbp->ramchain.A); - errs++; + if ( fwrite(&crc,1,sizeof(crc),fp) != sizeof(crc) || fwrite(&balancehash,1,sizeof(balancehash),fp) != sizeof(balancehash) ) + printf("error writing.(%s)\n",crcfname); + fclose(fp); } - else + } + } + coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; + iguana_bundlestats(coin,buf); + return(coin->balanceswritten); +} + +void iguana_RTramchainfree(struct iguana_info *coin) +{ + iguana_utxoupdate(coin,-1,0,0,0,0,-1); // free hashtables + coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; + iguana_ramchain_free(coin,&coin->RTramchain,1); +} + +void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) +{ + uint32_t i,changed = 0; struct iguana_ramchain *dest = &coin->RTramchain; struct iguana_blockRO *B; + if ( dest->H.data != 0 ) + { + i = 0; + if ( coin->RTheight != bp->bundleheight + dest->H.data->numblocks ) + changed++; + else + { + B = (void *)(long)((long)dest->H.data + dest->H.data->Boffset); + for (i=0; iH.data->numblocks; i++) + if ( bits256_cmp(B[i].hash2,bp->hashes[i]) != 0 ) + { + char str[65],str2[65]; printf("mismatched hash2 at %d %s vs %s\n",bp->bundleheight+i,bits256_str(str,B[i].hash2),bits256_str(str2,bp->hashes[i])); + changed++; + break; + } + } + if ( changed != 0 ) + { + printf("RTramchain changed %d bundlei.%d | coin->RTheight %d != %d bp->bundleheight + %d coin->RTramchain.H.data->numblocks\n",coin->RTheight,i,coin->RTheight,bp->bundleheight,dest->H.data->numblocks); + //coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; + iguana_RTramchainfree(coin); + } + } + if ( coin->RTramchain.H.data == 0 ) + { + //printf("ALLOC RTramchain\n"); + iguana_ramchainopen(coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); + dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; + dest->externalind = dest->H.stacksize = 0; + dest->H.scriptoffset = 1; + } +} + +int32_t iguana_realtime_update(struct iguana_info *coin) +{ + struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t bundlei,err,n,flag=0; + struct iguana_block *block=0; struct iguana_blockRO *B; struct iguana_ramchain *dest=0,blockR; + long filesize; void *ptr; char str[65],fname[1024]; + if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi == coin->balanceswritten && coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n ) + { + iguana_RTramchainalloc(coin,bp); + while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height) + { + dest = &coin->RTramchain; + B = (void *)(long)((long)rdata + rdata->Boffset); + bundlei = (coin->RTheight % coin->chain->bundlesize); + if ( (block= bp->blocks[bundlei]) != 0 && bits256_nonz(block->RO.prev_block) != 0 ) { - spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); - u = &spentU[unspentind]; - if ( (pkind= u->pkind) != 0 && pkind < spentbp->ramchain.H.data->numpkinds ) + iguana_blocksetcounters(coin,block,dest); + //coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; + B[bundlei] = block->RO; + if ( (ptr= iguana_bundlefile(coin,fname,&filesize,bp,bundlei)) != 0 ) { - utxo = &spentbp->ramchain.Uextras[unspentind]; - if ( utxo->spentflag == 0 ) + if ( iguana_mapchaininit(coin,&blockR,bp,bundlei,block,ptr,filesize) == 0 ) { - utxo->prevspendind = A2[pkind].lastind; - utxo->spentflag = 1; - utxo->height = h; - A2[pkind].total += u->value; - A2[pkind].lastind = spendind; - spentbp->dirty = now; + if ( (err= iguana_ramchain_iterate(coin,dest,&blockR,bp)) != 0 || bits256_cmp(blockR.H.data->firsthash2,block->RO.hash2) != 0 ) + { + printf("ERROR [%d:%d] %s vs ",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); + printf("mapped.%s\n",bits256_str(str,blockR.H.data->firsthash2)); + if ( (block= bp->blocks[bundlei]) != 0 ) + { + block->queued = 0; + block->fpipbits = 0; + bp->issued[bundlei] = 0; + block->issued = 0; + OS_removefile(fname,0); + } + iguana_RTramchainfree(coin); + return(-1); + } + flag++; + if ( iguana_RTutxo(coin,bp,dest,bundlei) < 0 ) + { + printf("RTutxo error -> RTramchainfree\n"); + iguana_RTramchainfree(coin); + return(-1); + } + coin->RTheight++; + printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); + coin->RTramchain.H.data->numblocks = bundlei + 1; } else { - errs++; - printf("iguana_balancegen: pkind.%d double spend of hdrsi.%d unspentind.%d prev.%u spentflag.%d height.%d\n",pkind,spentbp->hdrsi,unspentind,utxo->prevspendind,utxo->spentflag,utxo->height); - getchar(); + printf("error mapchaininit\n"); + iguana_ramchain_free(coin,&blockR,1); + return(-1); } } else { - errs++; - printf("iguana_balancegen: pkind overflow %d vs %d\n",pkind,spentbp->ramchain.H.data->numpkinds); + //printf("no fileptr for RTheight.%d\n",coin->RTheight); + return(-1); } } + else + { + if ( block == 0 ) + printf("no blockptr.%p for RTheight.%d\n",block,coin->RTheight); + else + { + block->queued = 0; + block->fpipbits = 0; + bp->issued[bundlei] = 0; + block->issued = 0; + } + return(-1); + } } - else + } + if ( dest != 0 && flag != 0 ) + { + n = 0; + while ( block != 0 ) { - errs++; - printf("iguana_balancegen: error with unspentind.%d vs max.%d\n",unspentind,spentbp->ramchain.H.data->numunspents); + if ( bits256_cmp(iguana_blockhash(coin,coin->RTheight-n-1),block->RO.hash2) != 0 ) + { + printf("blockhash error at %d\n",coin->RTheight-n-1); + break; + } + block = iguana_blockfind(coin,block->RO.prev_block); + n++; + if ( coin->RTgenesis != 0 && n >= bp->n ) + break; } + if ( coin->RTgenesis == 0 && n == coin->RTheight ) + { + printf("RTgenesis verified\n"); + coin->RTgenesis = (uint32_t)time(NULL); + } + printf(">>>> RT.%d:%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,n,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); } - if ( numtxid != bp->ramchain.H.data->numtxids ) + return(0); +} + +int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) +{ + int32_t hdrsi,numpkinds,iter,numhdrsi,numunspents,err; struct iguana_bundle *bp; + char fname[1024],fname2[1024],destfname[1024]; bits256 balancehash; FILE *fp,*fp2; + struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate; + vupdate_sha256(balancehash.bytes,&vstate,0,0); + for (hdrsi=0; hdrsibundlescount; hdrsi++) + if ( (bp= coin->bundles[hdrsi]) == 0 || bp->balancefinish <= 1 || bp->ramchain.H.data == 0 || bp->ramchain.A == 0 || bp->ramchain.Uextras == 0 ) + break; + if ( hdrsi <= coin->balanceswritten || hdrsi < refhdrsi ) + return(0); + numhdrsi = hdrsi; + vupdate_sha256(balancehash.bytes,&vstate,0,0); + for (iter=0; iter<3; iter++) { - printf("iguana_balancegen: numtxid.%d != bp %d\n",numtxid,bp->ramchain.H.data->numtxids); - errs++; + for (hdrsi=0; hdrsibundles[hdrsi]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) + { + sprintf(fname,"accounts/%s/debits.%d",coin->symbol,bp->bundleheight); + sprintf(fname2,"accounts/%s/lastspends.%d",coin->symbol,bp->bundleheight); + if ( iter == 0 ) + { + vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); + vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); + } + else if ( iter == 1 ) + { + if ( (fp= fopen(fname,"wb")) != 0 && (fp2= fopen(fname2,"wb")) != 0 ) + { + err = -1; + if ( fwrite(&numhdrsi,1,sizeof(numhdrsi),fp) == sizeof(numhdrsi) && fwrite(&numhdrsi,1,sizeof(numhdrsi),fp2) == sizeof(numhdrsi) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp) == sizeof(balancehash) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp2) == sizeof(balancehash) ) + { + if ( fwrite(Aptr,sizeof(*Aptr),numpkinds,fp) == numpkinds ) + { + if ( fwrite(Uptr,sizeof(*Uptr),numunspents,fp2) == numunspents ) + { + //bp->dirty = 0; + err = 0; + //free(bp->ramchain.A), bp->ramchain.A = 0; + //free(bp->ramchain.Uextras), bp->ramchain.Uextras = 0; + printf("[%d] of %d saved (%s) and (%s)\n",hdrsi,numhdrsi,fname,fname2); + } + } + } + if ( err != 0 ) + { + printf("balanceflush.%s error iter.%d hdrsi.%d\n",coin->symbol,iter,hdrsi); + fclose(fp); + fclose(fp2); + return(-1); + } + fclose(fp), fclose(fp2); + } + else + { + printf("error opening %s or %s %p\n",fname,fname2,fp); + if ( fp != 0 ) + fclose(fp); + } + } + else if ( iter == 2 ) + { + sprintf(destfname,"DB/%s/accounts/debits.%d",coin->symbol,bp->bundleheight); + if ( OS_copyfile(fname,destfname,1) < 0 ) + { + printf("balances error copying (%s) -> (%s)\n",fname,destfname); + return(-1); + } + sprintf(destfname,"DB/%s/accounts/lastspends.%d",coin->symbol,bp->bundleheight); + if ( OS_copyfile(fname2,destfname,1) < 0 ) + { + printf("balances error copying (%s) -> (%s)\n",fname2,destfname); + return(-1); + } + printf("%s %s\n",fname,destfname); + /*if ( hdrsi > numhdrsi-purgedist && numhdrsi >= purgedist ) + { + sprintf(destfname,"DB/%s/accounts/debits_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); + OS_removefile(destfname,0); + sprintf(destfname,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); + OS_removefile(destfname,0); + }*/ + } + } + else + { + printf("balanceflush iter.%d error loading [%d] Aptr.%p Uptr.%p numpkinds.%u numunspents.%u\n",iter,hdrsi,Aptr,Uptr,numpkinds,numunspents); + return(-1); + } + } } - if ( emit != ramchain->numXspends ) + coin->balancehash = balancehash; + coin->balanceswritten = numhdrsi; + for (hdrsi=0; hdrsibundles[hdrsi]) == 0 ) + { + if ( bp->ramchain.A != 0 ) + { + free(bp->ramchain.A); + bp->ramchain.A = 0; + bp->ramchain.allocatedA = 0; + } + if ( bp->ramchain.Uextras != 0 ) + { + free(bp->ramchain.Uextras); + bp->ramchain.Uextras = 0; + bp->ramchain.allocatedU = 0; + } + if ( iguana_mapvolatiles(coin,&bp->ramchain) != 0 ) + printf("error mapping bundle.[%d]\n",hdrsi); + } + char str[65]; printf("BALANCES WRITTEN for %d bundles %s\n",coin->balanceswritten,bits256_str(str,coin->balancehash)); + coin->balanceswritten = iguana_volatileinit(coin); + iguana_RTramchainfree(coin); + return(coin->balanceswritten); +} + +int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) +{ + uint32_t starttime,j=0,flag = 0; struct iguana_bundle *prevbp; + if ( bp->balancefinish > 1 ) { - printf("iguana_balancegen: emit %d != %d ramchain->numXspends\n",emit,ramchain->numXspends); - errs++; + printf("make sure DB files have this bp.%d\n",bp->hdrsi); + iguana_validateQ(coin,bp); + return(flag); } - printf(">>>>>>>> balances.%d done errs.%d spendind.%d\n",bp->hdrsi,errs,n); - if ( errs == 0 ) - bp->validated = (uint32_t)time(NULL); - return(-errs); + if ( bp != 0 && coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) + { +#ifdef IGUANA_SERIALIZE_BALANCEGEN + for (j=0; jbundlescount-1; j++) + { + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 ) + { + j = -1; + break; + } + } +#endif + if ( j != -1 ) + { + for (j=0; jhdrsi; j++) + { + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish <= 1 ) + { + j = -1; + break; + } + } + } + // printf("B [%d] j.%d u.%u b.%u\n",bp->hdrsi,j,bp->utxofinish,bp->balancefinish); + if ( bp->bundleheight+bp->n < coin->blocks.hwmchain.height && bp->utxofinish > 1 && bp->balancefinish <= 1 && (bp->hdrsi == 0 || bp->hdrsi == j) ) + { + starttime = (uint32_t)time(NULL); + for (j=0; j<=bp->hdrsi; j++) + iguana_allocvolatile(coin,&coin->bundles[j]->ramchain); + if ( iguana_balancegen(coin,bp,startheight,endheight) < 0 ) + { + printf("GENERATE BALANCES ERROR ht.%d\n",bp->bundleheight); + exit(-1); + } + bp->balancefinish = (uint32_t)time(NULL); + printf("GENERATED BALANCES for ht.%d duration %d seconds\n",bp->bundleheight,bp->balancefinish - (uint32_t)starttime); + bp->queued = 0; + iguana_validateQ(coin,bp); + if ( bp->hdrsi >= coin->longestchain/coin->chain->bundlesize-1 && bp->hdrsi >= coin->balanceswritten ) + { + iguana_balanceflush(coin,bp->hdrsi,3); + printf("balanceswritten.%d flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",coin->balanceswritten,bp->hdrsi,coin->longestchain/coin->chain->bundlesize); + } + flag++; + } + else + { + //printf("third case.%d utxo.%u balance.%u prev.%u\n",bp->hdrsi,bp->utxofinish,bp->balancefinish,prevbp!=0?prevbp->utxofinish:-1); + coin->pendbalances--; + iguana_balancesQ(coin,bp); + } + } + return(flag); } int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp) { - bp->validated = (uint32_t)time(NULL); - printf("VALIDATE.%d %u\n",bp->bundleheight,bp->validated); + if ( bp->validated <= 1 ) + { + bp->validated = (uint32_t)time(NULL); + //printf("VALIDATE.%d %u\n",bp->bundleheight,bp->validated); + } return(0); } \ No newline at end of file diff --git a/iguana/main.c b/iguana/main.c index 7e1c479cc..3c86d5496 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -38,15 +38,15 @@ struct iguana_info *Coins[IGUANA_MAXCOINS]; char Userhome[512],GLOBALTMPDIR[512] = "tmp"; int32_t USE_JAY,FIRST_EXTERNAL,IGUANA_disableNXT,Debuglevel; uint32_t prices777_NXTBLOCK,MAX_DEPTH = 100; -queue_t helperQ,jsonQ,finishedQ,bundlesQ,validateQ,emitQ,balancesQ; +queue_t helperQ,jsonQ,finishedQ,bundlesQ,validateQ,emitQ,balancesQ,TerminateQ; struct supernet_info MYINFO,**MYINFOS; static int32_t initflag; int32_t HDRnet,netBLOCKS; cJSON *API_json; #ifdef __linux__ -int32_t IGUANA_NUMHELPERS = 8; +int32_t IGUANA_NUMHELPERS = 3; #else -int32_t IGUANA_NUMHELPERS = 4; +int32_t IGUANA_NUMHELPERS = 3; #endif struct iguana_jsonitem { struct queueitem DL; struct supernet_info *myinfo; uint32_t fallback,expired,allocsize; char **retjsonstrp; char remoteaddr[64]; char jsonstr[]; }; @@ -323,9 +323,28 @@ void sigalarm_func() { printf("\nSIGALRM\n"); signal(SIGALRM,sigalarm_func); } void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func); } #endif +// mksquashfs DB/BTC BTC.squash -b 1048576 -> 19GB? +// mksquashfs DB/BTC BTC.lzo -comp lzo -b 1048576 -> takes a really long time -> 20GB +// mksquashfs DB/BTC BTC.xz -b 1048576 -comp xz -Xdict-size 512K -> takes a long time -> 16GB +// mksquashfs DB/BTC BTC.xz1m -b 1048576 -comp xz -Xdict-size 1024K -> takes a long time -> +/* + mksquashfs DB/BTC BTC.xz -comp xz + mksquashfs DB/BTC BTC.xzs -b 16384 -comp xz -Xdict-size 8K + mksquashfs DB/BTC BTC.xz1m -b 1048576 -comp xz -Xdict-size 1024K + mksquashfs DB/BTC BTC.xz8k -comp xz -Xdict-size 8K +mksquashfs DB/BTC BTC.lzo -comp lzo +mksquashfs DB/BTC BTC.lzo1m -comp lzo -b 1048576 +mksquashfs DB/BTC BTC.squash +mksquashfs DB/BTC BTC.squash1M -b 1048576 + + mksquashfs DB/BTC BTC.xz -comp xz + sudo mount BTC.xz DB/ro/BTC -t squashfs -o loop +*/ + + void mainloop(struct supernet_info *myinfo) { - int32_t i,flag; struct iguana_info *coin; struct iguana_helper *ptr; struct iguana_bundle *bp,*prevbp = 0; + int32_t i,flag; struct iguana_info *coin; struct iguana_helper *ptr; struct iguana_bundle *bp; sleep(3); printf("mainloop\n"); while ( 1 ) @@ -334,39 +353,25 @@ void mainloop(struct supernet_info *myinfo) if ( 1 ) { for (i=0; iactive != 0 && (bp= coin->current) != 0 && coin->started != 0 ) + if ( (coin= Coins[i]) != 0 && coin->active != 0 && (bp= coin->current) != 0 ) { - flag++; - //iguana_bundleissue(coin,bp,bp->n,100); - if ( (ptr= queue_dequeue(&balancesQ,0)) != 0 ) + if ( coin->started != 0 ) { - if ( (bp= ptr->bp) != 0 && ptr->coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) + iguana_realtime_update(coin); + if ( (ptr= queue_dequeue(&balancesQ,0)) != 0 ) { - if ( bp->utxofinish != 0 && bp->balancefinish <= 1 && (bp->hdrsi == 0 || (prevbp != 0 && prevbp->utxofinish != 0)) ) - { - //printf("hdrsi.%d start balances.%d\n",bp->hdrsi,bp->bundleheight); - iguana_balancecalc(ptr->coin,bp); - bp->queued = 0; - } - else - { - //printf("third case.%d utxo.%u balance.%u prev.%u\n",bp->hdrsi,bp->utxofinish,bp->balancefinish,prevbp!=0?prevbp->utxofinish:-1); - coin->pendbalances--; - iguana_balancesQ(coin,bp); - } - //iguana_coinflush(ptr->coin,0); + flag++; + if ( ptr->coin != 0 && (bp= ptr->bp) != 0 ) + iguana_balancecalc(ptr->coin,bp,bp->bundleheight,bp->bundleheight+bp->n-1); + myfree(ptr,ptr->allocsize); } - myfree(ptr,ptr->allocsize); } } } iguana_jsonQ(); + pangea_queues(SuperNET_MYINFO(0)); if ( flag == 0 ) - { - pangea_queues(SuperNET_MYINFO(0)); - usleep(1000000); - } - else usleep(100000); + usleep(100000); } } @@ -1019,7 +1024,7 @@ int maingen(int argc, char** argv) void iguana_main(void *arg) { - cJSON *argjson; int32_t usessl = 0, ismainnet = 1; int32_t i; + cJSON *argjson; int32_t usessl = 0, ismainnet = 1; int32_t i; struct iguana_info *btc,*btcd; struct supernet_info *myinfo; char *tmpstr,*helperargs,*coinargs,helperstr[512]; mycalloc(0,0,0); myinfo = SuperNET_MYINFO(0); @@ -1091,33 +1096,43 @@ void iguana_main(void *arg) OS_ensure_directory("tmp"); OS_ensure_directory("purgeable"); OS_ensure_directory(GLOBALTMPDIR); - iguana_coinadd("BTC",0); - iguana_coinadd("BTCD",0); + btc = iguana_coinadd("BTC",0); + btcd = iguana_coinadd("BTCD",0); + if ( btc == 0 || btcd == 0 ) + { + printf("error adding BTC.%p or BTCD.%p\n",btc,btcd); + exit(-1); + } if ( (tmpstr= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"help\"}"),0)) != 0 ) { if ( (API_json= cJSON_Parse(tmpstr)) != 0 && (API_json= jobj(API_json,"result")) != 0 ) API_json = jobj(API_json,"API"); free(tmpstr); } - if ( IGUANA_NUMHELPERS == 0 ) - IGUANA_NUMHELPERS = 1; - for (i=0; i