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:
parent
c047487523
commit
e8e02cac50
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -58,7 +58,6 @@ definitions:
|
|||
enum:
|
||||
- CREATE
|
||||
- TRANSFER
|
||||
- GENESIS
|
||||
asset:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user