mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Add CyclicBlockchainError exception, fix tests
This commit is contained in:
parent
6fa9d5f563
commit
553148c5e4
@ -537,6 +537,9 @@ class Bigchain(object):
|
|||||||
invalid_reason (Optional[str]): Reason the block is invalid
|
invalid_reason (Optional[str]): Reason the block is invalid
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if block['id'] == previous_block_id:
|
||||||
|
raise exceptions.CyclicBlockchainError()
|
||||||
|
|
||||||
vote = {
|
vote = {
|
||||||
'voting_for_block': block['id'],
|
'voting_for_block': block['id'],
|
||||||
'previous_block': previous_block_id,
|
'previous_block': previous_block_id,
|
||||||
@ -591,17 +594,16 @@ class Bigchain(object):
|
|||||||
|
|
||||||
# since the resolution of timestamp is a second,
|
# since the resolution of timestamp is a second,
|
||||||
# we might have more than one vote per timestamp
|
# we might have more than one vote per timestamp
|
||||||
if len(last_voted) > 1:
|
mapping = {v['vote']['previous_block']: v['vote']['voting_for_block']
|
||||||
mapping = {v['vote']['previous_block']: v['vote']['voting_for_block']
|
for v in last_voted}
|
||||||
for v in last_voted}
|
last_block_id = list(mapping.values())[0]
|
||||||
last_block_id = list(mapping.values())[0]
|
while True:
|
||||||
while True:
|
try:
|
||||||
try:
|
if last_block_id == mapping[last_block_id]:
|
||||||
last_block_id = mapping[last_block_id]
|
raise exceptions.CyclicBlockchainError()
|
||||||
except KeyError:
|
last_block_id = mapping[last_block_id]
|
||||||
break
|
except KeyError:
|
||||||
else:
|
break
|
||||||
last_block_id = last_voted[0]['vote']['voting_for_block']
|
|
||||||
|
|
||||||
res = r.table('bigchain').get(last_block_id).run(self.conn)
|
res = r.table('bigchain').get(last_block_id).run(self.conn)
|
||||||
|
|
||||||
|
@ -56,3 +56,7 @@ class MultipleVotesError(Exception):
|
|||||||
|
|
||||||
class GenesisBlockAlreadyExistsError(Exception):
|
class GenesisBlockAlreadyExistsError(Exception):
|
||||||
"""Raised when trying to create the already existing genesis block"""
|
"""Raised when trying to create the already existing genesis block"""
|
||||||
|
|
||||||
|
|
||||||
|
class CyclicBlockchainError(Exception):
|
||||||
|
"""Raised when there is a cycle in the blockchain"""
|
||||||
|
@ -315,17 +315,17 @@ class TestBigchainApi(object):
|
|||||||
assert b.get_last_voted_block()['id'] == block_3['id']
|
assert b.get_last_voted_block()['id'] == block_3['id']
|
||||||
|
|
||||||
def test_no_vote_written_if_block_already_has_vote(self, b):
|
def test_no_vote_written_if_block_already_has_vote(self, b):
|
||||||
b.create_genesis_block()
|
genesis = b.create_genesis_block()
|
||||||
|
|
||||||
block_1 = dummy_block()
|
block_1 = dummy_block()
|
||||||
|
|
||||||
b.write_block(block_1, durability='hard')
|
b.write_block(block_1, durability='hard')
|
||||||
|
|
||||||
b.write_vote(block_1, b.vote(block_1, b.get_last_voted_block()['id'], True))
|
b.write_vote(block_1, b.vote(block_1, genesis['id'], True))
|
||||||
retrieved_block_1 = r.table('bigchain').get(block_1['id']).run(b.conn)
|
retrieved_block_1 = r.table('bigchain').get(block_1['id']).run(b.conn)
|
||||||
|
|
||||||
# try to vote again on the retrieved block, should do nothing
|
# try to vote again on the retrieved block, should do nothing
|
||||||
b.write_vote(retrieved_block_1, b.vote(retrieved_block_1, b.get_last_voted_block()['id'], True))
|
b.write_vote(retrieved_block_1, b.vote(retrieved_block_1, genesis['id'], True))
|
||||||
retrieved_block_2 = r.table('bigchain').get(block_1['id']).run(b.conn)
|
retrieved_block_2 = r.table('bigchain').get(block_1['id']).run(b.conn)
|
||||||
|
|
||||||
assert retrieved_block_1 == retrieved_block_2
|
assert retrieved_block_1 == retrieved_block_2
|
||||||
@ -348,12 +348,12 @@ class TestBigchainApi(object):
|
|||||||
.format(block_id=block_1['id'], n_votes=str(2), n_voters=str(1))
|
.format(block_id=block_1['id'], n_votes=str(2), n_voters=str(1))
|
||||||
|
|
||||||
def test_multiple_votes_single_node(self, b):
|
def test_multiple_votes_single_node(self, b):
|
||||||
b.create_genesis_block()
|
genesis = b.create_genesis_block()
|
||||||
block_1 = dummy_block()
|
block_1 = dummy_block()
|
||||||
b.write_block(block_1, durability='hard')
|
b.write_block(block_1, durability='hard')
|
||||||
# insert duplicate votes
|
# insert duplicate votes
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
r.table('votes').insert(b.vote(block_1, b.get_last_voted_block()['id'], True)).run(b.conn)
|
r.table('votes').insert(b.vote(block_1, genesis['id'], True)).run(b.conn)
|
||||||
|
|
||||||
from bigchaindb.exceptions import MultipleVotesError
|
from bigchaindb.exceptions import MultipleVotesError
|
||||||
with pytest.raises(MultipleVotesError) as excinfo:
|
with pytest.raises(MultipleVotesError) as excinfo:
|
||||||
@ -1215,6 +1215,7 @@ class TestMultipleInputs(object):
|
|||||||
assert owned_inputs_user2 == [{'cid': 0, 'txid': tx['id']}]
|
assert owned_inputs_user2 == [{'cid': 0, 'txid': tx['id']}]
|
||||||
|
|
||||||
def test_get_owned_ids_single_tx_single_output_invalid_block(self, b, user_sk, user_vk):
|
def test_get_owned_ids_single_tx_single_output_invalid_block(self, b, user_sk, user_vk):
|
||||||
|
genesis = b.create_genesis_block()
|
||||||
# create a new users
|
# create a new users
|
||||||
user2_sk, user2_vk = crypto.generate_key_pair()
|
user2_sk, user2_vk = crypto.generate_key_pair()
|
||||||
|
|
||||||
@ -1225,7 +1226,7 @@ class TestMultipleInputs(object):
|
|||||||
b.write_block(block, durability='hard')
|
b.write_block(block, durability='hard')
|
||||||
|
|
||||||
# vote the block VALID
|
# vote the block VALID
|
||||||
vote = b.vote(block, b.get_unvoted_blocks()[0]['id'], True)
|
vote = b.vote(block, genesis['id'], True)
|
||||||
b.write_vote(block, vote)
|
b.write_vote(block, vote)
|
||||||
|
|
||||||
# get input
|
# get input
|
||||||
@ -1343,6 +1344,8 @@ class TestMultipleInputs(object):
|
|||||||
assert spent_inputs_user1 == tx_signed
|
assert spent_inputs_user1 == tx_signed
|
||||||
|
|
||||||
def test_get_spent_single_tx_single_output_invalid_block(self, b, user_sk, user_vk):
|
def test_get_spent_single_tx_single_output_invalid_block(self, b, user_sk, user_vk):
|
||||||
|
genesis = b.create_genesis_block()
|
||||||
|
|
||||||
# create a new users
|
# create a new users
|
||||||
user2_sk, user2_vk = crypto.generate_key_pair()
|
user2_sk, user2_vk = crypto.generate_key_pair()
|
||||||
|
|
||||||
@ -1353,7 +1356,7 @@ class TestMultipleInputs(object):
|
|||||||
b.write_block(block, durability='hard')
|
b.write_block(block, durability='hard')
|
||||||
|
|
||||||
# vote the block VALID
|
# vote the block VALID
|
||||||
vote = b.vote(block, b.get_unvoted_blocks()[0]['id'], True)
|
vote = b.vote(block, genesis['id'], True)
|
||||||
b.write_vote(block, vote)
|
b.write_vote(block, vote)
|
||||||
|
|
||||||
# get input
|
# get input
|
||||||
|
Loading…
x
Reference in New Issue
Block a user