diff --git a/README.md b/README.md index 4ad8eaf206d0f49c9158f1b12be73a7883af96c9..c9fb9e847cf9bb82e7f4e30199e2712f3806d3fb 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,13 @@ pip install -r requirements.txt ``` - Crear un link simbólico al archivo local_settings.py desde el local settings del entorno en que se encuentre el proyecto - Ejecutar: - - sudo apt-get install libssl-dev build-essential automake pkg-config libtool libffi-dev libgmp-dev libyaml-cpp-dev + - sudo apt-get install libssl-dev build-essential automake pkg-config libtool libffi-dev libgmp-dev libyaml-cpp-dev memcached - git clone https://github.com/ethereum/pyethereum/ - cd pyethereum - python setup.py install +- Poner en crontab el sig comando reemplazando donde corresponde los directorios + /directorio/del/venv/bin/python /directorio/de/aplicacion/manage.py desatascar_pendientes > /dev/null ### Utilización - Stamp - Método: POST diff --git a/TsaApi/local_settings_dev.py b/TsaApi/local_settings_dev.py index 5accc7edc2cd6eaf03908889ac3acb8994123994..e7caa878b7139ffeceaf6b198679a9e79c8cb421 100644 --- a/TsaApi/local_settings_dev.py +++ b/TsaApi/local_settings_dev.py @@ -15,11 +15,23 @@ ACCOUNT_ADDRESS = '0x25c185dcaed065bac30a0a1cd0688a7aa02896d7' HOST_ADDRESS = 'http://10.23.10.72:8501' -#Contracts info +# Contracts info CONTRACTS = { - '01':{ + '01': { 'address': '0x88933138A9Ef6474ee4f255A6395210F4f014d6B', - 'abi': [{"constant":True,"inputs":[{"name":"ots","type":"string"}],"name":"getHash","outputs":[{"name":"","type":"string"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":True,"inputs":[{"name":"ots","type":"string"}],"name":"getBlockNumber","outputs":[{"name":"","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":True,"inputs":[{"name":"ots","type":"string"},{"name":"file_hash","type":"string"}],"name":"verify","outputs":[{"name":"","type":"bool"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":False,"inputs":[{"name":"ots","type":"string"},{"name":"file_hash","type":"string"}],"name":"stamp","outputs":[],"payable":False,"stateMutability":"nonpayable","type":"function"}], + 'abi': [{"constant": True, "inputs": [{"name": "ots", "type": "string"}], "name": "getHash", + "outputs": [{"name": "", "type": "string"}], "payable": False, "stateMutability": "view", + "type": "function"}, + {"constant": True, "inputs": [{"name": "ots", "type": "string"}], "name": "getBlockNumber", + "outputs": [{"name": "", "type": "uint256"}], "payable": False, "stateMutability": "view", + "type": "function"}, {"constant": True, "inputs": [{"name": "ots", "type": "string"}, + {"name": "file_hash", "type": "string"}], + "name": "verify", "outputs": [{"name": "", "type": "bool"}], "payable": False, + "stateMutability": "view", "type": "function"}, {"constant": False, "inputs": [ + {"name": "ots", "type": "string"}, {"name": "file_hash", "type": "string"}], "name": "stamp", + "outputs": [], "payable": False, + "stateMutability": "nonpayable", + "type": "function"}], }, } @@ -33,4 +45,21 @@ PERMANENT_OTS_PREFIX = '1x' GAS = 250000 GAS_PRICE = 1 -SENTRY_URL = 'http://2ec54beaab3b4459a1e5afadea070f98:92aee3f5d91e4e66996a3e0792985541@172.17.30.21:9000/54' \ No newline at end of file +SENTRY_URL = 'http://2ec54beaab3b4459a1e5afadea070f98:92aee3f5d91e4e66996a3e0792985541@172.17.30.21:9000/54' + +MEMCACHED_HOST = '172.17.0.1' +MEMCACHED_PORT = 11211 # TIENE QUE SER INT + +PENDING_TXS_MEMCACHED_KEY = 'pending_txs' + +TEST_MEMCACHED_HOST = MEMCACHED_HOST +TEST_MEMCACHED_PORT = MEMCACHED_PORT + +TEST_PENDING_TXS_MEMCACHED_KEY = 'test_pending_txs' + +ELASTIC_APM = { + 'SERVICE_NAME': 'TsaApi-dev', + 'SERVER_URL': 'http://10.1.100.67:8200', + 'DEBUG': True, +} + diff --git a/TsaApi/local_settings_preprod.py b/TsaApi/local_settings_preprod.py index 3e45e9f9be26a7e32e66285e5306c94df4be4ccb..685c6348548d431842c3169f4dd413af860ef9bb 100644 --- a/TsaApi/local_settings_preprod.py +++ b/TsaApi/local_settings_preprod.py @@ -8,6 +8,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ """ APP_ROOT = '/var/www/tsaapi.pp.bfa.local/' +LOG_ROOT = APP_ROOT + 'logs/' STATIC_ROOT = APP_ROOT + 'html/' STATIC_URL = '/tsa/static/' @@ -15,11 +16,47 @@ ACCOUNT_ADDRESS = '0xA9cAc6C2EF4909A05eF24A12Ecadf9E541B5995F' # cuenta con bal HOST_ADDRESS = 'http://10.23.10.73:54450' # Nodo de la BFA de Test -#Contracts info +# Contracts info CONTRACTS = { - '01':{ + '01': { 'address': '0xD5110AB5cE1be270d5B8c5FB7A25c60765994ca8', - 'abi': [ { "constant": False, "inputs": [], "name": "selfDestroy", "outputs": [], "payable": False, "stateMutability": "nonpayable", "type": "function" }, { "constant": False, "inputs": [ { "name": "ots", "type": "string" }, { "name": "file_hash", "type": "string" } ], "name": "stamp", "outputs": [], "payable": False, "stateMutability": "nonpayable", "type": "function" }, { "anonymous": False, "inputs": [ { "indexed": True, "name": "from", "type": "address" }, { "indexed": True, "name": "hash", "type": "string" }, { "indexed": True, "name": "ots", "type": "string" } ], "name": "Stamped", "type": "event" }, { "anonymous": False, "inputs": [ { "indexed": True, "name": "from", "type": "address" }, { "indexed": True, "name": "contract_address", "type": "address" } ], "name": "Deploy", "type": "event" }, { "anonymous": False, "inputs": [ { "indexed": True, "name": "from", "type": "address" }, { "indexed": True, "name": "contract_address", "type": "address" } ], "name": "SelfDestroy", "type": "event" }, { "inputs": [], "payable": False, "stateMutability": "nonpayable", "type": "constructor" }, { "constant": True, "inputs": [ { "name": "ots", "type": "string" } ], "name": "getBlockNumber", "outputs": [ { "name": "", "type": "uint256" } ], "payable": False, "stateMutability": "view", "type": "function" }, { "constant": True, "inputs": [ { "name": "ots", "type": "string" } ], "name": "getHash", "outputs": [ { "name": "", "type": "string" } ], "payable": False, "stateMutability": "view", "type": "function" }, { "constant": True, "inputs": [ { "name": "ots", "type": "string" }, { "name": "file_hash", "type": "string" } ], "name": "verify", "outputs": [ { "name": "", "type": "bool" } ], "payable": False, "stateMutability": "view", "type": "function" } ], + 'abi': [{"constant": False, "inputs": [], "name": "selfDestroy", "outputs": [], "payable": False, + "stateMutability": "nonpayable", "type": "function"}, {"constant": False, + "inputs": [{"name": "ots", "type": "string"}, + {"name": "file_hash", + "type": "string"}], "name": "stamp", + "outputs": [], "payable": False, + "stateMutability": "nonpayable", + "type": "function"}, {"anonymous": False, + "inputs": [ + {"indexed": True, + "name": "from", + "type": "address"}, + {"indexed": True, + "name": "hash", + "type": "string"}, + {"indexed": True, + "name": "ots", + "type": "string"}], + "name": "Stamped", + "type": "event"}, + {"anonymous": False, "inputs": [{"indexed": True, "name": "from", "type": "address"}, + {"indexed": True, "name": "contract_address", "type": "address"}], + "name": "Deploy", "type": "event"}, {"anonymous": False, + "inputs": [{"indexed": True, "name": "from", "type": "address"}, + {"indexed": True, "name": "contract_address", + "type": "address"}], "name": "SelfDestroy", + "type": "event"}, + {"inputs": [], "payable": False, "stateMutability": "nonpayable", "type": "constructor"}, + {"constant": True, "inputs": [{"name": "ots", "type": "string"}], "name": "getBlockNumber", + "outputs": [{"name": "", "type": "uint256"}], "payable": False, "stateMutability": "view", + "type": "function"}, + {"constant": True, "inputs": [{"name": "ots", "type": "string"}], "name": "getHash", + "outputs": [{"name": "", "type": "string"}], "payable": False, "stateMutability": "view", + "type": "function"}, {"constant": True, "inputs": [{"name": "ots", "type": "string"}, + {"name": "file_hash", "type": "string"}], + "name": "verify", "outputs": [{"name": "", "type": "bool"}], "payable": False, + "stateMutability": "view", "type": "function"}], }, } CURRENT_CONTRACT_VERSION = '01' @@ -32,4 +69,10 @@ PERMANENT_OTS_PREFIX = '1x' GAS = 250000 GAS_PRICE = 1 -SENTRY_URL = 'http://aa30f3ecd3bb4923a7046f197da61e07:47cd9f9ea1e243f6a9f47e2aa40b85c3@10.1.100.118:9000/82' \ No newline at end of file +SENTRY_URL = 'http://aa30f3ecd3bb4923a7046f197da61e07:47cd9f9ea1e243f6a9f47e2aa40b85c3@10.1.100.118:9000/82' + +ELASTIC_APM = { + 'SERVICE_NAME': 'TsaApi-pp', + 'SERVER_URL': 'http://10.20.99.87:8200', + 'DEBUG': True, +} diff --git a/TsaApi/local_settings_prod.py b/TsaApi/local_settings_prod.py index 9d51a160ba5d96d9d00dc00fe70360b1c33281bf..dbdd5cee9e8dee3cb6d1375aad1616e91e9d0af1 100644 --- a/TsaApi/local_settings_prod.py +++ b/TsaApi/local_settings_prod.py @@ -41,4 +41,10 @@ PERMANENT_OTS_PREFIX = '1x' GAS = 250000 GAS_PRICE = 100000000 -SENTRY_URL = 'http://36f4f241a007447d8a4441a13055b110:136cb6d1af854b869d13610603fa7321@10.1.100.118:9000/84' \ No newline at end of file +SENTRY_URL = 'http://36f4f241a007447d8a4441a13055b110:136cb6d1af854b869d13610603fa7321@10.1.100.118:9000/84' + +ELASTIC_APM = { + 'SERVICE_NAME': 'TsaApi', + 'SERVER_URL': 'http://10.20.99.87:8200', + 'DEBUG': False, +} diff --git a/app/management/__init__.py b/app/management/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/app/management/commands/__init__.py b/app/management/commands/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/app/management/commands/borrar_memcached.py b/app/management/commands/borrar_memcached.py new file mode 100644 index 0000000000000000000000000000000000000000..c28b22da4cc24c46fb1d2fe980555109d974d662 --- /dev/null +++ b/app/management/commands/borrar_memcached.py @@ -0,0 +1,20 @@ +import logging + +from django.core.management import BaseCommand + +from app.services import TransactionUnstucker, MemcachedStorage +from TsaApi.settings import GAS_PRICE +from TsaApi.settings import PENDING_TXS_MEMCACHED_KEY + +class Command(BaseCommand): + unstucker = TransactionUnstucker() + logger = logging.getLogger('cmd') + storage = MemcachedStorage() + + def handle(self, *args, **options): + try: + self.storage.store([]) + print("Memcached sobre key {} cambiado a {}".format(PENDING_TXS_MEMCACHED_KEY,self.storage.retrieve())) + except Exception as e: + self.logger.error(str(e)) + print("Hubo un error {}".format(str(e))) diff --git a/app/management/commands/contenido_memcached.py b/app/management/commands/contenido_memcached.py new file mode 100644 index 0000000000000000000000000000000000000000..c0465f045a4a663ca5eec8f0c4a063d23d35836a --- /dev/null +++ b/app/management/commands/contenido_memcached.py @@ -0,0 +1,15 @@ +import logging + +from django.core.management import BaseCommand + +from app.services import TransactionUnstucker, MemcachedStorage +from TsaApi.settings import GAS_PRICE + + +class Command(BaseCommand): + unstucker = TransactionUnstucker() + logger = logging.getLogger('cmd') + storage = MemcachedStorage() + + def handle(self, *args, **options): + print(self.storage.retrieve()) diff --git a/app/management/commands/desatascar_pendientes.py b/app/management/commands/desatascar_pendientes.py new file mode 100644 index 0000000000000000000000000000000000000000..afb6ddfed1dc10137d936f7fc1f658669ad7ee4d --- /dev/null +++ b/app/management/commands/desatascar_pendientes.py @@ -0,0 +1,15 @@ +import logging + +from django.core.management import BaseCommand + +from app.managers import EthereumGateway +from app.services import TransactionUnstucker +from TsaApi.settings import GAS_PRICE +import logging + + +class Command(BaseCommand): + unstucker = TransactionUnstucker(logging.getLogger('console-logger')) + + def handle(self, *args, **options): + self.unstucker.unstuck_pending_transactions(GAS_PRICE) diff --git a/app/utils.py b/app/utils.py index d7e2b233fa5822086b7ef5574305ce7e5f273a48..7604af8d659d8acc05bde72cf8d364acc7da16fb 100644 --- a/app/utils.py +++ b/app/utils.py @@ -7,6 +7,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ """ +import base64 import datetime import hashlib import time @@ -14,7 +15,7 @@ import math from TsaApi.settings import ACCOUNT_ADDRESS, CURRENT_CONTRACT_VERSION, PERMANENT_OTS_PREFIX, TEMPORARY_OTS_PREFIX -class Utils(): +class Utils: @staticmethod def sha256_encode(string): return hashlib.sha256(string.encode('utf-8')).hexdigest() @@ -25,7 +26,8 @@ class Utils(): @staticmethod def get_ots_hash(file_hash): - #El ots se genera con los hashes sha256 de (archivo original+timestamp+dirección de la cuenta) + versión del contrato + # El ots se genera con los hashes sha256 de (archivo original+timestamp+dirección de la cuenta) + versión del + # contrato return Utils.sha256_encode(str(file_hash + Utils.sha256_encode(str(int(time.time()))) + Utils.sha256_encode(ACCOUNT_ADDRESS))) + CURRENT_CONTRACT_VERSION @staticmethod @@ -56,4 +58,9 @@ class Utils(): @staticmethod def get_temporary_ots(ots_hash, tx_hash): - return TEMPORARY_OTS_PREFIX + '-' + ots_hash + '-' + tx_hash \ No newline at end of file + return TEMPORARY_OTS_PREFIX + '-' + ots_hash + '-' + tx_hash + + +class Base64EncodingService: + def encode(self, stuff): + return base64.b64encode(stuff) diff --git a/requirements.txt b/requirements.txt index e7e919e6c5f1ea1ae27a23d4c7d124c58f98abfe..442d892db1b2cfb0d620f772ee95f13f7e732d01 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,9 @@ -ipython==7.2.0 -ipython-genutils==0.2.0 -pymemcache==2.1.1 -elastic-apm==3.0.0 +asn1crypto==0.24.0 attrdict==2.0.0 certifi==2018.4.16 +cffi==1.11.5 chardet==3.0.4 +coincurve==9.0.0 coreapi==2.3.3 coreschema==0.0.4 cytoolz==0.9.0.1 @@ -20,6 +19,8 @@ eth-keyfile==0.5.1 eth-keys==0.2.0b3 eth-rlp==0.1.2 eth-utils==1.0.3 +ethereum==2.3.2 +future==0.16.0 hexbytes==0.1.0 idna==2.7 itypes==1.1.0 @@ -28,17 +29,29 @@ lru-dict==1.1.6 MarkupSafe==1.0 openapi-codec==1.3.2 parsimonious==0.8.0 +pbkdf2==1.3 +py-ecc==1.4.3 +pycparser==2.18 pycryptodome==3.6.4 +pyethash==0.1.27 PyJWT==1.6.4 +pysha3==1.0.2 python-bitcoinlib==0.10.1 pytz==2018.5 +PyYAML==4.2b4 raven==6.9.0 +repoze.lru==0.7 requests==2.19.1 rlp==1.0.1 +scrypt==0.8.6 simplejson==3.16.0 six==1.11.0 toolz==0.9.0 uritemplate==3.0.0 urllib3==1.23 web3==4.5.0 -websockets==5.0.1 \ No newline at end of file +websockets==5.0.1 +elastic-apm==3.0.0 +ipython==7.2.0 +ipython-genutils==0.2.0 +pymemcache==2.1.1 \ No newline at end of file