From b0a83c7cf34980855d8a1541c1cdf8b4f683fc6d Mon Sep 17 00:00:00 2001 From: Aditya Anand M C Date: Thu, 5 Dec 2019 16:52:29 +0530 Subject: [PATCH] feat: built out sync_etc which checks txn mining status --- app/app/urls.py | 1 + app/dashboard/utils.py | 21 ++++++++++++ app/dashboard/views.py | 73 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/app/app/urls.py b/app/app/urls.py index 0bcb2e887e4..1d6316df8f0 100644 --- a/app/app/urls.py +++ b/app/app/urls.py @@ -339,6 +339,7 @@ # sync methods url(r'^sync/web3/?', dashboard.views.sync_web3, name='sync_web3'), + url(r'^sync/etc/?', dashboard.views.sync_etc, name='sync_etc'), url(r'^sync/get_amount/?', dashboard.helpers.amount, name='helpers_amount'), re_path(r'^sync/get_issue_details/?', dashboard.helpers.issue_details, name='helpers_issue_details'), diff --git a/app/dashboard/utils.py b/app/dashboard/utils.py index 4574c399836..ddd8f580fcc 100644 --- a/app/dashboard/utils.py +++ b/app/dashboard/utils.py @@ -471,6 +471,27 @@ def has_tx_mined(txid, network): return False +def get_etc_txn_status(txnid, network='mainnet'): + if not txnid: + return False + + blockscout_url = f'https://blockscout.com/etc/mainnet/api?module=transaction&action=gettxinfo&txhash={txnid}' + blockscout_response = requests.get(blockscout_url).json() + + if blockscout_response['status'] and blockscout_response['result']: + response = { + 'blockNumber': int(blockscout_response['result']['blockNumber']), + 'confirmations': int(blockscout_response['result']['confirmations']) + } + if response['confirmations'] > 0: + response['has_mined'] = True + else: + response['has_mined'] = False + return response + + return False + + def get_bounty_id(issue_url, network): issue_url = normalize_url(issue_url) bounty_id = get_bounty_id_from_db(issue_url, network) diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 9f0b7e202ba..8ba09f567e5 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -94,8 +94,9 @@ maybe_market_to_github, maybe_market_to_slack, maybe_market_to_user_discord, maybe_market_to_user_slack, ) from .utils import ( - apply_new_bounty_deadline, get_bounty, get_bounty_id, get_context, get_unrated_bounties_count, get_web3, - has_tx_mined, re_market_bounty, record_user_action_on_interest, release_bounty_to_the_public, web3_process_bounty, + apply_new_bounty_deadline, get_bounty, get_bounty_id, get_context, get_etc_txn_status, get_unrated_bounties_count, + get_web3, has_tx_mined, re_market_bounty, record_user_action_on_interest, release_bounty_to_the_public, + web3_process_bounty, ) logger = logging.getLogger(__name__) @@ -2866,6 +2867,74 @@ def sync_web3(request): return JsonResponse(result, status=result['status']) +# @require_POST +# @csrf_exempt +# @ratelimit(key='ip', rate='5/s', method=ratelimit.UNSAFE, block=True) +def sync_etc(request): + """Sync up ETC chain to find transction status. + + Returns: + JsonResponse: The JSON response following the web3 sync. + + """ + + response = { + 'status': '400', + 'message': 'bad request' + } + + # TODO: make into POST + txnid = request.GET.get('txnid', None) + bounty_id = request.GET.get('id', None) + network = request.GET.get('network', 'mainnet') + + # TODO: REMOVE + txnid = '0x30060f38c0e9e255061d1daf079d3707c640bfb540e207dbc6fc0e6e6d52ecd1' + bounty_id = 1 + + if not txnid: + response['message'] = 'error: transaction not provided' + elif not bounty_id: + response['message'] = 'error: issue url not provided' + elif network != 'mainnet': + response['message'] = 'error: etc syncs only on mainnet' + else: + + # TODO: CHECK IF BOUNTY EXSISTS + # bounty = Bounty.object.get(pk=bounty_id) + # if not bounty: + # response['message'] = f'error: bounty with key {bounty_id} does not exist' + # else: + # print('bounty found') # wrap whole section below within else + retry = True + blockNumber = 0 + confirmations = 0 + + # TODO: figure out retry / exponential backoff + while retry: + transaction = get_etc_txn_status(txnid, network) + if not transaction: + logging.error('blockscout failed') + elif transaction['has_mined']: + blockNumber = transaction['blockNumber'] + confirmations = transaction['confirmations'] + retry = False + + if blockNumber > 0 and confirmations > 0: + print('transaction has mined') + # TODO: INVOKE FUNCTION TO UPDATE BOUNTY STATE + + response = { + 'status': '200', + 'message': 'success', + 'id': bounty_id, + 'bounty_url': '', + 'blockNumber': blockNumber, + 'confirmations': confirmations + } + + return JsonResponse(response, status=response['status']) + # LEGAL @xframe_options_exempt def terms(request):