From a5eae93dc5ff2f9cd0fbe971a505b1a19a091197 Mon Sep 17 00:00:00 2001 From: Vivek Teega Date: Sat, 26 Jun 2021 13:46:40 +0000 Subject: [PATCH] Added checks to handle bad api responses --- .python-version | 1 + requirements.txt | 16 + tracktokens-smartcontracts.py | 1077 ++++++++++++++++++++++++++++++--- 3 files changed, 1004 insertions(+), 90 deletions(-) create mode 100644 .python-version create mode 100644 requirements.txt diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..a5c4c76 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.9.0 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..18a7146 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,16 @@ +arrow==1.1.0 +bidict==0.21.2 +certifi==2021.5.30 +cffi==1.14.5 +chardet==4.0.0 +greenlet==1.1.0 +idna==2.10 +pycparser==2.20 +python-dateutil==2.8.1 +python-engineio==3.14.2 +python-socketio==4.6.1 +requests==2.25.0 +secp256k1==0.13.2 +six==1.16.0 +SQLAlchemy==1.4.18 +urllib3==1.26.5 diff --git a/tracktokens-smartcontracts.py b/tracktokens-smartcontracts.py index ee3623a..035d40f 100755 --- a/tracktokens-smartcontracts.py +++ b/tracktokens-smartcontracts.py @@ -11,34 +11,869 @@ import requests import socketio from sqlalchemy import create_engine, func from sqlalchemy.orm import sessionmaker - +import time import parsing from config import * +from datetime import datetime +import pdb from models import SystemData, ActiveTable, ConsumedTable, TransferLogs, TransactionHistory, RejectedTransactionHistory, \ Base, ContractStructure, ContractBase, ContractParticipants, SystemBase, ActiveContracts, ContractAddressMapping, \ LatestCacheBase, ContractTransactionHistory, RejectedContractTransactionHistory, TokenContractAssociation +goodblockset = {3387923, +3387978, +3396172, +3396192, +3396199, +3396201, +3396205, +3396206, +3396208, +3429342, +3443480, +3443669, +3443675, +3443677, +3443679, +3443680, +3443682, +3443684, +3443702, +3443718, +3443723, +3443733, +3443764, +3443895, +3444345, +3444499, +3444502, +3444503, +3444505, +3444513, +3444522, +3444595, +3444691, +3444698, +3444732, +3444756, +3444828, +3445284, +3445287, +3445463, +3445501, +3446215, +3446465, +3446877, +3446884, +3446888, +3446943, +3446980, +3447073, +3447257, +3447278, +3454503, +3503146, +3609700, +3935975, +3937128, +3937241, +3937242, +3937338, +3937525, +3939941, +3939999, +3940023, +3941146, +3941147, +3956547, +3961676, +3969778, +3970781, +3981168, +3990334, +4000081, +4000252, +4000341, +4000359, +4000456, +4001475, +4002492, +4008981, +4008986, +4008999, +4009033, +4009096, +4010850, +4010910, +4010919, +4010957, +4010980, +4030789, +4030795, +4034239, +4173382, +4174529, +4176306, +4176341, +4176352, +4176383, +4177433, +4177436, +4177705, +4179318, +4184367, +4184544, +4184706, +4186183, +4190429, +4191992, +4203044, +4204961, +4206876, +4210582, +4212515, +4212538, +4212587, +4212634, +4212648, +4213909, +4213921, +4213939, +4213967, +4221370, +4235291, +4243310, +4243333, +4248901, +4256675, +4256730, +4280238, +4281352, +4291219, +4293808, +4313846, +4313887, +4315165, +4315166, +4315223, +4315314, +4315388, +4315411, +4316891, +4316964, +4317202, +4317879, +4317887, +4317962, +4318675, +4318747, +4318796, +4318799, +4318811, +4318848, +4318881, +4318885, +4318889, +4318908, +4318927, +4318928, +4318942, +4318979, +4318987, +4318992, +4319012, +4319028, +4319426, +4319563, +4320551, +4320553, +4320554, +4320569, +4320575, +4320583, +4321197, +4321248, +4321289, +4322379, +4322494, +4323991, +4324082, +4324099, +4324108, +4324111, +4324160, +4324282, +4324285, +4324286, +4324438, +4324446, +4324450, +4324451, +4324456, +4324459, +4324537, +4324562, +4325899, +4326104, +4326179, +4328292, +4328296, +4328309, +4328402, +4338538, +4338608, +4338622, +4340833, +4341514, +4353757, +4353777, +4353779, +4353808, +4353825, +4355736, +4355799, +4355819, +4356783, +4356788, +4356793, +4356901, +4356933, +4356952, +4356970, +4357082, +4357970, +4358021, +4358201, +4358221, +4358222, +4358307, +4358308, +4358324, +4358344, +4358355, +4358379, +4358391, +4360056, +4360211, +4360576, +4360906, +4360955, +4361030, +4362187, +4362192, +4362213, +4362728, +4363547, +4363668, +4364856, +4364858, +4364868, +4364875, +4364876, +4365014, +4365152, +4365327, +4366550, +4366621, +4366675, +4366700, +4366747, +4368196, +4369662, +4369683, +4369756, +4376861, +4377318, +4378253, +4378295, +4378297, +4384839, +4385456, +4385457, +4385498, +4386139, +4389212, +4390807, +4410901, +4410906, +4410912, +4410940, +4411239, +4411273, +4411288, +4411315, +4411330, +4411339, +4411346, +4411348, +4411350, +4411353, +4411355, +4411661, +4411683, +4411740, +4411742, +4411743, +4411745, +4411746, +4411757, +4413288, +4413289, +4413291, +4413418, +4413420, +4413430, +4413457, +4413465, +4413470, +4413474, +4418348, +4420905, +4420912, +4420920, +4420940, +4420952, +4420958, +4421020, +4421091, +4421093, +4421100, +4421147, +4431335, +4433179, +4433620, +4433637, +4434828, +4434873, +4434888, +4434891, +4434898, +4434903, +4437014, +4437066, +4447198, +4447202, +4447204, +4447261, +4447314, +4448107, +4449169, +4449323, +4449488, +4473417, +4473420, +4473503, +4473517, +4473583, +4473804, +4484210, +4484247, +4508994, +4509004, +4509300, +4509950, +4528359, +4528622, +4541278, +4541295, +4552508, +4552522, +4561033, +4562937, +4576480, +4576482, +4577665, +4577712, +4597585, +4597674, +4598087, +4598090, +4599578, +4599724, +4599771, +4606282, +4608453, +4608750, +4612976, +4621941, +4621968, +4629357, +4629457, +4643323, +4643325, +4643544, +4643635, +4658051, +4658053, +4658163, +4658174, +4658778, +4661954, +4664069, +4664075, +4665838, +4665898, +4674594, +4674633, +4684574, +4684602, +4695346, +4695451, +4695529, +4695552, +3961676, +4323991, +4324562, +4361030, +4362187, +4362192, +4364858, +4364868, +4364875, +4364876} + +goodtxset = {'a74a03ec1e77fa50e0b586b1e9745225ad4f78ce96ca59d6ac025f8057dd095c', +'fdcb3ff273deb2a03c19333d4f4f3a22b1fedd22e17fef576559319c40450f50', +'8425c6d4171f8b1634fa1aa339b59e18ae3a585ed3387749cd2fa30d81e0f95e', +'cde8728abca696af417d2f69dda6f55defdf1f5a4bd4625df768ca863d620fa7', +'9ce989dec4ad8a39ca7461812232514c59a3618c38eb6a590ab1e693b17baf7d', +'8c3559b0ba78d1143d3ab4e30c3611842fc57988751be67d761e5c087a8d07c5', +'3803668250105fca8a90e691e07916ece655611afc07b2c6a01b028f35f59352', +'5c180a2961189dd40d5af35a17fbed7865443f6c4ef263924630d3c815606ee9', +'22330e8b2c98ef0d3dc1b0d7961aaad9b2a7bd5afbb4c71d6d4bf20c02595cce', +'c6eb7adc731a60b2ffa0c48d0d72d33b2ec3a33e666156e729a63b25f6c5cd56', +'7c84e9ac1a3d9a81868ca801966c75c4ab261bbc2d0e07050c0f25275cf8a5e1', +'d8436c30c3493dcf723672d337093bbe9466afa88235051c7981c39fa30c1326', +'b463b2b447433b7044bdd3022e271db02b30a3307f25e9c13e18eab1bd681d93', +'cf6de70c9e9e3d45d37bc6e4112851655d82dbd5aef48aedcee466fe4799b950', +'26f08763cd177e2d55080041637527a7769eb3507b023a25bc9edbe8649c2fe2', +'3faa8479657839e6ff9869b49fe5b20441e45e780403c3ab7e33eb70787a785d', +'511f16a69c5f62ad1cce70a2f9bfba133589e3ddc560d406c4fbf3920eae8469', +'e92bf6a8bddf177a5e2d793fa86c7ad059c89157f683f90f02b3590c0e4282c5', +'21976fe4a9a99eb31bd18a496328f7cb91bd4f708bb848771fd638949a5eaba3', +'d8a8b87bd2dd98ac3e5a6996f7bbb30612ecf13756c0f860968c2cb7c8cf01e5', +'dd050ac2ec951eaad4ee897c8348b5a9314a6e7d13debbc319757ec121c5a013', +'dfbc183b45762d7db565eeb0eddce74232acbc8a2c00a68a6ef628c16bb95a93', +'bb6cef5e9612363ed263291e8d3b39533661b3ba1b3ce8c2e9500158124266b8', +'edcd710fa6176cee9c738188a053967ffb4c5dca1a1aa721bee7e22b7f3b7e11', +'dd5512594a0402b914e8d852c918a3b0017e888deea1324512c62f62420a27e0', +'78f6e1dbb2eb8de746395d5c35b47ab91f51076bf3a134afa5fe5b0a44eba5e0', +'d07676c59c90b2363db301af4158d7f384dc0d6e84bb0619639ac358e6f311f1', +'38db5c9c78e6b6c97e622cc1576ebf3b824280f728c157beb56b974d5d802fa7', +'259974b79c94bba0481ad5e3b2f468380df9ac31da7dfdd0da8c3af78bcea561', +'4258e8a7530d4d1e3f1d7524cc927d0c9c335a779a032bbb2d83725680a47ee9', +'21b0b9564ae62d32eed3c9911686c20dea24e1a94c255d7b3de4ecaa720e3d17', +'5e67fee05ed5f6598a85e8fb12e207183bc4441c8f81d54b89ce6bfd196c5fdf', +'eec02efef5a505e141f5551604d401a872e33837edfcbb7e5895a9951c50aa2a', +'97b051261a91dfb4b9d591c44d9ab6192efc2f82d85777f5bf33861952d30cb4', +'3e52f39f785191b693d99859a9823eed281c2ff85669803ef85b55ea924bf790', +'3b8c7d37e16a2f7446411feebe9d141fda6edd4886998033bb3405a08c6026a7', +'0727f232cee6f4c1e10f7b281c8c5c7bb2e90c2c0fc50c8b1160f383840a8ae5', +'0623bea90559e1bb59f4134f6164544ef305fbeaa792e51f09e03706cfe35b79', +'67783a84997fd6b6099267afd158494a971c3aea6ff6856583d778ff5bcc2a0c', +'441c222e9953c6e4278e38362c691835a3c7b6f09f036bf6918b619d0e16cd3c', +'3c0c391d1ec5db8c6636996b6479c25a4a939fb7e9f14d899d41431c5d0a6aad', +'d5e61452a5fc98cac6a0c2c8eb5dc45c345513f2bb27240d66ef3d47a11c46bc', +'3a53a7b61f0ff1c09a25f2ffcb3a97ae0ec0e3b0eccb5e82fec4966dbc0eddcf', +'a433e8f2e7d332cd9574d7325b33720c75f459870d5e060b506a7c7c17650b37', +'2cbc28088cfb983b9b8fd7ec7ee5abcac5cdef07e706413d4094c2caa7020753', +'7edcc427a565a458ae81dcc9a9717d2592120bedd632a17d4ca3fa863e08ca81', +'27ee5479706aba9d37eb458e1a51657b418dc1c9574ed37af763d7d7d7178937', +'f38996915cd00f7bb6ab33ca522168739e4af41ac718ec77b9e7974687f48ec6', +'4db4f56b711720b1769a70d834ef3138b599143d0dcf82c1d3e22e44201cc1b4', +'ad50d8bffe7214473b6f8f454f55749d23a26ab3fc854d63e1ccc808045d98ba', +'5a36fce4646358c751b5403ec5c7465f1b11c8dca6d86e8a9cd4e26184e07b1a', +'3520cda2de65249f7629683c4b8f3efb15479076fe9521250aba2f1abe3f2ce9', +'b57cf412c8cb16e473d04bae44214705c64d2c25146be22695bf1ac36e166ee0', +'ebc99f41c4ccaea32bd9dbc251515838ba47660b7422c7cae39ee3e2ae0107fe', +'e6338071b4247003e16aae50e2696d42f42df116b928122bd94c3c718fbd70bc', +'cf54e0e1b12065ad5ac307400e19b9097f2759f4ef003753e0938eb6c1c36f00', +'ebc015c8c57acdca1020863537eaa25cd00c9ff71c4dc3975b3d4104aa456488', +'b2b4e8bb8cb463e0295f9b639c29aae443eb8e7911551220e7dd45648a4e17c6', +'0e6ec23a1755217b64a6bae24ac14a326a427bcea88c9e4a25a6a89ab6b5e1f6', +'55f144c92556075e6980de0febf5ab41ebf34af4b15eb60fa115384d2507c460', +'af9ca8eb285437a637ddc03cb25e06f15ac650b9f4b8529205380410b11697b1', +'a59a7a3f24d374679747256790908e9eec841a2220e51e479f545122e2181fdb', +'16a3a51868c0e4461958fbd725dca6c2c8d8e9ffedc52a948fea21f4e6ecbf55', +'dec6a4cf1d2ecfd1b36eae0139b8e4fe6307a44af1100f805511860d43508e48', +'f4bea61cc8831a51945fdd240ed3bc198ef3205f4dd409d13d3a36f050a808a0', +'44e17058bb67046e391027d0695cd2e494242406d0b7cec0748645ecaeb97ec1', +'cb36f02e2eb97984a5de6a22123e989ba08dcb13d8c38b101f743dc3200d7490', +'322f60f380573876b5391e77b1296640d97de56d6efcb21f83d6d010e0820165', +'ba8e3784503f5b728764ca7853fb3f07efdd68a86152b126ce8a9ccc0a85f30c', +'ac6e826fb63a62b17f4603202c2ba43cd20aa9e362ed5f7419b71844ecaadc65', +'1e6de7e90286a211335e3fbcab1022c3561d57ffcfe4036a556fa4c58b032ec0', +'cd4539baedd99a5aaa743a2ed2babc55d2d0042cb95d71761f54e918571a57ee', +'6635af4bf7b82f280a57b9696227e79280b17442ad01a2e0902b513f1ef7c017', +'d219431684852035ac19137bda6a1904461d11fc8d3a66aff3fa21139f4ffde0', +'7e4b1e283602645584b24321417dad922bb8f65b3b983c924a047e22b9ef1c8a', +'55acaa10d9cdb37636b2b5f97054fc6a10ceb1cce310009b2f9ff5e8bb274e84', +'13e8242ee6c8c90a57e902051ce38f3c87376a6672b5be132d931363ecc4ca75', +'3a9118d83177f6e9fb8d46ee97bf1e1390cac2ba24ce1e3982086c910053ade0', +'e6f3effa2b1d885e1bacec3e7ff8256c4b55b4e0bda0514508ba4fc44ce13250', +'074acad64d28f63746616ffe39dd9e1b03c56b80809bf35b02b545f9907564ae', +'01f560d06ead33b2dabba9b9fdb44ab9ff693e63c0033bb422c991a4ccaa3a9a', +'46c5734b45d45276b69364ffac6cceb789ea667853760750be1875847d226f37', +'a1f6f8834ec597b23041c44761c93af3f595941dd23eac1357f80c886c601a8f', +'4476e804db749a21d5d5ac809a487b4f31b9f4f561531879e4b507abafa18953', +'65c1a4cb0cfc2fe51107abcb77277f1ab0e16f985c78369599d98f684fb45144', +'3f71fd1649ee36cf66ffcab38bc59dc18aab2995d37ae1e3dcafe9f63598c4bb', +'61bf9bfb99417054862fcd5da7cfc8c68dcc477272ecd3e821fa07bc7d2e7a70', +'535c996c16aedb8df875dcf48e38242e79b22784a9297d663bf271644a747951', +'1ab70a9de6a8deeb0ba8f6c4ca015d60659c90953a7c8a1f3215276fe57b1fb2', +'b93810c8ab06676a42907e2b116cf8799e08c4c0f0829d77b1cc9284f308a9f0', +'612ad2b43229a5b02714ac86d8d119269e291872885312269b4d9f98c0bd4ed5', +'c1ab82c2a996103dcdb9895e453b4a8d991a14ffed79505c752ae02ae657076b', +'9bf4006ec5f4f0af4512318dd90cbd24f3af45a6280a444164a67d5af155d85a', +'89e3dc0c351d5554caa013515be89865c128a5424fea363cc6d43b53981a4290', +'911d634423646a12c7a0825b3d2dbabd6a34231835318e546142295300705254', +'fbae58129af3c09590fbf1781d7b8d331e521f8bf8e51cf22d91fecf34d68f79', +'3a2b547fb501a376c0d04fd883c0e0fc8f226413ac175ec9e345eac7611a16fd', +'db5c739bcdb88f6ba8532e66ca344dd517c527a3a38793529b53ae133c917433', +'536bb47cf8cc0499588d25ff4185e92c4edd77610a6aeb92cf551c2f74607af0', +'5783bf578fcf8cb7b193d82d961ac2b82cf3767e578f67326c96373a4feab8f7', +'d0b4e46302d55e5e08369e595df24f58726eedde6004dbd99d04f740b9e41132', +'7a51b3e2301ae30402770284c008a5905e56e534efe6dec9dee93aeb9381905f', +'db4407a6f08f08e8fe375cce5aa72c1ef1dc03522b7bf5dd625230ab18485675', +'951e7e2bf6d42f690acbcb7a0cef8a3c5f58994148c0461bcd8daf417ea8bfda', +'22e7156182f9dd6695a1f23108da144534ac783b42188c84913d99df0c0cfee3', +'ab67fb7852361fcc05e7d5550fe7a30bd1211718dbca5a66ab26892a7650c4e0', +'57caac52230ad49aa6fbb83e6d2fc84f48909ee65197034f6a8064d397066ae9', +'47c41cc4de57abb4e9fa7b1347d14bd62bc7401bfd9dce6caf11ce4b73fd94ec', +'3addd5b84ea121bbf6b4044452a806bd94adfbf35d591932229846509fe616eb', +'466e7827eb7034bdf6a1ebba4c1b385e2faa1dc21e418e66b535dcf5a73d88c7', +'4a2640abbd6921cb7ef8fdc8a6cadd27da44539aa10c5e6ad364432824bea419', +'1fd1e25e703124d294c69c67852cc1fb2017e51f37aa4b733d423badfcf90a52', +'e3ad816a90a4320d74d52324c5c657041ef29219fd7be971f51917e59ececbf8', +'641d218c815f689a461565789920d7b86ecabd1a324611f039450be91b632a4b', +'9818246afc1b90b717bb202259ba9595a82f999e3310f4369c0c50b06c9de15f', +'b8628b077b4c472e4a6ab18a7f99f7006317e7abe909f8dbe43312780cd8b0a0', +'3788c20cc073baff9b9505380d7522f2dfdbedabd31fa1326347be49adbbdcb4', +'e65c8cca158865575529159c023fdd83001fd7492e0a854191f8cbf93475c494', +'d7e160ef8119f91070f3e95426911c927b87a03cf5374d3bd75ceecebd60073b', +'6db604b62b1be5fdfcd3fb51611f7042666060c65a5217deac5c91a9b5b10453', +'e7b24ae11da6590c9d296eaeeb26c080cc97b20c73793ec205b91ed43f3816cc', +'458b8494dccf3cb91aaa49131537b5008f699004fa3ac4157f9e48420bdd9662', +'bacaea9cb7e3bb62d9e54506e038c9daf7850a7342df047858fe1ff48597a3a9', +'41d5913ca22c3ced4c08c6f8637b9e067f2d7758d0d0275dc704e8f8b64b9f7c', +'3be4222924e4ff05a6bc121e069ed51b335ed2f6cb95402593c8a27417c505f0', +'72ecc2b914745cdb0d6421b1422dfbdba96c0256e56d6d4c1d84ece56d0e3e18', +'3620e5beb80ea8e4aded4796072399a8f17fb782e5736c8d5577493ec3794702', +'2ca7477d0425c676d4e28e5b4e1c71f4b12a16ebd840d0595c3937f23c3d70b0', +'12215cf6c84e1137cfca91c2c1db822eb1caacda9befd008c2adb556cadff0f6', +'40fd93136637c31f9772c3f846cb857988fa2ca59a77282ff1c54dc754f95051', +'3d011143188a0a931bfebe76e77c11272bfb543f71286690072423bb376ee872', +'50ee03d685ad9bc06d07b049d041ca523afd46439c631b08cd684bb8b2fd5929', +'5c4ea2a61857a1179e861274ae292ad22d778eba1eb04d5b02b8901461480baf', +'86f157bb40c266caa5b7b6212fab35f32d6d059251e47e799405457bb00720b9', +'cd27fbfec5083a79986aec7d772ba9695fd6c23263c2252a6eb84dafc7fb9ced', +'e51d497ae3961ea7bca697f7347fd7156c17310be5cb9b956e6fcc7438755f57', +'392fdd08ebaed00373cd6496cde779f976a7928f02cd9cfa7aaf96bea619f6e4', +'d3a8cf88f949bb068c9ae6118afb0373a2929713a165ffcd7113be4ec9004945', +'7127bffb2681dadc8090087261676135f2a063923d19f4683816bf3a8061dbee', +'7669a68489ced1aed50ba44d8be50c6c2513481ae27a464d6c29d0df66029b4b', +'1a9077b6b2ad7c13442b0e5751b26b5ad50e64c37eed2d782d10c72b260cb46d', +'59e75e41cd2966a5ce39b8a7bbb1e89ccee203fffaade7b440c216bdb692895e', +'93638c3080f030a1c169680f542fde5c5fbee9f119a2bb78ae6f28fc4616be48', +'0080c6a7155016d55f9717851aa2ad5a9571d3b03fa3ed872095190ca7ab4136', +'260ebd1d7f40c9126466c728d8504c1fb9492bb59f9186adc91c5ac16ca5daf9', +'f4a9131c8af63f8e59c96745019d621d04c24beaeec018a49051890f869e1588', +'8fb08532dfe79c7fa5537ef95a0d1c9c806c134707a05453e62c92c59c45cb0b', +'4cf0bbfe84e73bb22ccbe802a5f90301dbb24573ce707061db0e4c995551fad9', +'5b1b2127115f71e2a10d32da321b5b76b9f6ad0cd6ca1c1dbff454a6e783e826', +'13822b25f5e92870c9fb5a6ad09ebbe0ba3ba2c909a381fc41fcab25e3d2be7f', +'4a26e4bafcd460e38ce082c44ec49725dfe26e5362dd67fc060ff21e273f549d', +'e6b7422316f7ff5d7538a3e48d5860edfabac2d475365addda2f822c45ba56ec', +'7ed1d7e63b852626dd29be2553e9c88566734282220d67703a329660776a1a3a', +'8309340f71736574268497665ab8f31948478988d2f7a9c26014c0ba7fd521fb', +'061c7f252198e284d5993fc1798050f56f27c6b46aaf90fac4df0df326b28e4c', +'ce2685d884fe5c885fb0279e7745dacee38348c5bb8cc629c72bba589943dc3e', +'9d2a9d6f3fff5645eda3e1cdf8df56411d4a92ddf7f6563d745cbd36ac79405c', +'622e602433049439913c9507bc26f45830055f5119b8926e63af6d7f81ce5138', +'60d072af2202693a2467a097b2bc74383508759c36a6fbb94e857538a9e618f7', +'2483f05eade500e24d34f7dc5f1443dca078c2c8c04fd6dd0b87da7c5f19a3e2', +'bec8026fd4a3d606970f37a3c049b9610613637c35eeee15854b8744867b0735', +'092b2ee21b233f81113aa0a0af38879b90b16021ca215b4ec6aa53b070305b49', +'600db50af61adc64812e9866cf789b67535bfa48fba3a82aea023dbb5a6df170', +'78ba189416344f22c50ad5006f5e612115bc903efc97757889fd8d706bb81f5e', +'2dcbb87dae48f4cef02342ac1caa6fe9e293e9ef8b0e109a640430dee8a474ea', +'dd8813ca9b05201b7463a1cf337a177749542eba1cbaa8fb8f7a02185dbf8932', +'ebab14d8926ff9b00a5a5d8f16747fb1008fabf0a91f202adf6d379a77d0318c', +'9219e49b8a402a185dc96bbde1d6e5988b34dca4c7da28c028cbdf0caacb3755', +'2efe394a7af45d0d631b855a44a90a37d0fbf457301e3f02ba70f7dfb069c3e9', +'8992e7200bb05a89f6b6141d82b69d9bf74b30bcc709d06c33b475902ea59e99', +'93779565a4462e6b912deaee052f26b092b11f669dcbabfb6de1b43cedbc1946', +'492d0595a3048bd9742d632e2a2643e22a3e0dff16985ab678a64d5403beb1ee', +'45a24ca98a644b889f65b31e27316bbdf5aeee3d4408ea8ec247235ed044e0a6', +'296002fedfb70ca513bedbd5fe0e72d5ceeca5c9ac633ad1d98879887146a5eb', +'4c7bd839fd63731012feb08f4f219370fe6febf56e4a709c8b8cc1afa3bac65e', +'0a10adf58dfc0a84fa6f093bb933f4bc777001c7add52b60637a18a3779e5d54', +'98981e00f3d5c7be41a8dae6e062d42555f2bd8672e9c9a8dd9375803fd4267a', +'fab5f3e8c9849fc19105f05f28f31d297a04d70ef3d85a6cd147d53bda684c0e', +'2790937711173f0d6e6095308850945408218fd5823345e2b3a2107aa65f4dae', +'ae5fb75ab5b05ea54d6089023e00ae797d09449e7e1b69f8250ebf9bdc02bf4a', +'4f84f7296875f76ab5790e176ce4284e36558e4d46591c26cd66f7daca412ff6', +'bbe2e76c54ed38930a1940988a68abde0c20a313b8d40e29cb0984ac77f9f971', +'45d44e43a04b4025456e2e6f265c5fca05245350e817b79b28fd97e3212f832c', +'172a7646479dcc6482f88e7f8fc5fad88522a4c5aadf72cda35ae84c3f4fe2d6', +'4fa284945a06ee78943203be7833711b6fd22505f87efc7ae334c4897da57c80', +'2795f8838e10ad379a639063c17b72b323f2cb790975198bc8ac0ede416477b5', +'db857c67829c6026e1bbe6dc015db074d14eda24a576b1746781c3bc5d14c0ce', +'9709ed076fef74da5ef153337404d88c25b54b6a657b72c59d8325149ddc93de', +'0dcf380356f6d2d7bcba56930e898b83126048af6020904d6196a81885f95b9c', +'2540e7376a10dd67d07f5cc2423b05a7e1641a5631a03e783701940e820fffc2', +'3975271761b85a03064b115de71fd27b1bcaa226337a35e7f7bc229a055d9c3b', +'c98477c4016c5e5efa9740158747ecc599713304d770dab5841c182bff5aa62d', +'b3b9cb17bc96663a956fadf1a8cd1d09a323eefd1a5c887153a5e05ade95283a', +'7a1fbd32552fb1fa6f30e55e17ac880affbdfba7420ec4153c90801d89dadcbc', +'49b479660361c526944d3bd4edd7babdf04c47e0b9d413a2d42e5bda0554e053', +'25e901bbf4c3a95b499ec6db269c7685c3fafcb2294ad23430ff9a38fa732d6a', +'8827a9b2baf1e4b6bc3a8f8bd987cba04064613aa035a10c8df17c87762dba7d', +'d04fa3810fd0275502d93628c6399d1f6ee1e891f4285a3bb99d3f83cda6211d', +'4266ae72d5ee29b527b283d137f9f7552b926b21aec867158fc8256df08c6b54', +'9776901f56b85ab35f50615603157893daf337bfa3af97d42d9c6d5cbe98c61d', +'50cf0f4dc221c801ca62bf524309249b5dcc9fbaa8621c20d3d152348b3974ac', +'7382fa53b6d64b269fd9b326ec46104cd30480c8e7b193ca441c70b735621a46', +'ef4430106dbfc1bfee425f4a1288fafcedae17636e3e44483ab868b729a7cdb0', +'e16f57915e4fcbc535a0eacb7c46d39decd8594b6092d435e66f85ce4091b600', +'adc15fe031ca56ac63e317a838ac99972a19cd63c7294f9c53960080be0ec289', +'dafb9bffabee8044994e9b32d98278f8a0e74647dc80519d5f113014f2142b46', +'763b6ec4637f426f6b41fce6af7f23a3537925aaf3b23cbfdbae3227f6930a4e', +'db779d26caf9a11881630256cecf4cede992c616253af77958b706835e4f71a6', +'51d4d8ec4a8536041a80ae5899635162347e316525271659c99e0f79389ffc20', +'e118f346408aba460c5acc78d416ac4d78c93cd0f3f8edab2bfd1d4777e18ced', +'f12664c4ce0206a6b7307ecdc824aaaeec0ab00bd31608ffef628e8a35d2ee8a', +'8dba8a73696e6d0d61cfe7d6b3d1baf9d17a4b336edb5ce100f8fdcc9015f1f1', +'090b2240badddc79406930aefe159d2dce96998b0c4926f829fd28052cdba11f', +'ce75b076f7956692976b3dc2080ebbab7a1062b908bf1c4a071bd404726e175a', +'18d4d6bbebe8430b4c94e2e3c17ba24cce6a3c1a2ab7e46d103e97190aa3db36', +'7cbcc0ce87a0a9f725ee7200a7e86c9bc7d6247da2a96aef37b7ca6652563d88', +'640e2365b73d4c43d84d594b226d017ff520ed8059b889d295c0f900e735b29b', +'9684451f0c396ea9adbcc86fb4abc7306cc408301752d0a0209cc0dbfbb2f4fa', +'a32334d2e357e04f6aa41feaf23e4cad58e0ee7a718dcd6b1ea004d78708a672', +'15e9df0ab69520069311a5a8c20a1e0eead8d97547e4a848404d887803af1968', +'9f6f0a29256e77c8972c3da1a24b3f765dac2fcdb93820cbd88b7f82c54da3d9', +'320feb73d8c766dd6f86b95a7420469a2ad9a56e92c88598b7c2838db5c90ac9', +'1e3e464c911bbaea8c1b2ddc1b6e7630fc773efe77cca7792b9745f67a13ff96', +'988cbcf1afe194c59c04ee381787d28fca9fa5049c18873ee001f084acc6e448', +'0d36855b7571bb8cb95b715a042fe329da3a8e4b778f9d75823e936a0e549312', +'429cc35d04c057bb691eedb0b792bc829b6fd88cd2eecf72a728d7d496d8c30f', +'604c30546332ca9fd30b048303643dde9c7946615fe6869b730d16fdb7b02878', +'6146fe7c79189d69df963819d90ec4932552dae2db32dade683c6c63c76dad84', +'5e2a58a43ff166e931d08a540685d7f039017b4573682e03dd96543a7eacb73b', +'af40d8ec09b302be543caea9729c43042fe84faa0a66d9841055081d913c2093', +'afb884d94a0fdcd789e30a11e0e2d99361a624955570560c53e925f5bc3c637e', +'b389de9d41637bb5917fbecae7b8086d5e2a7e97e32be8f3372dea99bcba498d', +'d4f1d0593d2c452839ecea58caab35f01ee260ee24327a97fa1da71523ab825d', +'6b307a5ec87cb3f56b35717963070e00c60b6da250e422f6805956cd18820d5a', +'f926a5ca4f2d6dd6d47123ad512fe52f20547b5067765c68b1c51c038e22607e', +'7e083b829d991ee91486d7fee10276c289cb47465cf9b5113fb6ffcf9ee8d509', +'5d411870089af67c73b83251ad7fa198e26963684ec1fd6f53ecc05d0d5a3fa3', +'073a7a3001d559d0777ff559ff4aebe48dcc7d53c1876271b9cec534c8502846', +'e3c3a7a9cb9c83940f864be276ff6307934a1a23680269e654d00fd520621802', +'7bf2d61f2c128435cea56eaa869dffc5feb705ddd6b1b0752092caa0ecf2cf5a', +'9fd3974b313b0e7b66802259e39e493f77976fd403a02fc006680b5e310e6587', +'33513a8fd099520b3d7797153bb1f0cfa3afaf95c3ba12ec8c8d9936d3851776', +'932208d88197c89a6a819eff1d17515f9a00ef68140e7dbd8711d59fd3344ad0', +'0594fff94b6c5eef1aa3418f89a2b9a815b0b78cd37a9f5bf5e6c7527e341938', +'f0e8db89dc4bb6f1d0afd375a7ce62a1d6a8d30bead1a9e7fc2bf0a307402209', +'3cd8260017004591c8f66263f266f969ced86b858f2e3b43533d349f5f6d4167', +'e79b02d8eb1e72278d5d23db1ae4dd779bd834e4de15119a05f37fa849662277', +'c128256462490241ae90861f5ab5648f37c3579828588996f4eafd090209bc19', +'ecbbb79b86d4e5c55bc97273290c0b1989d6fe867d219fc3ab2837981a586671', +'b22772b8fce88d52a4280bb991411b25de1c6aa64da8889cf03548d95614900b', +'01f5c6de4661bda50e99434e37fff96f6d113e1dd2907f0f768816dca57a75f3', +'ee3ced889ded3e7484b61f8a591bff2e67e3b8b486f398e10db9f3fe74445a82', +'8a90dc410bbd5404421af830def2b74e2baf8af566524ef018f0a6f45443538d', +'f47160e6901aa364a49a122c37591bd6bfc3091931931c66a87cd8002857c120', +'41284ecc6d052cb2e2674a9e78058a402a201290d8e5a0912cea571f59289ad8', +'4d328859872d13930f86cd367c2c4879efe0d13114aa233cf8fce3e42274ff92', +'a48e6af747934c4e7441f35c616cb70f4793e4cc353c30cd99eae68fad8eb178', +'3de5562c2b42023dd09d83a53dd49c3d3f15dd82034602fa694fa9f197fb0fb8', +'70742e4750d2d41fa9249ec293cfee40eb98ec96f5dd9b3566180c2ce491e59b', +'9c18f5f2f520793a670fd7d13a81ed0b5b2b2353b80c1df9a26457ada2070aef', +'41dff580778dc0d6913456134c3c616714e913d049363a6ef2320984a900d0ea', +'33212388c36ef30a4a2344fb0ba69de51024ae6e9437d5a7da62bd0273231f9e', +'ab57f854266f4d74fe9e44b59153947a7d87719574c50bce7e987294d759acce', +'f55ab35d960b8d8f3b9157e8ad35307d478b3f35f1a78e4d48046b3cf1a58704', +'1153dece5a0fed4ba5b5946578df9cddcdedfedeefd26b0e9d403c89774c7e63', +'aac7e91aece0703ee8229d0347deb38dc6c5194fe19d65566594ebca627c2426', +'4f0d12abad3bd347134db8b6c7ca9d4db2490bff589ad63c4a431ac52b77cfed', +'ac4cbb2c073b66eb1e002e0d009a209b7b407e416f361ebf3b07df8f32f2f84c', +'270bce14bbb30b331ea04bb785118ba2460e780eca07410c019596199cee6f4b', +'4d1ec4d8e74b2cd7211e8effaf24979172bfc345e3ef10248c67980feb17969a', +'df25f18d610e8cdeded67016f8d0b48cda71691627a66681dab788a4cd92460a', +'3d5e468a3f1aef9b259eef7105e8eb5a0ce4c8d3a2230cf8fc036ff0fe61b4e3', +'e62f0d358a697f8863bd7ce8d29442661a5fea1e20d3cee08b8441919d01c8f1', +'68c424677691726381d4b80b664718609f0d7e96ff21ee204dc6afa3c7eafb26', +'386ab80b0dc9609063101c4408abe43f3edba36b51f5dbed4e4349a201a9310c', +'62ae5f6a96afe8b2fb971777e3fbf8daf1dbae26ba049dedc38e137ea1c592dd', +'74baa5e9183f820df28cac718fdf1081333eba1463be6b43be8534c757aab558', +'f81031a1c3919c0f04f467531b51da84cbe92cf846629456f6d837cefdbe4b18', +'6b3c0b47bfeaecfa277e2cef7ca9833e62abdc751c4fe0c3841d35185e09e000', +'a74e8a63c64f0f93dde2eb8e4080e280b911abd3587e1e94d6cb310eff4d5c3b', +'923ca648c0358452d2d320f76435b0991782a9810fcebe113ec1bbd90676e051', +'8fd5989e62ea9db5a22c3321b559eed0f71c9113659c4c898a2f6bd1cdd177e2', +'3944bcc8ac1eeefe8ca42b164887eedf09d7831560ba3b348cafd2d8a688f9aa', +'b7f1beed64f8c3b50d7ed2aa40ef81069a1435f2070e608ed79d6227561ebdf1', +'c96a0993941fc28892a5bab0566b7efe5282239f7dad2e9bf32eca4cd7a2e341', +'297fc73b91a9727ac6c68c2301868d1d18474638dad1939e37e92308584f72a5', +'6f62cbbaca8a3c1801bed061dfb25127e9ba5180d1fd62259c62be763bf1e060', +'5c25c6297cc55a73a85b9fd05b5e7f062bdcdad2638d938cc106a74635328a48', +'0f870c311083f9066cc1536355eb9311dd4d4ebb2eb3f4be59a68f82cf101ce2', +'b1bd3c1a5148bde436c6b5fee1c6aba715e90c9c796f7052737c1d9271c11304', +'f01eca1701776198dcd54facb4ea6d0430eac1f606ef3cb60e681d6866619dae', +'254bb1d8c26bb655db414eb8da2c818e5b722102de88533e39710e5a8fa189fc', +'d643b37250556456341f1e2ea3e92917e8979029207881d6b5523185d3f982cf', +'3094eeb53e4561f924207347c7eaacbcba33c87baa805b9e861002b48bc80198', +'8e122930dbe5f9d7e6b2ddbdc6077e42c6575b0513b7dc56723b74845b31f394', +'465796280843bd23899514250aeaa4604d5f93d0de32732d906c26356c4c0272', +'ec73e56997ffe21a8989a80b7b1b004ea81c4f9209295ae4ba58c20ff1490f6f', +'a8bfd689e82a1683ef217ec4a365c3723a327f82a23748d2524a6c9f38874deb', +'352b7579bbfee90dce0a78092e5af97b6c0e9f7722106859b675b103ac70ea61', +'4e217dc342815642c42a85e80017879d1fec77e97c55fd8982b498398a4c8141', +'677ef5637eb541fb9491f420dcc146b3b184dc9e232aa57ad36ddf1529f69622', +'16a8dd1a35c2711c330fa3e4ce108b48581d7f50bd39d52774a82d6404289e1d', +'caef4776c79795a8f5907c99d7d8a64ab2ba3d2484298b6fca6247f6c92deb15', +'a50f3d1859240d306d97b0bb9fee5be3e61dbd36744b57051a4b01713c0b018f', +'b8a4a6b56ff5ccf1c29a1270b760f799825cc9f875921457132080cff07a7ccf', +'90b7c60f1a910fa507273cb1c9e9688fb3371c501fa666ebee35fe0fd6876864', +'a6e68957ec18f9424be3c35854e8b510ff69fd2fcc245625c19fe756f8a6ba22', +'42622508d48ba6652c8c5e057a9ca0d4dca52df1c2c8f2e205ec5af84a4ae034', +'d6e330a0fdaa09122efb29026e6b29ae01c67dfa97152134699e5727ce8f1a8c', +'3ef8229136529cd0097b28f71a3473f82d37d77bf30e466d1a87ee990243b926', +'42141524318ce10cd680465d66d24839cc56f92b8c8511ce237e2f8c698b8acb', +'53aa67d564e8cb18c24be81b694cd6796af777616d91a563297610bf866664ed', +'66202c052c27c4947a892be7160829134f92e15e520d995b0649c398e5ab6c97', +'e37d3e48ab530054cc6001b96f6ff65d7fac342a945453bced9e7d0e93d2ce72', +'0ac8508da892c66f210fbd271fbd105659900df11d49d55fd70ab629543332d8', +'3f86a17910c56e2038a0bd4a9429754921c3db3b231981fa7777a0716de322d4', +'d1f6f3f6aa4aab63a93df3329719f0f17ce0abf6de44f91c74189fdf79397f03', +'7160c44006ac68d56b2d3d8ee9762aef613c988dc2bd118244edd6e5fd2888f1', +'cc7e88c6ad07001d77771f8aa8b1df8240344112d4a33b0df6c201d0dfce52e0', +'c0bc8fadc1aa383211db4d8ffc33fb42b1a0c4c6a8e41b31bf17cbeef6ce256d', +'ea8028180dff361f39a1f342a5df70a29102da2808415b7c4ad91fde82a8b50d', +'d53845f444884348f2853af02f61f4026f9cb587f934a821666263a07ce4bde2', +'4da0c42cd50b30f0225399ce606df889afbcee48a476704fed5d5cd06df6903f', +'7b49f85631277f0eb805c0d6c1339c2d06e1f7245147bd848595681e26be1c16', +'c25449daa3a5a20c432ffbd7224951942eac76cc752b8d40a5b8c0b4aebc643a', +'e04e97ea87675d30569ad0f4b87c468a3f5e2d4bdd8a57d194d9dc2d694c81a7', +'16ce4899882e7903d066f561944c4eb93757f91a5656b7950452db40102d7fef', +'a576f5dcafb9b39fcc8ef7f306b2282c60d5d25edf46002e14a26fc23ff9cf6e', +'801bb9ae6e63614aa8b18d7672501952352c8e7bcb4d435287bfa358b1a6ceaf', +'c66af0d4b38d60db6839e96dd5e51c39bd66f0eabada130456011aabaa82fb03', +'8c84643fffbd3b78330eac851e77b6b90b3787996c8909f276a01ad0e4bfe42e', +'7f31a398614e8dc5aa6e4c00a84684641a07c920f0769ab1456b0fd99988c586', +'4cc5cf690d91d4b0f17482d9b3cf37a8cc3cfbd9a80031c7d0ad83009e3eae4f', +'62aa36f441c3641b07a7e8bc517920f88dd866d75326f8969ea759067bb83519', +'2b3c96cae11cf115ce41ad3ad432a1be964525ecae064b297a03b1ffc8445c26', +'c1d6efb5b64f4411884f42c2222767f808f3e02bdf288ab308669e45f453ab0d', +'3144b230521841fbd05a4c007073ada4c01ba0db361dd269ff67619741ed01a7', +'c699166ed9dd58eaa1815fd9b940109974286b5f827c9ebf7f4cadcd235e0fc6', +'8dda730c35ebfd18471cfd22a9d82c61f43972b0f5cc22046277646cf5547954', +'9bb296afaefcf0af647acfacbb8b823f8d3a15e5655f139471a84909a88eb94d', +'4e93768d652cdc5ee161efc9f16318e100de93b995cbe0c1badba2dbc140b0c1', +'92f9f687c84d3c76b9b584fb974369c81fb412f2040aa1b728c6cc5db20f2810', +'1c1458a772198d641f5e23bcabfd11c8e45881762e419c262a5b2fbfd0ca5a24', +'1c0a012649db8561b4002a417897418e7127fb756b025a542552eb63d842c80a', +'c80d5f78a14cee0be8eaae8eecd93c79e9341aaa77b86e81c931710389072179', +'aa0227a4df7ba5ccd73828333cb9d9e50cdcf138aafdf23102e95654a691dd7a', +'1c40b7e8db498b8776b70e41a5e364e8e734c9fba441cce58bfa6ca11fa16742', +'e9ec6e6c690da07b38ba005b26ba97dc8ae201b5fc70978501a1ad973fd3145e', +'3dde18eafa3d4fb8deb7a6314e3448dec3ae4ee240ed9ad018f6a3f5c22fccbe', +'d51972193c1ab27686784fbc6bdf57f2ab3512db10d087fa7daa9b223b4dcd25', +'93ed06b90fd50dab61dcf147ce69c352730fd73ca0c9d2afd0b4da3ed8a01e1c', +'ecd834cd2b93485c58d01cfe47ebf3de8e9e56b395ef5bf29480e030b5d317da', +'235e0fee34ba0972c51b174a975fa97deb0855949962a63faa227e6c89827d9b', +'e3a0472f06f169a06bb26b2e3f9f5cd0d91051f324eeb8518f39aa989a013fa1', +'8d12689f78116526aa0d6eb24450fcc52cd1417cfba960f8e49ec2ce7e0ae146', +'2adba391227f919132be08d4063328bcec9edf8f7d3f3ffbb9552cb117eaf9df', +'4938f163678066ef336a0089ed40fbb329d29168fdb54a4417128796a7f28677', +'b4f00c50d3a326448724f0199c41f9f6b375b1fb09d3f08dee06aff50cd443a6', +'814d4127765aead557be45a54bf08fd1880a8c8d5cb69de2cd54ecf0b0ba9f2c', +'44d4882a9c0a793ea5e77931109d52e943485894718c37d2190a76078b1b0f71', +'14503fc26e9699b768dc90f32d316cff443f19f5dda3d264454eb61674bd973f', +'2f8c794eac8254b4048935104bb6cafede8ce24543b3ed5cae556d2d0a7a4581', +'dabc14dd8539ae18a5a9243fb6c78b6dfdb348bf99c1ad1db57080d9b01ebfc2', +'514cd93b8d3ee13b807dee6f81071a5afa7c6bf8e6398b1f8a2670b8641410b7', +'1ce47158d3d4b55d637bffc72ec4300646477682a4b07954bd0297b6891c725f', +'e3086334be719c20df144302013188714ab70a9e712957aa397b65e197d5a260', +'9f64264fe373658c52703429a35a8ef451e78e280ebd215110acacf41c692062', +'9be7ab557421e8164e2e890bc9e9c393b911e2e7346bca586ea8ea746db5ef82', +'77de61802eeab102a1c8f835a550d3158d5f19c3cfcb0e2c341ff3370fa0cf78', +'5bef4e0dbe537b32135689ca199df434255e7914fe695454832a7ba58924aa4c', +'4cbb8510cbc98a9576a743a6848ed2987b3f1c5701152dabbcf2587ada7e11cf', +'4d9a2a4df387574c5d1df5b6c95dc72d3976778ab4b440ce665723962470414b', +'2d182aac179091eb1a452ca88b928d65b353d06b018ce76dc405382cd3e7b32c', +'1df4967e9866867aa6c108861b41c60efa4b430aeaf352274dcd1716a86e22e6', +'2136ad0d7378afea9d74fee86f193ee321a5f6b76cb3d4f00ae6c3fca0b73468', +'146a3f30fafa3bac8eb2cba7488e37523a127dfa9d5db5e62231ed073d4db98d', +'dc1d5351986f79b13fcb55dbebc14b58a760a2cc78e493782f363039031dc0a2', +'988d61985965f6319786edfacffc7ea6c60d22482257e816d0ca32c53d12a2d9', +'a04ea0bb0a58aa953ec51e3e52cbfe1bb140551f46c05d1211e01c43675d59f0', +'2b31f8378b9a1d8dddb5738490e88aabc447c3325fb093ef2675d888c40bb5e7', +'87c37a2e48a74655540eaafe311c6c83ae606611a78f5d3eb0dca7dcf0eab7f5', +'1e00f056d6bda9518676e6f30c6da5abd766ee36c79ef3fab11d3afa01854eb5', +'354dd562a379f18f6182d377ff1d73a15b059e55d230e26b381d2a8cfd00d56b', +'0b114de869ee0665af1b2b3a8732457bbdc404ef009cce95b5cec8c2603f9ff8', +'f9cc18d4cd894d1b61d9de374d9d1665af3d10d6f3342156b85c0f0ae0c73cbc', +'4a5ca92a505ba9a09c970d746c33ddaa206584ddd34e2e485b68dffbcf621cfc', +'b9a05501f19a137bcfefba702aad7628aff3fe6ce2cb8be03796373dec279907', +'f1ebd02e1cdf382cf75344a6289b8bf132227350fb46147961bf74650d38b0c5', +'466acf103d5e3fca2f406e97496af96dbdbba99ba5204e2ef18584574c12fe07', +'a03f2217b1781f1e0fa0a5eb5ca11a43c6c88f0374bc54f3930eab57247ae089', +'e6bfc52d2e4f5fe47c5d06746b6ecd28bb083a9ae7338746578e9b6c512f3878', +'f4c2aa16e5a355b5839502848b519ccf28014c7e185bbc5ab3bf787517f247b4', +'9552ceac803aac6bd88f3b95de8dce4f314730962b2d1a598cbd0bb61017d8d8', +'c9f0eac85cdbf0ce00ed19197f938084f36f81a45ed6470931287c0471e64272', +'fc8c9b7720e4671de42c4473a603c4ff7ef49e579b70bde01431b1a1e905cbd0', +'f92eda195323a5938bc3514116fa4f05dac695c785a20be8f8afa8e967901769', +'36671b6c0a92eec53a0bbf98c1e7f1e9734ea2e9185d0d5038a8c4a157ba876f', +'ce6b04307b81dacce56cb3c87972ecdd28bba40e52b9d1efeea5651f52fe691f', +'ea4a8c27e68bbb4f70121a2c7b1877cdff8737e014e9bad1abbe83b0c3997b1c', +'5ef8953f395c841e27ddc1fe3ca0d79331c8189807cec5ed0ff724da5e08cefe', +'bcd37032ad64ce978586cfb1a65b3ec5bb7446eefada4149ce9d7a88b669ed7a', +'ff1e4deba577be3a1e9c9c31c61d305bc0aa13c10bc2ec6064057adc4a36c5f1', +'a8b67d1442fd65d4d05d3bcb6da74c7a59739787df08e120fd4d733e5f966aa7', +'c9eba770b629fd32d2180553cb96d8352dc5cb0bb652f900ffc1e9e29038f98f', +'ed1da7bbd10476dd0e84d0cefa6a457230c84bb4b31190b4ff4b58e25c398210', +'3aa16d6479d93b8bd0c4642856190ea0dc8777723b74089af58bd61b4700d8f2', +'bb47dea8df3aab2f16960e5ab33fa54c9c1bc239833f69fabba64a7b099fc688', +'f2ee6e2778650b556ec5e5e6fc6127e31fe7976efd7b2401e7b36cc7ec260fd4', +'a2604f43af7a5b9f600d34e0c9a1b3829360d2ccbbe20de96a0c32f4a7d70e18', +'b55b22f981a3ffe3c8ccf0ef320f72cd4f228b74bd4bda73236a0c8f67478999', +'322f60f380573876b5391e77b1296640d97de56d6efcb21f83d6d010e0820165', +'45d44e43a04b4025456e2e6f265c5fca05245350e817b79b28fd97e3212f832c', +'4266ae72d5ee29b527b283d137f9f7552b926b21aec867158fc8256df08c6b54', +'f0e8db89dc4bb6f1d0afd375a7ce62a1d6a8d30bead1a9e7fc2bf0a307402209', +'3cd8260017004591c8f66263f266f969ced86b858f2e3b43533d349f5f6d4167', +'e79b02d8eb1e72278d5d23db1ae4dd779bd834e4de15119a05f37fa849662277', +'8a9i0dc410bbd5404421af830def2b74e2baf8af566524ef018f0a6f45443538d', +'f47160e6901aa364a49a122c37591bd6bfc3091931931c66a87cd8002857c120', +'41284ecc6d052cb2e2674a9e78058a402a201290d8e5a0912cea571f59289ad8', +'4d328859872d13930f86cd367c2c4879efe0d13114aa233cf8fce3e42274ff92' } + + def retryRequest(tempserverlist, apicall): - if len(tempserverlist) != 0: + while len(tempserverlist) != 0: try: response = requests.get('{}api/{}'.format(tempserverlist[0], apicall)) except: tempserverlist.pop(0) - return retryRequest(tempserverlist, apicall) else: if response.status_code == 200: return json.loads(response.content) else: tempserverlist.pop(0) - return retryRequest(tempserverlist, apicall) - else: - logger.error("None of the APIs are responding for the call {}".format(apicall)) - sys.exit(0) + + if len(tempserverlist) == 0: + logger.error("None of the APIs are responding for the call {}".format(apicall)) + return 0 def multiRequest(apicall, net): testserverlist = ['http://0.0.0.0:9000/', 'https://testnet-flosight.duckdns.org/', 'https://testnet.flocha.in/'] - mainserverlist = ['http://0.0.0.0:9001/', 'https://flosight.duckdns.org/', 'https://explorer.mediciland.com/', 'https://livenet.flocha.in/'] + mainserverlist = ['https://flosight.duckdns.org/','http://0.0.0.0:9495/'] if net == 'mainnet': return retryRequest(mainserverlist, apicall) elif net == 'testnet': @@ -48,14 +883,17 @@ def multiRequest(apicall, net): def pushData_SSEapi(message): signature = pybtc.sign_message(message.encode(), privKey) headers = {'Accept': 'application/json', 'Content-Type': 'application/json', 'Signature': signature} + '''try: r = requests.post(sseAPI_url, json={'message': '{}'.format(message)}, headers=headers) except: - logger.error("couldn't push the following message to SSE api {}".format(message))''' + logger.error("couldn't push the following message to SSE api {}".format(message))''' + print('') def processBlock(blockindex): - logger.info(f"Processing block {blockindex}") + logger.info(f'Processing block {blockindex}') + logger.info('Processing block ' + str(blockindex)) # Get block details response = multiRequest(f"block-index/{blockindex}", config['DEFAULT']['NET']) blockhash = response['blockHash'] @@ -65,23 +903,53 @@ def processBlock(blockindex): counter = 0 acceptedTxList = [] # Scan every transaction + logger.info("Before tx loop") + #pdb.set_trace() + counter = 0 + #pdb.set_trace() for transaction in blockinfo["tx"]: - transaction_data = multiRequest(f"tx/{transaction}", config['DEFAULT']['NET']) - text = transaction_data["floData"] - text = text.replace("\n", " \n ") + if blockindex < 4365011 and (transaction not in goodtxset): + continue + counter = counter + 1 + logger.info(f"Transaction {counter} {transaction}") + #transaction_data = multiRequest(f"tx/{transaction}", config['DEFAULT']['NET']) + #try: + # text = transaction_data["floData"] + # text = text.replace("\n", " \n ") + #except: + # logger.info("The API has passed the Block height test but failed transaction_data['floData'] test. transaction_data response from the API is logged below") + # logger.info(f"{transaction_data}") + + + #if current_index == -1: + current_index = -1 + while(current_index == -1): + transaction_data = multiRequest(f"tx/{transaction}", config['DEFAULT']['NET']) + try: + text = transaction_data["floData"] + text = text.replace("\n", " \n ") + current_index = 2 + except: + logger.info("The API has passed the Block height test but failed transaction_data['floData'] test") + logger.info(f"Block Height : {blockindex}") + logger.info(f"Transaction {transaction} data : ") + logger.info(transaction_data) + logger.info('Program will wait for 1 seconds and try to reconnect') + time.sleep(1) + # todo Rule 9 - Reject all noise transactions. Further rules are in parsing.py returnval = None parsed_data = parsing.parse_flodata(text, blockinfo, config['DEFAULT']['NET']) if parsed_data['type'] != 'noise': logger.info(f"Processing transaction {transaction}") - logger.debug(f"flodata {text} is parsed to {parsed_data}") + logger.info(f"flodata {text} is parsed to {parsed_data}") returnval = processTransaction(transaction_data, parsed_data) if returnval == 1: acceptedTxList.append(transaction) elif returnval == 0: - logger.debug("Transfer for the transaction %s is illegitimate. Moving on" % transaction) + logger.info("Transfer for the transaction %s is illegitimate. Moving on" % transaction) if len(acceptedTxList) > 0: tempinfo = blockinfo['tx'].copy() @@ -104,7 +972,7 @@ def processBlock(blockindex): def processApiBlock(blockhash): - print(config['DEFAULT']['NET']) + logger.info(config['DEFAULT']['NET']) blockinfo = multiRequest('block/{}'.format(str(blockhash)), config['DEFAULT']['NET']) # todo Rule 8 - read every transaction from every block to find and parse flodata @@ -121,13 +989,13 @@ def processApiBlock(blockhash): parsed_data = parsing.parse_flodata(text, blockinfo, config['DEFAULT']['NET']) if parsed_data['type'] != 'noise': logger.info(f"Processing transaction {transaction}") - logger.debug(f"flodata {text} is parsed to {parsed_data}") + logger.info(f"flodata {text} is parsed to {parsed_data}") returnval = processTransaction(transaction_data, parsed_data) if returnval == 1: acceptedTxList.append(transaction) elif returnval == 0: - logger.debug("Transfer for the transaction %s is illegitimate. Moving on" % transaction) + logger.info("Transfer for the transaction %s is illegitimate. Moving on" % transaction) if len(acceptedTxList) > 0: tempinfo = blockinfo['tx'].copy() @@ -142,13 +1010,14 @@ def processApiBlock(blockhash): session = sessionmaker(bind=engine)() entry = session.query(SystemData).filter(SystemData.attribute == 'lastblockscanned').all()[0] entry.value = str(blockinfo['height']) - print('Last scanned block value should be '+ str(entry.value)) + logger.info('Last scanned block value should be '+ str(entry.value)) session.commit() session.close() # Check smartContracts which will be triggered locally, and not by the contract committee checkLocaltriggerContracts(blockinfo) + def updateLatestTransaction(transactionData, parsed_data): # connect to latest transaction db conn = sqlite3.connect('latestCache.db') @@ -658,9 +1527,9 @@ def processTransaction(transaction_data, parsed_data): else: outputlist = outputlist[0] - logger.debug( + logger.info( f"Input address list : {inputlist}") - logger.debug( + logger.info( f"Output address list : {outputlist}") # All FLO checks completed at this point. @@ -668,7 +1537,7 @@ def processTransaction(transaction_data, parsed_data): # todo Rule 44 - Process as per the type of transaction if parsed_data['type'] == 'transfer': - logger.debug(f"Transaction {transaction_data['txid']} is of the type transfer") + logger.info(f"Transaction {transaction_data['txid']} is of the type transfer") # todo Rule 45 - If the transfer type is token, then call the function transferToken to adjust the balances if parsed_data['transferType'] == 'token': @@ -1485,7 +2354,7 @@ def processTransaction(transaction_data, parsed_data): if not os.path.isfile(f"./smartContracts/{parsed_data['contractName']}-{parsed_data['contractAddress']}.db"): # todo Rule 49 - If the contract name hasn't been taken before, check if the contract type is an authorized type by the system if parsed_data['contractType'] == 'one-time-event': - logger.debug("Smart contract is of the type one-time-event") + logger.info("Smart contract is of the type one-time-event") # either userchoice or payeeAddress condition should be present. Check for it if 'userchoices' not in parsed_data['contractConditions'] and 'payeeAddress' not in parsed_data[ @@ -1731,7 +2600,7 @@ def processTransaction(transaction_data, parsed_data): return 0 elif parsed_data['type'] == 'smartContractPays': - logger.debug(f"Transaction {transaction_data['txid']} is of the type smartContractPays") + logger.info(f"Transaction {transaction_data['txid']} is of the type smartContractPays") # Check if input address is a committee address if inputlist[0] in committeeAddressList: @@ -2200,15 +3069,31 @@ def scanBlockchain(): session.close() # todo Rule 6 - Find current block height - # Rule 7 - Start analysing the block contents from starting block to current height + # Rule 7 - Start analysing the block contents from starting block to current height # Find current block height - response = multiRequest('blocks?limit=1', config['DEFAULT']['NET']) - current_index = response['blocks'][0]['height'] - logger.debug("Current block height is %s" % str(current_index)) - + current_index = -1 + while(current_index == -1): + response = multiRequest('blocks?limit=1', config['DEFAULT']['NET']) + try: + current_index = response['blocks'][0]['height'] + except: + logger.info('Latest block count response from multiRequest() is not in the right format. Displaying the data received in the log below') + logger.info(response) + logger.info('Program will wait for 1 seconds and try to reconnect') + time.sleep(1) + else: + logger.info("Current block height is %s" % str(current_index)) + break + for blockindex in range(startblock, current_index): - processBlock(blockindex) + if blockindex < 4365011: + if blockindex in goodblockset: + processBlock(blockindex) + else: + logger.info(f"Skipping block {blockindex}") + else: + processBlock(blockindex) # At this point the script has updated to the latest block # Now we connect to flosight's websocket API to get information about the latest blocks @@ -2230,6 +3115,7 @@ stream_handler.setFormatter(formatter) logger.addHandler(file_handler) logger.addHandler(stream_handler) + # todo Rule 1 - Read command line arguments to reset the databases as blank # Rule 2 - Read config to set testnet/mainnet # Rule 3 - Set flo blockexplorer location depending on testnet or mainnet @@ -2238,8 +3124,7 @@ logger.addHandler(stream_handler) # Read command line arguments -parser = argparse.ArgumentParser( - description='Script tracks RMT using FLO data on the FLO blockchain - https://flo.cash') +parser = argparse.ArgumentParser(description='Script tracks RMT using FLO data on the FLO blockchain - https://flo.cash') parser.add_argument('-r', '--reset', nargs='?', const=1, type=int, help='Purge existing db and rebuild it') args = parser.parse_args() @@ -2257,7 +3142,7 @@ config.read('config.ini') # Assignment the flo-cli command if config['DEFAULT']['NET'] == 'mainnet': - neturl = 'https://flosight.duckdns.org/' + neturl = 'http://0.0.0.0:9495/' localapi = config['DEFAULT']['FLO_CLI_PATH'] elif config['DEFAULT']['NET'] == 'testnet': neturl = 'https://testnet-flosight.duckdns.org/' @@ -2268,7 +3153,7 @@ else: # Delete database and smartcontract directory if reset is set to 1 if args.reset == 1: - logger.debug("Resetting the database. ") + logger.info("Resetting the database. ") apppath = os.path.dirname(os.path.realpath(__file__)) dirpath = os.path.join(apppath, 'tokens') shutil.rmtree(dirpath) @@ -2299,66 +3184,78 @@ if args.reset == 1: session.close() +def switchNeturl(currentneturl): + mainserverlist = ['http://0.0.0.0:9495/'] + neturlindex = mainserverlist.index(currentneturl) + if neturlindex+1 >= len(mainserverlist): + return mainserverlist[neturlindex+1 - len(mainserverlist)] + else: + return mainserverlist[neturlindex+1] -# MAIN LOGIC +def reconnectWebsocket(socket_variable): + # Switch a to different flosight + # neturl = switchNeturl(neturl) + # Connect to Flosight websocket to get data on new incoming blocks + i=0 + newurl = neturl + while(not socket_variable.connected): + logger.info(f"While loop {i}") + logger.info(f"Sleeping for 3 seconds before attempting reconnect to {newurl}") + time.sleep(3) + try: + """ neturl = temp + logger.info(f"neturl: {neturl}") """ + scanBlockchain() + logger.info(f"Websocket endpoint which is being connected to {newurl}socket.io/socket.io.js") + socket_variable.connect(f"{newurl}socket.io/socket.io.js") + i=i+1 + except: + logger.info(f"disconnect block: Failed reconnect attempt to {newurl}") + newurl = switchNeturl(newurl) + i=i+1 + + +# MAIN LOGIC # scan from the latest block saved locally to latest network block scanBlockchain() -scanBlockchain() - -def switchNeturl(neturl): - testserverlist = ['http://0.0.0.0:9000/', 'https://testnet-flosight.duckdns.org/', 'https://testnet.flocha.in/'] - mainserverlist = ['http://0.0.0.0:9001/', 'https://flosight.duckdns.org/', 'https://explorer.mediciland.com/', 'https://livenet.flocha.in/'] - if config['DEFAULT']['NET'] == 'mainnet': - neturlindex = mainserverlist.index(neturl) - if neturlindex+1 >= len(mainserverlist): - return mainserverlist[neturlindex+1 - len(mainserverlist)] - else: - return mainserverlist[neturlindex+1] - elif config['DEFAULT']['NET'] == 'testnet': - neturlindex = testserverlist.index(neturl) - if neturlindex+1 >= len(testserverlist): - return testserverlist[neturlindex+1 - len(testserverlist)] - else: - return testserverlist[neturlindex+1] - -def reconnectSSE(neturl): - - # Connect to Flosight websocket to get data on new incoming blocks - sio = socketio.Client(reconnection=False) - try: - sio.connect( neturl + "socket.io/socket.io.js") - except: - logger.debug(f"Could not connect to the websocket endpoint {neturl}. Switching & retrying to next") - neturl = switchNeturl(neturl) - reconnectSSE(neturl) - - @sio.on('connect') - def on_connect(): - logger.debug(f"Token Tracker has connected to websocket endpoint {neturl}") - sio.emit('subscribe', 'inv') - - @sio.on('disconnect') - def disconnect(): - logger.debug(f"Token Tracker disconnected from websocket endpoint {neturl}") - logger.debug('The script will rescan from the latest block in local db to latest server on FLO network') - scanBlockchain() - logger.debug("Rescan completed") - logger.debug('Attempting reconnect to websocket ...') - reconnectSSE(neturl) - - @sio.on('connect_error') - def connect_error(): - logger.debug(f"CONNECTION_ERROR to the websocket endpoint {neturl}. Switching & retrying to next") - neturl = switchNeturl(neturl) - reconnectSSE(neturl) - - @sio.on('block') - def on_block(data): - logger.debug('New block received') - logger.debug(str(data)) - processApiBlock(data) # At this point the script has updated to the latest block # Now we connect to flosight's websocket API to get information about the latest blocks +# Neturl is the URL for Flosight API whose websocket endpoint is being connected to + neturl = 'https://flosight.duckdns.org/' -reconnectSSE(neturl) +sio = socketio.Client() +# Connect to a websocket endpoint and wait for further events +reconnectWebsocket(sio) +#sio.connect(f"{neturl}socket.io/socket.io.js") + +@sio.on('connect') +def token_connect(): + current_time=datetime.now().strftime('%H:%M:%S') + logger.info(f"Token Tracker has connected to websocket endpoint. Time : {current_time}") + sio.emit('subscribe', 'inv') + +@sio.on('disconnect') +def token_disconnect(): + current_time = datetime.now().strftime('%H:%M:%S') + logger.info(f"disconnect block: Token Tracker disconnected from websocket endpoint. Time : {current_time}") + logger.info('disconnect block: Triggering client disconnect') + sio.disconnect() + logger.info('disconnect block: Finished triggering client disconnect') + reconnectWebsocket(sio) + +@sio.on('connect_error') +def connect_error(): + current_time = datetime.now().strftime('%H:%M:%S') + logger.info(f"connection error block: Token Tracker disconnected from websocket endpoint. Time : {current_time}") + logger.info('connection error block: Triggering client disconnect') + sio.disconnect() + logger.info('connection error block: Finished triggering client disconnect') + reconnectWebsocket(sio) + +@sio.on('block') +def on_block(data): + logger.info('New block received') + logger.info(str(data)) + processApiBlock(data) +