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""" """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): class CyclicBlockchainError(BigchainDBError):
"""Raised when there is a cycle in the blockchain""" """Raised when there is a cycle in the blockchain"""
@ -110,3 +106,7 @@ class DuplicateTransaction(ValidationError):
class ThresholdTooDeep(ValidationError): class ThresholdTooDeep(ValidationError):
"""Raised if threshold condition is too deep""" """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 import backend
from bigchaindb.backend.changefeed import ChangeFeed from bigchaindb.backend.changefeed import ChangeFeed
from bigchaindb.models import Transaction from bigchaindb.models import Transaction
from bigchaindb.common.exceptions import ValidationError from bigchaindb.common.exceptions import (ValidationError,
GenesisBlockAlreadyExistsError)
from bigchaindb import Bigchain from bigchaindb import Bigchain
@ -73,6 +74,14 @@ class BlockPipeline:
# If transaction is not valid it should not be included # If transaction is not valid it should not be included
try: 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) tx.validate(self.bigchain)
return tx return tx
except ValidationError as e: except ValidationError as e:

View File

@ -506,3 +506,12 @@ def wsserver_port(wsserver_config):
@pytest.fixture @pytest.fixture
def wsserver_base_url(wsserver_scheme, wsserver_host, wsserver_port): def wsserver_base_url(wsserver_scheme, wsserver_host, wsserver_port):
return '{}://{}:{}'.format(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(signed_transfer_tx)
snowflake.send(create_tx) snowflake.send(create_tx)
assert snowflake.send(None) == [create_tx, signed_transfer_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