mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Removed duplicated transaction validation in votes pipeline.
Separated block validation from transaction validation. Refactored block signature validation.
This commit is contained in:
parent
d49b06933a
commit
6b073f0898
@ -203,6 +203,12 @@ class Block(object):
|
||||
InvalidSignature: If a Block's signature is invalid.
|
||||
"""
|
||||
|
||||
self._validate_block(bigchain)
|
||||
self._validate_block_transactions(bigchain)
|
||||
|
||||
return self
|
||||
|
||||
def _validate_block(self, bigchain):
|
||||
# First, make sure this node hasn't already voted on this block
|
||||
if bigchain.has_previous_vote(self.id, self.voters):
|
||||
return self
|
||||
@ -212,18 +218,16 @@ class Block(object):
|
||||
if self.node_pubkey not in possible_voters:
|
||||
raise OperationError('Only federation nodes can create blocks')
|
||||
|
||||
# Check that the signature is valid
|
||||
if not self.is_signature_valid():
|
||||
raise InvalidSignature('Block signature invalid')
|
||||
raise InvalidSignature('Invalid block signature')
|
||||
|
||||
# Finally: Tentative assumption that every blockchain will want to
|
||||
# validate all transactions in each block
|
||||
def _validate_block_transactions(self, bigchain):
|
||||
for tx in self.transactions:
|
||||
# NOTE: If a transaction is not valid, `is_valid` will throw an
|
||||
# an exception and block validation will be canceled.
|
||||
# If a transaction is not valid, `validate_transactions` will
|
||||
# throw an an exception and block validation will be canceled.
|
||||
bigchain.validate_transaction(tx)
|
||||
|
||||
return self
|
||||
|
||||
def sign(self, private_key):
|
||||
"""Create a signature for the Block and overwrite `self.signature`.
|
||||
|
||||
@ -273,34 +277,19 @@ class Block(object):
|
||||
InvalidSignature: If the block's signature is not corresponding
|
||||
to it's data or `node_pubkey`.
|
||||
"""
|
||||
# TODO: Reuse `is_signature_valid` method here.
|
||||
# Validate block id
|
||||
block = block_body['block']
|
||||
block_serialized = serialize(block)
|
||||
block_id = hash_data(block_serialized)
|
||||
public_key = PublicKey(block['node_pubkey'])
|
||||
|
||||
try:
|
||||
signature = block_body['signature']
|
||||
except KeyError:
|
||||
signature = None
|
||||
|
||||
if block_id != block_body['id']:
|
||||
raise InvalidHash()
|
||||
|
||||
if signature is not None:
|
||||
# NOTE: CC throws a `ValueError` on some wrong signatures
|
||||
# https://github.com/bigchaindb/cryptoconditions/issues/27
|
||||
try:
|
||||
signature_valid = public_key\
|
||||
.verify(block_serialized.encode(), signature)
|
||||
except ValueError:
|
||||
signature_valid = False
|
||||
if signature_valid is False:
|
||||
raise InvalidSignature('Invalid block signature')
|
||||
|
||||
transactions = [Transaction.from_dict(tx) for tx
|
||||
in block['transactions']]
|
||||
|
||||
signature = block_body.get('signature')
|
||||
|
||||
return cls(transactions, block['node_pubkey'],
|
||||
block['timestamp'], block['voters'], signature)
|
||||
|
||||
|
@ -53,7 +53,7 @@ class Vote:
|
||||
block['block']['voters']):
|
||||
try:
|
||||
block = Block.from_dict(block)
|
||||
except (exceptions.InvalidHash, exceptions.InvalidSignature):
|
||||
except (exceptions.InvalidHash):
|
||||
# XXX: if a block is invalid we should skip the `validate_tx`
|
||||
# step, but since we are in a pipeline we cannot just jump to
|
||||
# another function. Hackish solution: generate an invalid
|
||||
@ -61,10 +61,8 @@ class Vote:
|
||||
# pipeline.
|
||||
return block['id'], [self.invalid_dummy_tx]
|
||||
try:
|
||||
self.consensus.validate_block(self.bigchain, block)
|
||||
except (exceptions.InvalidHash,
|
||||
exceptions.OperationError,
|
||||
exceptions.InvalidSignature):
|
||||
block._validate_block(self.bigchain)
|
||||
except (exceptions.OperationError, exceptions.InvalidSignature):
|
||||
# XXX: if a block is invalid we should skip the `validate_tx`
|
||||
# step, but since we are in a pipeline we cannot just jump to
|
||||
# another function. Hackish solution: generate an invalid
|
||||
|
@ -107,7 +107,7 @@ class TestBlockModel(object):
|
||||
with raises(InvalidHash):
|
||||
Block.from_dict(block)
|
||||
|
||||
def test_block_invalid_signature_deserialization(self, b):
|
||||
def test_block_invalid_signature(self, b):
|
||||
from bigchaindb.common.crypto import hash_data
|
||||
from bigchaindb.common.exceptions import InvalidSignature
|
||||
from bigchaindb.common.utils import gen_timestamp, serialize
|
||||
@ -131,7 +131,7 @@ class TestBlockModel(object):
|
||||
}
|
||||
|
||||
with raises(InvalidSignature):
|
||||
Block.from_dict(block_body)
|
||||
Block.from_dict(block_body).validate(b)
|
||||
|
||||
def test_compare_blocks(self, b):
|
||||
from bigchaindb.models import Block, Transaction
|
||||
|
Loading…
x
Reference in New Issue
Block a user