break BigchainDBCritical into CriticalDoubleSpend and CriticalDoubleInclusion and add test

This commit is contained in:
Scott Sadler 2017-03-03 13:48:52 +01:00
parent 59e21bfa4d
commit 3346fcb47b
3 changed files with 47 additions and 8 deletions

View File

@ -17,5 +17,9 @@ class DuplicateKeyError(OperationError):
"""Exception raised when an insert fails because the key is not unique""" """Exception raised when an insert fails because the key is not unique"""
class BigchainDBCritical(Exception): class CriticalDoubleSpend(BigchainDBError):
"""Unhandleable error that requires attention""" """Data integrity error that requires attention"""
class CriticalDoubleInclusion(BigchainDBError):
"""Data integrity error that requires attention"""

View File

@ -308,7 +308,7 @@ class Bigchain(object):
if list(validity.values()).count(Bigchain.BLOCK_VALID) > 1: if list(validity.values()).count(Bigchain.BLOCK_VALID) > 1:
block_ids = str([block for block in validity block_ids = str([block for block in validity
if validity[block] == Bigchain.BLOCK_VALID]) if validity[block] == Bigchain.BLOCK_VALID])
raise backend_exceptions.BigchainDBCritical( raise backend_exceptions.CriticalDoubleInclusion(
'Transaction {tx} is present in ' 'Transaction {tx} is present in '
'multiple valid blocks: {block_ids}' 'multiple valid blocks: {block_ids}'
.format(tx=txid, block_ids=block_ids)) .format(tx=txid, block_ids=block_ids))
@ -361,7 +361,7 @@ class Bigchain(object):
if self.get_transaction(transaction['id']): if self.get_transaction(transaction['id']):
num_valid_transactions += 1 num_valid_transactions += 1
if num_valid_transactions > 1: if num_valid_transactions > 1:
raise exceptions.BigchainDBCritical( raise backend_exceptions.CriticalDoubleSpend(
'`{}` was spent more than once. There is a problem' '`{}` was spent more than once. There is a problem'
' with the chain'.format(txid)) ' with the chain'.format(txid))

View File

@ -93,7 +93,7 @@ class TestBigchainApi(object):
@pytest.mark.genesis @pytest.mark.genesis
def test_get_spent_with_double_inclusion_detected(self, b, monkeypatch): def test_get_spent_with_double_inclusion_detected(self, b, monkeypatch):
from bigchaindb.backend.exceptions import BigchainDBCritical from bigchaindb.backend.exceptions import CriticalDoubleInclusion
from bigchaindb.models import Transaction from bigchaindb.models import Transaction
tx = Transaction.create([b.me], [([b.me], 1)]) tx = Transaction.create([b.me], [([b.me], 1)])
@ -123,12 +123,47 @@ class TestBigchainApi(object):
vote = b.vote(block3.id, b.get_last_voted_block().id, True) vote = b.vote(block3.id, b.get_last_voted_block().id, True)
b.write_vote(vote) b.write_vote(vote)
with pytest.raises(BigchainDBCritical): with pytest.raises(CriticalDoubleInclusion):
b.get_spent(tx.id, 0)
@pytest.mark.genesis
def test_get_spent_with_double_spend_detected(self, b, monkeypatch):
from bigchaindb.backend.exceptions import CriticalDoubleSpend
from bigchaindb.models import Transaction
tx = Transaction.create([b.me], [([b.me], 1)])
tx = tx.sign([b.me_private])
monkeypatch.setattr('time.time', lambda: 1000000000)
block1 = b.create_block([tx])
b.write_block(block1)
monkeypatch.setattr('time.time', lambda: 1000000020)
transfer_tx = Transaction.transfer(tx.to_inputs(), [([b.me], 1)],
asset_id=tx.id)
transfer_tx = transfer_tx.sign([b.me_private])
block2 = b.create_block([transfer_tx])
b.write_block(block2)
monkeypatch.setattr('time.time', lambda: 1000000030)
transfer_tx2 = Transaction.transfer(tx.to_inputs(), [([b.me], 2)],
asset_id=tx.id)
transfer_tx2 = transfer_tx2.sign([b.me_private])
block3 = b.create_block([transfer_tx2])
b.write_block(block3)
# Vote both block2 and block3 valid
vote = b.vote(block2.id, b.get_last_voted_block().id, True)
b.write_vote(vote)
vote = b.vote(block3.id, b.get_last_voted_block().id, True)
b.write_vote(vote)
with pytest.raises(CriticalDoubleSpend):
b.get_spent(tx.id, 0) b.get_spent(tx.id, 0)
@pytest.mark.genesis @pytest.mark.genesis
def test_get_block_status_for_tx_with_double_inclusion(self, b, monkeypatch): def test_get_block_status_for_tx_with_double_inclusion(self, b, monkeypatch):
from bigchaindb.backend.exceptions import BigchainDBCritical from bigchaindb.backend.exceptions import CriticalDoubleInclusion
from bigchaindb.models import Transaction from bigchaindb.models import Transaction
tx = Transaction.create([b.me], [([b.me], 1)]) tx = Transaction.create([b.me], [([b.me], 1)])
@ -148,7 +183,7 @@ class TestBigchainApi(object):
vote = b.vote(block2.id, b.get_last_voted_block().id, True) vote = b.vote(block2.id, b.get_last_voted_block().id, True)
b.write_vote(vote) b.write_vote(vote)
with pytest.raises(BigchainDBCritical): with pytest.raises(CriticalDoubleInclusion):
b.get_blocks_status_containing_tx(tx.id) b.get_blocks_status_containing_tx(tx.id)
@pytest.mark.genesis @pytest.mark.genesis