Do not allow duplicate GENESIS block creation - #1556 (#1612)

* Add a check for GENESIS transaction

* Add test and fixture

* Removed database query for GENESIS block

* Undo log level change
This commit is contained in:
Krish 2017-07-03 17:21:15 +02:00 committed by GitHub
parent ece195ff8d
commit e8411fc99e
4 changed files with 34 additions and 5 deletions

View File

@ -19,10 +19,6 @@ class StartupError(BigchainDBError):
"""Raised when there is an error starting up the system"""
class GenesisBlockAlreadyExistsError(BigchainDBError):
"""Raised when trying to create the already existing genesis block"""
class CyclicBlockchainError(BigchainDBError):
"""Raised when there is a cycle in the blockchain"""
@ -110,3 +106,7 @@ class DuplicateTransaction(ValidationError):
class ThresholdTooDeep(ValidationError):
"""Raised if threshold condition is too deep"""
class GenesisBlockAlreadyExistsError(ValidationError):
"""Raised when trying to create the already existing genesis block"""

View File

@ -13,7 +13,8 @@ import bigchaindb
from bigchaindb import backend
from bigchaindb.backend.changefeed import ChangeFeed
from bigchaindb.models import Transaction
from bigchaindb.common.exceptions import ValidationError
from bigchaindb.common.exceptions import (ValidationError,
GenesisBlockAlreadyExistsError)
from bigchaindb import Bigchain
@ -73,6 +74,14 @@ class BlockPipeline:
# If transaction is not valid it should not be included
try:
# Do not allow an externally submitted GENESIS transaction.
# A simple check is enough as a pipeline is started only after the
# creation of GENESIS block, or after the verification of a GENESIS
# block. Voting will fail at a later stage if the GENESIS block is
# absent.
if tx.operation == Transaction.GENESIS:
raise GenesisBlockAlreadyExistsError('Duplicate GENESIS transaction')
tx.validate(self.bigchain)
return tx
except ValidationError as e:

View File

@ -506,3 +506,12 @@ def wsserver_port(wsserver_config):
@pytest.fixture
def wsserver_base_url(wsserver_scheme, wsserver_host, wsserver_port):
return '{}://{}:{}'.format(wsserver_scheme, wsserver_host, wsserver_port)
@pytest.fixture
def genesis_tx(b, user_pk):
from bigchaindb.models import Transaction
tx = Transaction.create([b.me], [([user_pk], 1)])
tx.operation = Transaction.GENESIS
genesis_tx = tx.sign([b.me_private])
return genesis_tx

View File

@ -226,3 +226,14 @@ def test_block_snowflake(create_tx, signed_transfer_tx):
snowflake.send(signed_transfer_tx)
snowflake.send(create_tx)
assert snowflake.send(None) == [create_tx, signed_transfer_tx]
@pytest.mark.bdb
@pytest.mark.genesis
def test_duplicate_genesis_transaction(b, genesis_block, genesis_tx):
# Try to create a duplicate GENESIS transaction
# Expect None as it will be rejected during validation
from bigchaindb.pipelines import block
block_maker = block.BlockPipeline()
assert block_maker.validate_tx(genesis_tx.to_dict()) is None