validate_block now checks if a federation node created the block.

It checks to see if node_pubkey is a federation node and if the
signature is correct.

Created tests
This commit is contained in:
Rodolphe Marques 2016-04-28 13:54:50 +02:00
parent ec0662bdc7
commit 1813c26879
2 changed files with 40 additions and 1 deletions

View File

@ -167,7 +167,6 @@ class BaseConsensusRules(AbstractConsensusRules):
return transaction return transaction
# TODO: Unsure if a bigchain parameter is really necessary here?
@staticmethod @staticmethod
def validate_block(bigchain, block): def validate_block(bigchain, block):
"""Validate a block. """Validate a block.
@ -189,6 +188,15 @@ class BaseConsensusRules(AbstractConsensusRules):
if calculated_hash != block['id']: if calculated_hash != block['id']:
raise exceptions.InvalidHash() raise exceptions.InvalidHash()
# Check if the block was created by a federation node
if block['block']['node_pubkey'] not in (bigchain.federation_nodes + [bigchain.me]):
raise exceptions.OperationError('Only federation nodes can create blocks')
# Check if block signature is valid
verifying_key = crypto.VerifyingKey(block['block']['node_pubkey'])
if not verifying_key.verify(util.serialize(block['block']), block['signature']):
raise exceptions.InvalidSignature('Invalid block signature')
return block return block
@staticmethod @staticmethod

View File

@ -407,6 +407,37 @@ class TestBlockValidation(object):
assert block == b.validate_block(block) assert block == b.validate_block(block)
assert b.is_valid_block(block) assert b.is_valid_block(block)
def test_invalid_signature(self, b):
# create a valid block
block = b.create_block([])
# replace the block signature with an invalid one
block['signature'] = crypto.SigningKey(b.me_private).sign(b'wrongdata')
# check that validate_block raises an InvalidSignature exception
with pytest.raises(exceptions.InvalidSignature):
b.validate_block(block)
def test_invalid_node_pubkey(self, b):
# blocks can only be created by a federation node
# create a valid block
block = b.create_block([])
# create some temp keys
tmp_sk, tmp_vk = crypto.generate_key_pair()
# change the block node_pubkey
block['block']['node_pubkey'] = tmp_vk
# just to make sure lets re-hash the block and create a valid signature
# from a non federation node
block['id'] = crypto.hash_data(util.serialize(block['block']))
block['signature'] = crypto.SigningKey(tmp_sk).sign(util.serialize(block['block']))
# check that validate_block raises an OperationError
with pytest.raises(exceptions.OperationError):
b.validate_block(block)
class TestBigchainVoter(object): class TestBigchainVoter(object):