Skip to content

Commit

Permalink
Problem: The commit mode behaves incorrectly. (#2510)
Browse files Browse the repository at this point in the history
* 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.

* Add a test case for the sync mode.

* Do not strictly expect deliver_tx in the response.

* Fix post_mock in web/test_transactions.py.

* Check for the error field first.
  • Loading branch information
ldmberman authored and ttmc committed Sep 6, 2018
1 parent 2656302 commit 6994946
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 31 deletions.
39 changes: 17 additions & 22 deletions bigchaindb/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ def __init__(self, connection=None):
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)
Expand Down Expand Up @@ -96,29 +97,23 @@ def write_transaction(self, transaction, mode):

def _process_post_response(self, response, mode):
logger.debug(response)
if response.get('error') is not None:
return (500, 'Internal error')

error = response.get('error')
if error:
return (500, error)

result = response['result']
if mode == self.mode_commit:
check_tx_code = result.get('check_tx', {}).get('code', 0)
deliver_tx_code = result.get('deliver_tx', {}).get('code', 0)
error_code = check_tx_code or deliver_tx_code
else:
error_code = result.get('code', 0)

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 = []
Expand Down
19 changes: 10 additions & 9 deletions tests/tendermint/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,13 @@ 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])
for mode in ('broadcast_tx_sync', 'broadcast_tx_commit'):
code, message = b.write_transaction(double_spend, mode)
assert code == 500
assert message == 'Transaction validation failed'
6 changes: 6 additions & 0 deletions tests/web/test_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,12 @@ def should_not_be_called():
def test_post_transaction_valid_modes(mock_post, client, mode):
from bigchaindb.models import Transaction
from bigchaindb.common.crypto import generate_key_pair

def _mock_post(*args, **kwargs):
return Mock(json=Mock(return_value={'result': {'code': 0}}))

mock_post.side_effect = _mock_post

alice = generate_key_pair()
tx = Transaction.create([alice.public_key],
[([alice.public_key], 1)],
Expand Down

0 comments on commit 6994946

Please sign in to comment.