1
0
mirror of https://github.com/bigchaindb/bigchaindb.git synced 2024-06-28 00:27:45 +02:00

Problem: Bigchaindb startup sometimes fails due genesis block creation during init (#2129)

* removing GENESIS transaction type
* remove GENESIS transaction schema
* all blocks are same in the eyes of GOD no checks needed for genesis blocks
This commit is contained in:
Shahbaz Nazir 2018-03-16 16:19:12 +01:00 committed by vrde
parent c047487523
commit e8e02cac50
8 changed files with 17 additions and 51 deletions

View File

@ -93,12 +93,9 @@ def run_configure(args):
def _run_init():
b = bigchaindb.Bigchain()
bdb = bigchaindb.Bigchain()
schema.init_database(connection=b.connection)
b.create_genesis_block()
logger.info('Genesis block created.')
schema.init_database(connection=bdb.connection)
@configure_bigchaindb

View File

@ -1,7 +1,7 @@
---
"$schema": "http://json-schema.org/draft-04/schema#"
type: object
title: Transaction Schema - CREATE/GENESIS specific constraints
title: Transaction Schema - CREATE specific constraints
required:
- asset
- inputs

View File

@ -58,7 +58,6 @@ definitions:
enum:
- CREATE
- TRANSFER
- GENESIS
asset:
type: object
additionalProperties: false

View File

@ -480,8 +480,8 @@ class Transaction(object):
spend.
outputs (:obj:`list` of :class:`~bigchaindb.common.
transaction.Output`, optional): Define the assets to lock.
asset (dict): Asset payload for this Transaction. ``CREATE`` and
``GENESIS`` Transactions require a dict with a ``data``
asset (dict): Asset payload for this Transaction. ``CREATE``
Transactions require a dict with a ``data``
property while ``TRANSFER`` Transactions require a dict with a
``id`` property.
metadata (dict):
@ -491,8 +491,7 @@ class Transaction(object):
CREATE = 'CREATE'
TRANSFER = 'TRANSFER'
GENESIS = 'GENESIS'
ALLOWED_OPERATIONS = (CREATE, TRANSFER, GENESIS)
ALLOWED_OPERATIONS = (CREATE, TRANSFER)
VERSION = '2.0'
def __init__(self, operation, asset, inputs=None, outputs=None,
@ -521,10 +520,10 @@ class Transaction(object):
raise ValueError('`operation` must be one of {}'
.format(allowed_ops))
# Asset payloads for 'CREATE' and 'GENESIS' operations must be None or
# Asset payloads for 'CREATE' operations must be None or
# dicts holding a `data` property. Asset payloads for 'TRANSFER'
# operations must be dicts holding an `id` property.
if (operation in [Transaction.CREATE, Transaction.GENESIS] and
if (operation == Transaction.CREATE and
asset is not None and not (isinstance(asset, dict) and 'data' in asset)):
raise TypeError(('`asset` must be None or a dict holding a `data` '
" property instance for '{}' Transactions".format(operation)))
@ -928,7 +927,7 @@ class Transaction(object):
Outputs.
Note:
Given a `CREATE` or `GENESIS` Transaction is passed,
Given a `CREATE` Transaction is passed,
dummy values for Outputs are submitted for validation that
evaluate parts of the validation-checks to `True`.
@ -940,7 +939,7 @@ class Transaction(object):
Returns:
bool: If all Inputs are valid.
"""
if self.operation in (Transaction.CREATE, Transaction.GENESIS):
if self.operation == Transaction.CREATE:
# NOTE: Since in the case of a `CREATE`-transaction we do not have
# to check for outputs, we're just submitting dummy
# values to the actual method. This simplifies it's logic
@ -992,7 +991,7 @@ class Transaction(object):
"""Validates a single Input against a single Output.
Note:
In case of a `CREATE` or `GENESIS` Transaction, this method
In case of a `CREATE` Transaction, this method
does not validate against `output_condition_uri`.
Args:
@ -1013,8 +1012,8 @@ class Transaction(object):
ParsingError, ASN1DecodeError, ASN1EncodeError):
return False
if operation in (Transaction.CREATE, Transaction.GENESIS):
# NOTE: In the case of a `CREATE` or `GENESIS` transaction, the
if operation == Transaction.CREATE:
# NOTE: In the case of a `CREATE` transaction, the
# output is always valid.
output_valid = True
else:

View File

@ -131,7 +131,7 @@ class Transaction(Transaction):
for tx in tx_dict_list:
tx.update({'metadata': None})
tx_map[tx['id']] = tx
if tx['operation'] in [Transaction.CREATE, Transaction.GENESIS]:
if tx['operation'] == Transaction.CREATE:
tx_ids.append(tx['id'])
assets = list(bigchain.get_assets(tx_ids))
@ -411,8 +411,7 @@ class Block(object):
assets = []
for transaction in block_dict['block']['transactions']:
if transaction['operation'] in [Transaction.CREATE,
Transaction.GENESIS]:
if transaction['operation'] == Transaction.CREATE:
asset = transaction.pop('asset')
asset.update({'id': transaction['id']})
assets.append(asset)
@ -458,8 +457,7 @@ class Block(object):
assets = {asset.pop('id'): asset for asset in assets}
# add the assets to the block transactions
for transaction in block_dict['block']['transactions']:
if transaction['operation'] in [Transaction.CREATE,
Transaction.GENESIS]:
if transaction['operation'] == Transaction.CREATE:
transaction.update({'asset': assets.get(transaction['id'])})
return block_dict
@ -506,8 +504,7 @@ class Block(object):
"""
asset_ids = []
for transaction in block_dict['block']['transactions']:
if transaction['operation'] in [Transaction.CREATE,
Transaction.GENESIS]:
if transaction['operation'] == Transaction.CREATE:
asset_ids.append(transaction['id'])
return asset_ids

View File

@ -123,25 +123,6 @@ def condition_details_has_owner(condition_details, owner):
return False
def is_genesis_block(block):
"""Check if the block is the genesis block.
Args:
block (dict | Block): the block to check
Returns:
bool: True if the block is the genesis block, False otherwise.
"""
# we cannot have empty blocks, there will always be at least one
# element in the list so we can safely refer to it
# TODO: Remove this try-except and only handle `Block` as input
try:
return block.transactions[0].operation == 'GENESIS'
except AttributeError:
return block['block']['transactions'][0]['operation'] == 'GENESIS'
class Lazy:
"""Lazy objects are useful to create chains of methods to
execute later.

View File

@ -99,7 +99,6 @@ def test__run_init(mocker):
bigchain_mock.assert_called_once_with()
init_db_mock.assert_called_once_with(
connection=bigchain_mock.return_value.connection)
bigchain_mock.return_value.create_genesis_block.assert_called_once_with()
@pytest.mark.tendermint

View File

@ -135,12 +135,6 @@ def test_process_group_instantiates_and_start_processes(mock_process):
process.start.assert_called_with()
def test_is_genesis_block_returns_true_if_genesis(b):
from bigchaindb.utils import is_genesis_block
genesis_block = b.prepare_genesis_block()
assert is_genesis_block(genesis_block)
def test_lazy_execution():
from bigchaindb.utils import Lazy