From 8be9ea0dc1fa0915f40250cad222710bb784854d Mon Sep 17 00:00:00 2001 From: Lev Berman Date: Tue, 4 Sep 2018 14:39:53 +0200 Subject: [PATCH] Problem: The commit mode behaves incorrectly. Solution: Parse the Tendermint response properly. The functionality was disabled in https://github.com/bigchaindb/bigchaindb/pull/2235/files#diff-c6511560546a7dc577e7e647b5bfdaceL68 and was not fixed since then. --- bigchaindb/lib.py | 39 ++++++++++++---------------- tests/tendermint/test_integration.py | 18 ++++++------- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/bigchaindb/lib.py b/bigchaindb/lib.py index fa72a506..40bf4044 100644 --- a/bigchaindb/lib.py +++ b/bigchaindb/lib.py @@ -55,9 +55,10 @@ class BigchainDB(object): A connection to the database. """ config_utils.autoconfigure() + self.mode_commit = 'broadcast_tx_commit' self.mode_list = ('broadcast_tx_async', 'broadcast_tx_sync', - 'broadcast_tx_commit') + self.mode_commit) self.tendermint_host = bigchaindb.config['tendermint']['host'] self.tendermint_port = bigchaindb.config['tendermint']['port'] self.endpoint = 'http://{}:{}/'.format(self.tendermint_host, self.tendermint_port) @@ -94,29 +95,23 @@ class BigchainDB(object): def _process_post_response(self, response, mode): logger.debug(response) - if response.get('error') is not None: - return (500, 'Internal error') + + result = response['result'] + if mode == self.mode_commit: + check_tx_code = result.get('check_tx', {}).get('code', 0) + deliver_tx_code = result['deliver_tx'].get('code', 0) + error_code = check_tx_code or deliver_tx_code + else: + error_code = result.get('code', 0) + + error = response.get('error') + if error: + return (500, error) + + if error_code: + return (500, 'Transaction validation failed') return (202, '') - # result = response['result'] - # if mode == self.mode_list[2]: - # return self._process_commit_mode_response(result) - # else: - # status_code = result['code'] - # return self._process_status_code(status_code, - # 'Error while processing transaction') - - # def _process_commit_mode_response(self, result): - # check_tx_status_code = result['check_tx']['code'] - # if check_tx_status_code == 0: - # deliver_tx_status_code = result['deliver_tx']['code'] - # return self._process_status_code(deliver_tx_status_code, - # 'Error while commiting the transaction') - # else: - # return (500, 'Error while validating the transaction') - - def process_status_code(self, status_code, failure_msg): - return (202, '') if status_code == 0 else (500, failure_msg) def store_bulk_transactions(self, transactions): txns = [] diff --git a/tests/tendermint/test_integration.py b/tests/tendermint/test_integration.py index 683404bc..a009bd40 100644 --- a/tests/tendermint/test_integration.py +++ b/tests/tendermint/test_integration.py @@ -130,12 +130,12 @@ def test_post_transaction_responses(tendermint_ws_url, b): code, message = b.write_transaction(tx_transfer, 'broadcast_tx_commit') assert code == 202 - # NOTE: DOESN'T WORK (double spend) - # Tendermint crashes with error: Unexpected result type - # carly = generate_key_pair() - # double_spend = Transaction.transfer(tx.to_inputs(), - # [([carly.public_key], 1)], - # asset_id=tx.id)\ - # .sign([alice.private_key]) - # code, message = b.write_transaction(double_spend, 'broadcast_tx_commit') - # assert code == 500 + carly = generate_key_pair() + double_spend = Transaction.transfer( + tx.to_inputs(), + [([carly.public_key], 1)], + asset_id=tx.id, + ).sign([alice.private_key]) + code, message = b.write_transaction(double_spend, 'broadcast_tx_commit') + assert code == 500 + assert message == 'Transaction validation failed'