mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Merge remote-tracking branch 'ssh_upstream/master' into 21/validator_election
This commit is contained in:
commit
610e4bad9c
53
CHANGELOG.md
53
CHANGELOG.md
@ -18,6 +18,59 @@ For reference, the possible headings are:
|
||||
* **Known Issues**
|
||||
* **Notes**
|
||||
|
||||
## [2.0 Beta 3] - 2018-07-18
|
||||
|
||||
Tag name: v2.0.0b3
|
||||
|
||||
### Fixed
|
||||
|
||||
Fixed a bug in transaction validation. For some more-complex situations, it would say that a valid transaction was invalid. This bug was actually fixed before; it was [issue #1271](https://github.com/bigchaindb/bigchaindb/issues/1271). The unit test for it was turned off while we integrated Tendermint. Then the query implementation code got changed, reintroducing the bug, but the unit test was off so the bug wasn't caught. When we turned the test back on, shortly after releasing Beta 2, it failed, unveiling the bug. [Pull request #2389](https://github.com/bigchaindb/bigchaindb/pull/2389)
|
||||
|
||||
## [2.0 Beta 2] - 2018-07-16
|
||||
|
||||
Tag name: v2.0.0b2
|
||||
|
||||
### Added
|
||||
|
||||
* Added new configuration settings `tendermint.host` and `tendermint.port`. [Pull request #2342](https://github.com/bigchaindb/bigchaindb/pull/2342)
|
||||
* Added tests to ensure that BigchainDB gracefully handles "nasty" strings in keys and values. [Pull request #2334](https://github.com/bigchaindb/bigchaindb/pull/2334)
|
||||
* Added a new logging handler to capture benchmark stats to a separate file. [Pull request #2349](https://github.com/bigchaindb/bigchaindb/pull/2349)
|
||||
|
||||
### Changed
|
||||
|
||||
* Changed the names of BigchainDB processes (Python processes) to include 'bigchaindb', so they are easier to spot and find. [Pull request #2354](https://github.com/bigchaindb/bigchaindb/pull/2354)
|
||||
* Updated all code to support the latest version of Tendermint. Note that the BigchainDB ABCI server now listens to port 26657 instead of 46657. Pull requests [#2375](https://github.com/bigchaindb/bigchaindb/pull/2375) and [#2380](https://github.com/bigchaindb/bigchaindb/pull/2380)
|
||||
|
||||
### Removed
|
||||
|
||||
Removed all support and code for the old backlog_reassign_delay setting. [Pull request #2332](https://github.com/bigchaindb/bigchaindb/pull/2332)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed a bug that sometimes arose when using Docker Compose. (Tendermint would freeze.) [Pull request #2341](https://github.com/bigchaindb/bigchaindb/pull/2341)
|
||||
* Fixed a bug in the code that creates a MongoDB index for the "id" in the transactions collection. It works now, and performance is improved. [Pull request #2378](https://github.com/bigchaindb/bigchaindb/pull/2378)
|
||||
* The logging server would keep runnning in some tear-down scenarios. It doesn't do that any more. [Pull request #2304](https://github.com/bigchaindb/bigchaindb/pull/2304)
|
||||
|
||||
### External Contributors
|
||||
|
||||
@hrntknr - [Pull request #2331](https://github.com/bigchaindb/bigchaindb/pull/2331)
|
||||
|
||||
### Known Issues
|
||||
|
||||
The `bigchaindb upsert-validator` subcommand is not working yet, but a solution ([BEP-21](https://github.com/bigchaindb/BEPs/tree/master/21)) has been finalized and will be implemented before we release the final BigchainDB 2.0.
|
||||
|
||||
### Notes
|
||||
|
||||
* A lot of old/dead code was deleted. Pull requests
|
||||
[#2319](https://github.com/bigchaindb/bigchaindb/pull/2319),
|
||||
[#2338](https://github.com/bigchaindb/bigchaindb/pull/2338),
|
||||
[#2357](https://github.com/bigchaindb/bigchaindb/pull/2357),
|
||||
[#2365](https://github.com/bigchaindb/bigchaindb/pull/2365),
|
||||
[#2366](https://github.com/bigchaindb/bigchaindb/pull/2366),
|
||||
[#2368](https://github.com/bigchaindb/bigchaindb/pull/2368) and
|
||||
[#2374](https://github.com/bigchaindb/bigchaindb/pull/2374)
|
||||
* Improved the documentation page "How to setup a BigchainDB Network". [Pull Request #2312](https://github.com/bigchaindb/bigchaindb/pull/2312)
|
||||
|
||||
## [2.0 Beta 1] - 2018-06-01
|
||||
|
||||
Tag name: v2.0.0b1
|
||||
|
||||
@ -4,7 +4,7 @@ A high-level description of the files and subdirectories of BigchainDB.
|
||||
|
||||
## Files
|
||||
|
||||
### [`tendermint/lib.py`](./tendermint/lib.py)
|
||||
### [`lib.py`](lib.py)
|
||||
|
||||
The `BigchainDB` class is defined here. Most node-level operations and database interactions are found in this file. This is the place to start if you are interested in implementing a server API, since many of these class methods concern BigchainDB interacting with the outside world.
|
||||
|
||||
|
||||
@ -2,6 +2,9 @@ import copy
|
||||
import logging
|
||||
|
||||
from bigchaindb.log import DEFAULT_LOGGING_CONFIG as log_config
|
||||
from bigchaindb.lib import BigchainDB # noqa
|
||||
from bigchaindb.version import __version__ # noqa
|
||||
from bigchaindb.core import App # noqa
|
||||
|
||||
# from functools import reduce
|
||||
# PORT_NUMBER = reduce(lambda x, y: x * y, map(ord, 'BigchainDB')) % 2**16
|
||||
@ -84,13 +87,10 @@ config = {
|
||||
# the user wants to reconfigure the node. Check ``bigchaindb.config_utils``
|
||||
# for more info.
|
||||
_config = copy.deepcopy(config)
|
||||
from bigchaindb.tendermint import BigchainDB # noqa
|
||||
from bigchaindb.version import __version__ # noqa
|
||||
from bigchaindb.common.transaction import Transaction # noqa
|
||||
from bigchaindb import models # noqa
|
||||
from bigchaindb.upsert_validator import ValidatorElection # noqa
|
||||
|
||||
|
||||
Transaction.register_type(Transaction.CREATE, models.Transaction)
|
||||
Transaction.register_type(Transaction.TRANSFER, models.Transaction)
|
||||
Transaction.register_type(ValidatorElection.VALIDATOR_ELECTION, ValidatorElection)
|
||||
|
||||
@ -99,11 +99,13 @@ def get_assets(conn, asset_ids):
|
||||
|
||||
@register_query(LocalMongoDBConnection)
|
||||
def get_spent(conn, transaction_id, output):
|
||||
query = {'inputs.fulfills': {
|
||||
'transaction_id': transaction_id,
|
||||
'output_index': output}}
|
||||
|
||||
return conn.run(
|
||||
conn.collection('transactions')
|
||||
.find({'inputs.fulfills.transaction_id': transaction_id,
|
||||
'inputs.fulfills.output_index': output},
|
||||
{'_id': 0}))
|
||||
.find(query, {'_id': 0}))
|
||||
|
||||
|
||||
@register_query(LocalMongoDBConnection)
|
||||
|
||||
@ -21,7 +21,7 @@ from bigchaindb.commands import utils
|
||||
from bigchaindb.commands.utils import (configure_bigchaindb,
|
||||
input_on_stderr)
|
||||
from bigchaindb.log import setup_logging
|
||||
from bigchaindb.tendermint.utils import public_key_from_base64
|
||||
from bigchaindb.tendermint_utils import public_key_from_base64
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -97,7 +97,7 @@ def run_configure(args):
|
||||
def run_upsert_validator(args):
|
||||
"""Store validators which should be synced with Tendermint"""
|
||||
|
||||
b = bigchaindb.tendermint.BigchainDB()
|
||||
b = bigchaindb.BigchainDB()
|
||||
public_key = public_key_from_base64(args.public_key)
|
||||
validator = {'pub_key': {'type': 'ed25519',
|
||||
'data': public_key},
|
||||
@ -113,7 +113,7 @@ def run_upsert_validator(args):
|
||||
|
||||
|
||||
def _run_init():
|
||||
bdb = bigchaindb.tendermint.BigchainDB()
|
||||
bdb = bigchaindb.BigchainDB()
|
||||
|
||||
schema.init_database(connection=bdb.connection)
|
||||
|
||||
@ -170,7 +170,7 @@ def run_start(args):
|
||||
setup_logging()
|
||||
|
||||
logger.info('BigchainDB Version %s', bigchaindb.__version__)
|
||||
run_recover(bigchaindb.tendermint.lib.BigchainDB())
|
||||
run_recover(bigchaindb.lib.BigchainDB())
|
||||
|
||||
try:
|
||||
if not args.skip_initialize_database:
|
||||
@ -180,7 +180,7 @@ def run_start(args):
|
||||
pass
|
||||
|
||||
logger.info('Starting BigchainDB main process.')
|
||||
from bigchaindb.tendermint.commands import start
|
||||
from bigchaindb.start import start
|
||||
start()
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,178 @@
|
||||
"""This module contains all the goodness to integrate BigchainDB
|
||||
with Tendermint."""
|
||||
import logging
|
||||
|
||||
from abci.application import BaseApplication
|
||||
from abci.types_pb2 import (
|
||||
ResponseInitChain,
|
||||
ResponseInfo,
|
||||
ResponseCheckTx,
|
||||
ResponseBeginBlock,
|
||||
ResponseDeliverTx,
|
||||
ResponseEndBlock,
|
||||
ResponseCommit,
|
||||
Validator,
|
||||
PubKey
|
||||
)
|
||||
|
||||
from bigchaindb import BigchainDB
|
||||
from bigchaindb.tendermint_utils import (decode_transaction,
|
||||
calculate_hash)
|
||||
from bigchaindb.lib import Block, PreCommitState
|
||||
from bigchaindb.backend.query import PRE_COMMIT_ID
|
||||
|
||||
|
||||
CodeTypeOk = 0
|
||||
CodeTypeError = 1
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class App(BaseApplication):
|
||||
"""Bridge between BigchainDB and Tendermint.
|
||||
|
||||
The role of this class is to expose the BigchainDB
|
||||
transactional logic to the Tendermint Consensus
|
||||
State Machine."""
|
||||
|
||||
def __init__(self, bigchaindb=None):
|
||||
self.bigchaindb = bigchaindb or BigchainDB()
|
||||
self.block_txn_ids = []
|
||||
self.block_txn_hash = ''
|
||||
self.block_transactions = []
|
||||
self.validators = None
|
||||
self.new_height = None
|
||||
|
||||
def init_chain(self, validators):
|
||||
"""Initialize chain with block of height 0"""
|
||||
|
||||
block = Block(app_hash='', height=0, transactions=[])
|
||||
self.bigchaindb.store_block(block._asdict())
|
||||
return ResponseInitChain()
|
||||
|
||||
def info(self, request):
|
||||
"""Return height of the latest committed block."""
|
||||
r = ResponseInfo()
|
||||
block = self.bigchaindb.get_latest_block()
|
||||
if block:
|
||||
r.last_block_height = block['height']
|
||||
r.last_block_app_hash = block['app_hash'].encode('utf-8')
|
||||
else:
|
||||
r.last_block_height = 0
|
||||
r.last_block_app_hash = b''
|
||||
return r
|
||||
|
||||
def check_tx(self, raw_transaction):
|
||||
"""Validate the transaction before entry into
|
||||
the mempool.
|
||||
|
||||
Args:
|
||||
raw_tx: a raw string (in bytes) transaction."""
|
||||
|
||||
logger.benchmark('CHECK_TX_INIT')
|
||||
logger.debug('check_tx: %s', raw_transaction)
|
||||
transaction = decode_transaction(raw_transaction)
|
||||
if self.bigchaindb.is_valid_transaction(transaction):
|
||||
logger.debug('check_tx: VALID')
|
||||
logger.benchmark('CHECK_TX_END, tx_id:%s', transaction['id'])
|
||||
return ResponseCheckTx(code=CodeTypeOk)
|
||||
else:
|
||||
logger.debug('check_tx: INVALID')
|
||||
logger.benchmark('CHECK_TX_END, tx_id:%s', transaction['id'])
|
||||
return ResponseCheckTx(code=CodeTypeError)
|
||||
|
||||
def begin_block(self, req_begin_block):
|
||||
"""Initialize list of transaction.
|
||||
Args:
|
||||
req_begin_block: block object which contains block header
|
||||
and block hash.
|
||||
"""
|
||||
logger.benchmark('BEGIN BLOCK, height:%s, num_txs:%s',
|
||||
req_begin_block.header.height,
|
||||
req_begin_block.header.num_txs)
|
||||
|
||||
self.block_txn_ids = []
|
||||
self.block_transactions = []
|
||||
return ResponseBeginBlock()
|
||||
|
||||
def deliver_tx(self, raw_transaction):
|
||||
"""Validate the transaction before mutating the state.
|
||||
|
||||
Args:
|
||||
raw_tx: a raw string (in bytes) transaction."""
|
||||
logger.debug('deliver_tx: %s', raw_transaction)
|
||||
transaction = self.bigchaindb.is_valid_transaction(
|
||||
decode_transaction(raw_transaction), self.block_transactions)
|
||||
|
||||
if not transaction:
|
||||
logger.debug('deliver_tx: INVALID')
|
||||
return ResponseDeliverTx(code=CodeTypeError)
|
||||
else:
|
||||
logger.debug('storing tx')
|
||||
self.block_txn_ids.append(transaction.id)
|
||||
self.block_transactions.append(transaction)
|
||||
return ResponseDeliverTx(code=CodeTypeOk)
|
||||
|
||||
def end_block(self, request_end_block):
|
||||
"""Calculate block hash using transaction ids and previous block
|
||||
hash to be stored in the next block.
|
||||
|
||||
Args:
|
||||
height (int): new height of the chain."""
|
||||
|
||||
height = request_end_block.height
|
||||
self.new_height = height
|
||||
block_txn_hash = calculate_hash(self.block_txn_ids)
|
||||
block = self.bigchaindb.get_latest_block()
|
||||
|
||||
if self.block_txn_ids:
|
||||
self.block_txn_hash = calculate_hash([block['app_hash'], block_txn_hash])
|
||||
else:
|
||||
self.block_txn_hash = block['app_hash']
|
||||
|
||||
validator_updates = self.bigchaindb.get_validator_update()
|
||||
validator_updates = [encode_validator(v) for v in validator_updates]
|
||||
|
||||
# set sync status to true
|
||||
self.bigchaindb.delete_validator_update()
|
||||
|
||||
# Store pre-commit state to recover in case there is a crash
|
||||
# during `commit`
|
||||
pre_commit_state = PreCommitState(commit_id=PRE_COMMIT_ID,
|
||||
height=self.new_height,
|
||||
transactions=self.block_txn_ids)
|
||||
logger.debug('Updating PreCommitState: %s', self.new_height)
|
||||
self.bigchaindb.store_pre_commit_state(pre_commit_state._asdict())
|
||||
return ResponseEndBlock(validator_updates=validator_updates)
|
||||
|
||||
def commit(self):
|
||||
"""Store the new height and along with block hash."""
|
||||
|
||||
data = self.block_txn_hash.encode('utf-8')
|
||||
|
||||
# register a new block only when new transactions are received
|
||||
if self.block_txn_ids:
|
||||
self.bigchaindb.store_bulk_transactions(self.block_transactions)
|
||||
block = Block(app_hash=self.block_txn_hash,
|
||||
height=self.new_height,
|
||||
transactions=self.block_txn_ids)
|
||||
# NOTE: storing the block should be the last operation during commit
|
||||
# this effects crash recovery. Refer BEP#8 for details
|
||||
self.bigchaindb.store_block(block._asdict())
|
||||
|
||||
logger.debug('Commit-ing new block with hash: apphash=%s ,'
|
||||
'height=%s, txn ids=%s', data, self.new_height,
|
||||
self.block_txn_ids)
|
||||
logger.benchmark('COMMIT_BLOCK, height:%s', self.new_height)
|
||||
return ResponseCommit(data=data)
|
||||
|
||||
|
||||
def encode_validator(v):
|
||||
ed25519_public_key = v['pub_key']['data']
|
||||
# NOTE: tendermint expects public to be encoded in go-amino format
|
||||
|
||||
pub_key = PubKey(type='ed25519',
|
||||
data=bytes.fromhex(ed25519_public_key))
|
||||
|
||||
return Validator(pub_key=pub_key,
|
||||
address=b'',
|
||||
power=v['power'])
|
||||
@ -8,7 +8,7 @@ import aiohttp
|
||||
from bigchaindb import config
|
||||
from bigchaindb.common.utils import gen_timestamp
|
||||
from bigchaindb.events import EventTypes, Event
|
||||
from bigchaindb.tendermint.utils import decode_transaction_base64
|
||||
from bigchaindb.tendermint_utils import decode_transaction_base64
|
||||
|
||||
|
||||
HOST = config['tendermint']['host']
|
||||
@ -16,13 +16,12 @@ except ImportError:
|
||||
import requests
|
||||
|
||||
import bigchaindb
|
||||
from bigchaindb import backend, config_utils
|
||||
from bigchaindb import backend, config_utils, fastquery
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.exceptions import (SchemaValidationError,
|
||||
ValidationError,
|
||||
DoubleSpend)
|
||||
from bigchaindb.tendermint.utils import encode_transaction, merkleroot
|
||||
from bigchaindb.tendermint import fastquery
|
||||
from bigchaindb.tendermint_utils import encode_transaction, merkleroot
|
||||
from bigchaindb import exceptions as core_exceptions
|
||||
from bigchaindb.consensus import BaseConsensusRules
|
||||
|
||||
@ -254,10 +253,10 @@ class BigchainDB(object):
|
||||
|
||||
def get_transaction(self, transaction_id, include_status=False, cls=Transaction):
|
||||
transaction = backend.query.get_transaction(self.connection, transaction_id)
|
||||
asset = backend.query.get_asset(self.connection, transaction_id)
|
||||
metadata = backend.query.get_metadata(self.connection, [transaction_id])
|
||||
|
||||
if transaction:
|
||||
asset = backend.query.get_asset(self.connection, transaction_id)
|
||||
metadata = backend.query.get_metadata(self.connection, [transaction_id])
|
||||
if asset:
|
||||
transaction['asset'] = asset
|
||||
|
||||
@ -15,7 +15,7 @@ class Transaction(Transaction):
|
||||
"""Validate transaction spend
|
||||
|
||||
Args:
|
||||
bigchain (BigchainDB): an instantiated bigchaindb.tendermint.BigchainDB object.
|
||||
bigchain (BigchainDB): an instantiated bigchaindb.BigchainDB object.
|
||||
|
||||
Returns:
|
||||
The transaction (Transaction) if the transaction is valid else it
|
||||
|
||||
@ -3,10 +3,10 @@ import logging
|
||||
import setproctitle
|
||||
|
||||
import bigchaindb
|
||||
from bigchaindb.tendermint.lib import BigchainDB
|
||||
from bigchaindb.tendermint.core import App
|
||||
from bigchaindb.lib import BigchainDB
|
||||
from bigchaindb.core import App
|
||||
from bigchaindb.web import server, websocket_server
|
||||
from bigchaindb.tendermint import event_stream
|
||||
from bigchaindb import event_stream
|
||||
from bigchaindb.events import Exchange, EventTypes
|
||||
from bigchaindb.utils import Process
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
"""Code necessary for integrating with Tendermint."""
|
||||
|
||||
# Order is important!
|
||||
# If we import core first, core will try to load BigchainDB from
|
||||
# __init__ itself, causing a loop.
|
||||
from bigchaindb.tendermint.lib import BigchainDB # noqa
|
||||
from bigchaindb.tendermint.core import App # noqa
|
||||
@ -1,178 +0,0 @@
|
||||
"""This module contains all the goodness to integrate BigchainDB
|
||||
with Tendermint."""
|
||||
import logging
|
||||
|
||||
from abci.application import BaseApplication
|
||||
from abci.types_pb2 import (
|
||||
ResponseInitChain,
|
||||
ResponseInfo,
|
||||
ResponseCheckTx,
|
||||
ResponseBeginBlock,
|
||||
ResponseDeliverTx,
|
||||
ResponseEndBlock,
|
||||
ResponseCommit,
|
||||
Validator,
|
||||
PubKey
|
||||
)
|
||||
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb.tendermint.utils import (decode_transaction,
|
||||
calculate_hash)
|
||||
from bigchaindb.tendermint.lib import Block, PreCommitState
|
||||
from bigchaindb.backend.query import PRE_COMMIT_ID
|
||||
|
||||
|
||||
CodeTypeOk = 0
|
||||
CodeTypeError = 1
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class App(BaseApplication):
|
||||
"""Bridge between BigchainDB and Tendermint.
|
||||
|
||||
The role of this class is to expose the BigchainDB
|
||||
transactional logic to the Tendermint Consensus
|
||||
State Machine."""
|
||||
|
||||
def __init__(self, bigchaindb=None):
|
||||
self.bigchaindb = bigchaindb or BigchainDB()
|
||||
self.block_txn_ids = []
|
||||
self.block_txn_hash = ''
|
||||
self.block_transactions = []
|
||||
self.validators = None
|
||||
self.new_height = None
|
||||
|
||||
def init_chain(self, validators):
|
||||
"""Initialize chain with block of height 0"""
|
||||
|
||||
block = Block(app_hash='', height=0, transactions=[])
|
||||
self.bigchaindb.store_block(block._asdict())
|
||||
return ResponseInitChain()
|
||||
|
||||
def info(self, request):
|
||||
"""Return height of the latest committed block."""
|
||||
r = ResponseInfo()
|
||||
block = self.bigchaindb.get_latest_block()
|
||||
if block:
|
||||
r.last_block_height = block['height']
|
||||
r.last_block_app_hash = block['app_hash'].encode('utf-8')
|
||||
else:
|
||||
r.last_block_height = 0
|
||||
r.last_block_app_hash = b''
|
||||
return r
|
||||
|
||||
def check_tx(self, raw_transaction):
|
||||
"""Validate the transaction before entry into
|
||||
the mempool.
|
||||
|
||||
Args:
|
||||
raw_tx: a raw string (in bytes) transaction."""
|
||||
|
||||
logger.benchmark('CHECK_TX_INIT')
|
||||
logger.debug('check_tx: %s', raw_transaction)
|
||||
transaction = decode_transaction(raw_transaction)
|
||||
if self.bigchaindb.is_valid_transaction(transaction):
|
||||
logger.debug('check_tx: VALID')
|
||||
logger.benchmark('CHECK_TX_END, tx_id:%s', transaction['id'])
|
||||
return ResponseCheckTx(code=CodeTypeOk)
|
||||
else:
|
||||
logger.debug('check_tx: INVALID')
|
||||
logger.benchmark('CHECK_TX_END, tx_id:%s', transaction['id'])
|
||||
return ResponseCheckTx(code=CodeTypeError)
|
||||
|
||||
def begin_block(self, req_begin_block):
|
||||
"""Initialize list of transaction.
|
||||
Args:
|
||||
req_begin_block: block object which contains block header
|
||||
and block hash.
|
||||
"""
|
||||
logger.benchmark('BEGIN BLOCK, height:%s, num_txs:%s',
|
||||
req_begin_block.header.height,
|
||||
req_begin_block.header.num_txs)
|
||||
|
||||
self.block_txn_ids = []
|
||||
self.block_transactions = []
|
||||
return ResponseBeginBlock()
|
||||
|
||||
def deliver_tx(self, raw_transaction):
|
||||
"""Validate the transaction before mutating the state.
|
||||
|
||||
Args:
|
||||
raw_tx: a raw string (in bytes) transaction."""
|
||||
logger.debug('deliver_tx: %s', raw_transaction)
|
||||
transaction = self.bigchaindb.is_valid_transaction(
|
||||
decode_transaction(raw_transaction), self.block_transactions)
|
||||
|
||||
if not transaction:
|
||||
logger.debug('deliver_tx: INVALID')
|
||||
return ResponseDeliverTx(code=CodeTypeError)
|
||||
else:
|
||||
logger.debug('storing tx')
|
||||
self.block_txn_ids.append(transaction.id)
|
||||
self.block_transactions.append(transaction)
|
||||
return ResponseDeliverTx(code=CodeTypeOk)
|
||||
|
||||
def end_block(self, request_end_block):
|
||||
"""Calculate block hash using transaction ids and previous block
|
||||
hash to be stored in the next block.
|
||||
|
||||
Args:
|
||||
height (int): new height of the chain."""
|
||||
|
||||
height = request_end_block.height
|
||||
self.new_height = height
|
||||
block_txn_hash = calculate_hash(self.block_txn_ids)
|
||||
block = self.bigchaindb.get_latest_block()
|
||||
|
||||
if self.block_txn_ids:
|
||||
self.block_txn_hash = calculate_hash([block['app_hash'], block_txn_hash])
|
||||
else:
|
||||
self.block_txn_hash = block['app_hash']
|
||||
|
||||
validator_updates = self.bigchaindb.get_validator_update()
|
||||
validator_updates = [encode_validator(v) for v in validator_updates]
|
||||
|
||||
# set sync status to true
|
||||
self.bigchaindb.delete_validator_update()
|
||||
|
||||
# Store pre-commit state to recover in case there is a crash
|
||||
# during `commit`
|
||||
pre_commit_state = PreCommitState(commit_id=PRE_COMMIT_ID,
|
||||
height=self.new_height,
|
||||
transactions=self.block_txn_ids)
|
||||
logger.debug('Updating PreCommitState: %s', self.new_height)
|
||||
self.bigchaindb.store_pre_commit_state(pre_commit_state._asdict())
|
||||
return ResponseEndBlock(validator_updates=validator_updates)
|
||||
|
||||
def commit(self):
|
||||
"""Store the new height and along with block hash."""
|
||||
|
||||
data = self.block_txn_hash.encode('utf-8')
|
||||
|
||||
# register a new block only when new transactions are received
|
||||
if self.block_txn_ids:
|
||||
self.bigchaindb.store_bulk_transactions(self.block_transactions)
|
||||
block = Block(app_hash=self.block_txn_hash,
|
||||
height=self.new_height,
|
||||
transactions=self.block_txn_ids)
|
||||
# NOTE: storing the block should be the last operation during commit
|
||||
# this effects crash recovery. Refer BEP#8 for details
|
||||
self.bigchaindb.store_block(block._asdict())
|
||||
|
||||
logger.debug('Commit-ing new block with hash: apphash=%s ,'
|
||||
'height=%s, txn ids=%s', data, self.new_height,
|
||||
self.block_txn_ids)
|
||||
logger.benchmark('COMMIT_BLOCK, height:%s', self.new_height)
|
||||
return ResponseCommit(data=data)
|
||||
|
||||
|
||||
def encode_validator(v):
|
||||
ed25519_public_key = v['pub_key']['data']
|
||||
# NOTE: tendermint expects public to be encoded in go-amino format
|
||||
|
||||
pub_key = PubKey(type='ed25519',
|
||||
data=bytes.fromhex(ed25519_public_key))
|
||||
|
||||
return Validator(pub_key=pub_key,
|
||||
address=b'',
|
||||
power=v['power'])
|
||||
@ -1,6 +1,6 @@
|
||||
from bigchaindb.common.exceptions import (InvalidSignature, MultipleInputsError,
|
||||
DuplicateTransaction)
|
||||
from bigchaindb.tendermint.utils import key_from_base64
|
||||
from bigchaindb.tendermint_utils import key_from_base64
|
||||
from bigchaindb.common.crypto import (public_key_from_ed25519_key)
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from bigchaindb.common.schema import (_load_schema,
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
__version__ = '2.0.0b1'
|
||||
__short_version__ = '2.0b1'
|
||||
__version__ = '2.0.0b3'
|
||||
__short_version__ = '2.0b3'
|
||||
|
||||
@ -11,7 +11,7 @@ from flask_cors import CORS
|
||||
import gunicorn.app.base
|
||||
|
||||
from bigchaindb import utils
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb import BigchainDB
|
||||
from bigchaindb.web.routes import add_routes
|
||||
from bigchaindb.web.strip_content_type_middleware import StripContentTypeMiddleware
|
||||
|
||||
|
||||
@ -1,7 +1,14 @@
|
||||
# Write a BigchaindB Enhancement Proposal (BEP)
|
||||
# Write a BigchainDB Enhancement Proposal (BEP)
|
||||
|
||||
- Review [1/C4](https://github.com/bigchaindb/BEPs/tree/master/1), the process we use to accept any new code or PR of any kind, including one that adds a BEP to `bigchaindb/BEPs`.
|
||||
- Review [2/COSS](https://github.com/bigchaindb/BEPs/tree/master/2). Maybe print it for reference. It outlines what can go in a BEP.
|
||||
- Don't spend weeks on your BEP. Version 1 should take up to a few hours to write. You can add to it in the future. The process is iterative. If you need more than a few hours, then consider writing multiple BEPs.
|
||||
- Do _not_ start writing code before you think about it. You should always write a BEP first. Once you do that, you can start implementing it. To do that, make a pull request and say it implements your BEP.
|
||||
- Do _not_ write your BEP as an issue (i.e. a GitHub issue).
|
||||
If you have an idea for a new feature or enhancement, and you want some feedback before you write a full BigchainDB Enhancement Proposal (BEP), then feel free to:
|
||||
- ask in the [bigchaindb/bigchaindb Gitter chat room](https://gitter.im/bigchaindb/bigchaindb) or
|
||||
- [open a new issue in the bigchaindb/BEPs repo](https://github.com/bigchaindb/BEPs/issues/new) and give it the label **BEP idea**.
|
||||
|
||||
If you want to discuss an existing BEP, then [open a new issue in the bigchaindb/BEPs repo](https://github.com/bigchaindb/BEPs/issues/new) and give it the label **discuss existing BEP**.
|
||||
|
||||
## Steps to Write a New BEP
|
||||
|
||||
1. Look at the structure of existing BEPs in the [bigchaindb/BEPs repo](https://github.com/bigchaindb/BEPs). Note the section headings. [BEP-2](https://github.com/bigchaindb/BEPs/tree/master/2) (our variant of the consensus-oriented specification system [COSS]) says more about the expected structure and process.
|
||||
1. Write a first draft of your BEP. It doesn't have to be long or perfect.
|
||||
1. Push your BEP draft to the [bigchaindb/BEPs repo](https://github.com/bigchaindb/BEPs) and make a pull request. [BEP-1](https://github.com/bigchaindb/BEPs/tree/master/1) (our variant of C4) outlines the process we use to handle all pull requests. In particular, we try to merge all pull requests quickly.
|
||||
1. Your BEP can be revised by pushing more pull requests.
|
||||
|
||||
@ -3,7 +3,7 @@ BigchainDB and Smart Contracts
|
||||
|
||||
One can store the source code of any smart contract (i.e. a computer program) in BigchainDB, but BigchainDB won't run arbitrary smart contracts.
|
||||
|
||||
BigchainDB will run the subset of smart contracts expressible using `Crypto-Conditions <https://tools.ietf.org/html/draft-thomas-crypto-conditions-03>`_. Crypto-conditions are part of the `Interledger Protocol <https://interledger.org/>`_.
|
||||
BigchainDB will run the subset of smart contracts expressible using `Crypto-Conditions <https://tools.ietf.org/html/draft-thomas-crypto-conditions-03>`_.
|
||||
|
||||
The owners of an asset can impose conditions on it that must be met for the asset to be transferred to new owners. Examples of possible conditions (crypto-conditions) include:
|
||||
|
||||
|
||||
@ -27,9 +27,8 @@ and the other output might have 15 oak trees for another set of owners.
|
||||
|
||||
Each output also has an associated condition: the condition that must be met
|
||||
(by a TRANSFER transaction) to transfer/spend the output.
|
||||
BigchainDB supports a variety of conditions,
|
||||
a subset of the [Interledger Protocol (ILP)](https://interledger.org/)
|
||||
crypto-conditions. For details, see
|
||||
BigchainDB supports a variety of conditions.
|
||||
For details, see
|
||||
the section titled **Transaction Components: Conditions**
|
||||
in the relevant
|
||||
[BigchainDB Transactions Spec](https://github.com/bigchaindb/BEPs/tree/master/tx-specs/).
|
||||
|
||||
@ -5,8 +5,7 @@ import os
|
||||
import os.path
|
||||
|
||||
from bigchaindb.common.transaction import Transaction, Input, TransactionLink
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb.tendermint import lib
|
||||
from bigchaindb import lib
|
||||
from bigchaindb.web import server
|
||||
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@ Appendices
|
||||
the-bigchaindb-class
|
||||
backend
|
||||
commands
|
||||
tendermint-integration
|
||||
aws-setup
|
||||
generate-key-pair-for-ssh
|
||||
firewall-notes
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
######################
|
||||
Tendermint Integration
|
||||
######################
|
||||
|
||||
|
||||
.. automodule:: bigchaindb.tendermint
|
||||
:special-members: __init__
|
||||
|
||||
.. automodule:: bigchaindb.tendermint.lib
|
||||
:special-members: __init__
|
||||
:noindex:
|
||||
|
||||
.. automodule:: bigchaindb.tendermint.core
|
||||
:special-members: __init__
|
||||
|
||||
.. automodule:: bigchaindb.tendermint.event_stream
|
||||
:special-members: __init__
|
||||
|
||||
.. automodule:: bigchaindb.tendermint.fastquery
|
||||
:special-members: __init__
|
||||
|
||||
.. automodule:: bigchaindb.tendermint.commands
|
||||
:special-members: __init__
|
||||
|
||||
.. automodule:: bigchaindb.tendermint.utils
|
||||
:special-members: __init__
|
||||
@ -2,4 +2,4 @@
|
||||
The BigchainDB Class
|
||||
####################
|
||||
|
||||
.. autoclass:: bigchaindb.tendermint.BigchainDB
|
||||
.. autoclass:: bigchaindb.BigchainDB
|
||||
|
||||
@ -52,10 +52,11 @@ BigchainDB Server requires **Python 3.6+**, so make sure your system has it. Ins
|
||||
sudo apt install -y python3-pip libssl-dev
|
||||
```
|
||||
|
||||
Now install the latest version of BigchainDB. Check the [project page on PyPI][bdb:pypi] for the last version (which was `2.0.0a6` at the time of writing) and install it:
|
||||
Now install the latest version of BigchainDB. You can find the latest version by going to the [BigchainDB project release history page on PyPI][bdb:pypi]. For example, to install version 2.0.0b3, you would do:
|
||||
|
||||
```
|
||||
sudo pip3 install bigchaindb==2.0.0a6
|
||||
# Change 2.0.0b3 to the latest version as explained above:
|
||||
sudo pip3 install bigchaindb==2.0.0b3
|
||||
```
|
||||
|
||||
Check that you installed the correct version of BigchainDB Server using `bigchaindb --version`.
|
||||
@ -243,6 +244,19 @@ If you followed the recommended approach and created startup scripts for Bigchai
|
||||
|
||||
If you followed the above instructions, then your node should be publicly-accessible with BigchainDB Root URL `http://hostname:9984` (where hostname is something like `bdb7.canada.vmsareus.net` or `17.122.200.76`). That is, anyone can interact with your node using the [BigchainDB HTTP API](http-client-server-api.html) exposed at that address. The most common way to do that is to use one of the [BigchainDB Drivers](./drivers-clients/index.html).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
To check which nodes your node is connected to (via Tendermint protocols), do:
|
||||
|
||||
```text
|
||||
# if you don't jq installed, then install it
|
||||
sudo apt install jq
|
||||
# then do
|
||||
curl -s localhost:26657/net_info | jq ".result.peers[].node_info | {id, listen_addr, moniker}"
|
||||
```
|
||||
|
||||
Tendermint has other endpoints besides `/net_info`: see [the Tendermint RPC docs](https://tendermint.github.io/slate/?shell#introduction).
|
||||
|
||||
## Refreshing Your Node
|
||||
|
||||
If you want to refresh your node back to a fresh empty state, then your best bet is to terminate it and deploy a new virtual machine, but if that's not an option, then you can:
|
||||
|
||||
@ -154,7 +154,7 @@ spec:
|
||||
timeoutSeconds: 15
|
||||
# BigchainDB container
|
||||
- name: bigchaindb
|
||||
image: bigchaindb/bigchaindb:2.0.0-beta1
|
||||
image: bigchaindb/bigchaindb:2.0.0-beta3
|
||||
imagePullPolicy: Always
|
||||
args:
|
||||
- start
|
||||
|
||||
@ -34,7 +34,7 @@ spec:
|
||||
terminationGracePeriodSeconds: 10
|
||||
containers:
|
||||
- name: bigchaindb
|
||||
image: bigchaindb/bigchaindb:2.0.0-beta1
|
||||
image: bigchaindb/bigchaindb:2.0.0-beta3
|
||||
imagePullPolicy: Always
|
||||
args:
|
||||
- start
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
- name: Get Running BigchainDB Process(es)
|
||||
shell: "ps aux | grep \"[b]igchaindb\" | awk '{print $2}'"
|
||||
register: bdb_ps
|
||||
ignore_errors: yes
|
||||
when: stack_type|lower == "local"
|
||||
tags: [bigchaindb]
|
||||
|
||||
|
||||
@ -8,7 +8,8 @@ distribution_major: "{{ ansible_distribution_major_version }}"
|
||||
server_arch: "amd64,arm64"
|
||||
|
||||
# MongoDB Repos
|
||||
mongodb_apt_repo: "deb [arch={{ server_arch }}] http://repo.mongodb.org/apt/{{ distribution_name }} {{ distribution_codename }}/{{ mongodb_package }}/{{ mongo_version }} {{'main' if ansible_distribution == 'debian' else 'multiverse'}}"
|
||||
mongodb_apt_repo: "deb [arch={{ server_arch }}] http://repo.mongodb.org/apt/{{ distribution_name }} {{ distribution_codename }}/{{ mongodb_package }}/{{ mongo_version }} multiverse"
|
||||
mongodb_deb_repo: "deb http://repo.mongodb.org/apt/{{ distribution_name }} {{ distribution_codename }}/{{ mongodb_package }}/{{ mongo_version }} main"
|
||||
mongodb_yum_base_url: "https://repo.mongodb.org/yum/{{ ansible_os_family|lower }}/$releasever/{{ mongodb_package }}/{{ mongo_version }}/{{ ansible_architecture }}"
|
||||
mongodb_dnf_base_url: "https://repo.mongodb.org/yum/{{ ansible_os_family|lower }}/7/{{ mongodb_package }}/{{ mongo_version }}/{{ ansible_architecture }}"
|
||||
|
||||
|
||||
@ -22,6 +22,15 @@
|
||||
repo: "{{ mongodb_apt_repo }}"
|
||||
state: present
|
||||
update_cache: no
|
||||
when: distribution_name == "ubuntu"
|
||||
tags: [mongodb]
|
||||
|
||||
- name: Add MongoDB repo and update cache | deb
|
||||
apt_repository:
|
||||
repo: "{{ mongodb_deb_repo }}"
|
||||
state: present
|
||||
update_cache: no
|
||||
when: distribution_name == "debian"
|
||||
tags: [mongodb]
|
||||
|
||||
- name: Install MongoDB | apt
|
||||
|
||||
@ -229,7 +229,7 @@ def test_get_spending_transactions(user_pk, user_sk):
|
||||
|
||||
def test_store_block():
|
||||
from bigchaindb.backend import connect, query
|
||||
from bigchaindb.tendermint.lib import Block
|
||||
from bigchaindb.lib import Block
|
||||
conn = connect()
|
||||
|
||||
block = Block(app_hash='random_utxo',
|
||||
@ -242,7 +242,7 @@ def test_store_block():
|
||||
|
||||
def test_get_block():
|
||||
from bigchaindb.backend import connect, query
|
||||
from bigchaindb.tendermint.lib import Block
|
||||
from bigchaindb.lib import Block
|
||||
conn = connect()
|
||||
|
||||
block = Block(app_hash='random_utxo',
|
||||
@ -345,7 +345,7 @@ def test_get_unspent_outputs(db_context, utxoset):
|
||||
|
||||
def test_store_pre_commit_state(db_context):
|
||||
from bigchaindb.backend import query
|
||||
from bigchaindb.tendermint.lib import PreCommitState
|
||||
from bigchaindb.lib import PreCommitState
|
||||
|
||||
state = PreCommitState(commit_id='test',
|
||||
height=3,
|
||||
@ -359,7 +359,7 @@ def test_store_pre_commit_state(db_context):
|
||||
|
||||
def test_get_pre_commit_state(db_context):
|
||||
from bigchaindb.backend import query
|
||||
from bigchaindb.tendermint.lib import PreCommitState
|
||||
from bigchaindb.lib import PreCommitState
|
||||
|
||||
state = PreCommitState(commit_id='test2',
|
||||
height=3,
|
||||
|
||||
@ -90,7 +90,7 @@ def test_bigchain_run_init_when_db_exists(mocker, capsys):
|
||||
def test__run_init(mocker):
|
||||
from bigchaindb.commands.bigchaindb import _run_init
|
||||
bigchain_mock = mocker.patch(
|
||||
'bigchaindb.commands.bigchaindb.bigchaindb.tendermint.BigchainDB')
|
||||
'bigchaindb.commands.bigchaindb.bigchaindb.BigchainDB')
|
||||
init_db_mock = mocker.patch(
|
||||
'bigchaindb.commands.bigchaindb.schema.init_database',
|
||||
autospec=True,
|
||||
@ -274,7 +274,7 @@ def test_calling_main(start_mock, base_parser_mock, parse_args_mock,
|
||||
|
||||
@patch('bigchaindb.config_utils.autoconfigure')
|
||||
@patch('bigchaindb.commands.bigchaindb.run_recover')
|
||||
@patch('bigchaindb.tendermint.commands.start')
|
||||
@patch('bigchaindb.start.start')
|
||||
def test_recover_db_on_start(mock_autoconfigure,
|
||||
mock_run_recover,
|
||||
mock_start,
|
||||
@ -293,7 +293,7 @@ def test_recover_db_on_start(mock_autoconfigure,
|
||||
def test_run_recover(b, alice, bob):
|
||||
from bigchaindb.commands.bigchaindb import run_recover
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.tendermint.lib import Block, PreCommitState
|
||||
from bigchaindb.lib import Block, PreCommitState
|
||||
from bigchaindb.backend.query import PRE_COMMIT_ID
|
||||
from bigchaindb.backend import query
|
||||
|
||||
|
||||
@ -17,10 +17,10 @@ from pymongo import MongoClient
|
||||
|
||||
from bigchaindb.common import crypto
|
||||
from bigchaindb.log import setup_logging
|
||||
from bigchaindb.tendermint.lib import Block
|
||||
from bigchaindb.tendermint.utils import key_from_base64
|
||||
from bigchaindb.tendermint_utils import key_from_base64
|
||||
from bigchaindb.common.crypto import (key_pair_from_ed25519_key,
|
||||
public_key_from_ed25519_key)
|
||||
from bigchaindb.lib import Block
|
||||
|
||||
|
||||
TEST_DB_NAME = 'bigchain_test'
|
||||
@ -273,13 +273,13 @@ def merlin_pubkey(merlin):
|
||||
|
||||
@pytest.fixture
|
||||
def b():
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb import BigchainDB
|
||||
return BigchainDB()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tb():
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb import BigchainDB
|
||||
return BigchainDB()
|
||||
|
||||
|
||||
@ -518,7 +518,7 @@ def event_loop(request):
|
||||
@pytest.fixture(scope='session')
|
||||
def abci_server():
|
||||
from abci import ABCIServer
|
||||
from bigchaindb.tendermint.core import App
|
||||
from bigchaindb.core import App
|
||||
from bigchaindb.utils import Process
|
||||
|
||||
app = ABCIServer(app=App())
|
||||
|
||||
@ -280,7 +280,7 @@ class TestBigchainApi(object):
|
||||
|
||||
@pytest.mark.usefixtures('inputs')
|
||||
def test_write_transaction(self, b, user_pk, user_sk):
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb import BigchainDB
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
input_tx = b.get_owned_ids(user_pk).pop()
|
||||
@ -439,7 +439,7 @@ class TestBigchainApi(object):
|
||||
from bigchaindb.common.exceptions import InputDoesNotExist
|
||||
from bigchaindb.common.transaction import Input, TransactionLink
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb import BigchainDB
|
||||
|
||||
# Create an input for a non existing transaction
|
||||
input = Input(Ed25519Sha256(public_key=b58decode(user_pk)),
|
||||
@ -970,8 +970,8 @@ class TestMultipleInputs(object):
|
||||
|
||||
|
||||
def test_get_owned_ids_calls_get_outputs_filtered():
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
with patch('bigchaindb.tendermint.BigchainDB.get_outputs_filtered') as gof:
|
||||
from bigchaindb import BigchainDB
|
||||
with patch('bigchaindb.BigchainDB.get_outputs_filtered') as gof:
|
||||
b = BigchainDB()
|
||||
res = b.get_owned_ids('abc')
|
||||
gof.assert_called_once_with('abc', spent=False)
|
||||
@ -981,13 +981,13 @@ def test_get_owned_ids_calls_get_outputs_filtered():
|
||||
@pytest.mark.tendermint
|
||||
def test_get_outputs_filtered_only_unspent():
|
||||
from bigchaindb.common.transaction import TransactionLink
|
||||
from bigchaindb.tendermint.lib import BigchainDB
|
||||
from bigchaindb.lib import BigchainDB
|
||||
|
||||
go = 'bigchaindb.tendermint.fastquery.FastQuery.get_outputs_by_public_key'
|
||||
go = 'bigchaindb.fastquery.FastQuery.get_outputs_by_public_key'
|
||||
with patch(go) as get_outputs:
|
||||
get_outputs.return_value = [TransactionLink('a', 1),
|
||||
TransactionLink('b', 2)]
|
||||
fs = 'bigchaindb.tendermint.fastquery.FastQuery.filter_spent_outputs'
|
||||
fs = 'bigchaindb.fastquery.FastQuery.filter_spent_outputs'
|
||||
with patch(fs) as filter_spent:
|
||||
filter_spent.return_value = [TransactionLink('b', 2)]
|
||||
out = BigchainDB().get_outputs_filtered('abc', spent=False)
|
||||
@ -998,12 +998,12 @@ def test_get_outputs_filtered_only_unspent():
|
||||
@pytest.mark.tendermint
|
||||
def test_get_outputs_filtered_only_spent():
|
||||
from bigchaindb.common.transaction import TransactionLink
|
||||
from bigchaindb.tendermint.lib import BigchainDB
|
||||
go = 'bigchaindb.tendermint.fastquery.FastQuery.get_outputs_by_public_key'
|
||||
from bigchaindb.lib import BigchainDB
|
||||
go = 'bigchaindb.fastquery.FastQuery.get_outputs_by_public_key'
|
||||
with patch(go) as get_outputs:
|
||||
get_outputs.return_value = [TransactionLink('a', 1),
|
||||
TransactionLink('b', 2)]
|
||||
fs = 'bigchaindb.tendermint.fastquery.FastQuery.filter_unspent_outputs'
|
||||
fs = 'bigchaindb.fastquery.FastQuery.filter_unspent_outputs'
|
||||
with patch(fs) as filter_spent:
|
||||
filter_spent.return_value = [TransactionLink('b', 2)]
|
||||
out = BigchainDB().get_outputs_filtered('abc', spent=True)
|
||||
@ -1012,13 +1012,13 @@ def test_get_outputs_filtered_only_spent():
|
||||
|
||||
|
||||
@pytest.mark.tendermint
|
||||
@patch('bigchaindb.tendermint.fastquery.FastQuery.filter_unspent_outputs')
|
||||
@patch('bigchaindb.tendermint.fastquery.FastQuery.filter_spent_outputs')
|
||||
@patch('bigchaindb.fastquery.FastQuery.filter_unspent_outputs')
|
||||
@patch('bigchaindb.fastquery.FastQuery.filter_spent_outputs')
|
||||
def test_get_outputs_filtered(filter_spent, filter_unspent):
|
||||
from bigchaindb.common.transaction import TransactionLink
|
||||
from bigchaindb.tendermint.lib import BigchainDB
|
||||
from bigchaindb.lib import BigchainDB
|
||||
|
||||
go = 'bigchaindb.tendermint.fastquery.FastQuery.get_outputs_by_public_key'
|
||||
go = 'bigchaindb.fastquery.FastQuery.get_outputs_by_public_key'
|
||||
with patch(go) as get_outputs:
|
||||
get_outputs.return_value = [TransactionLink('a', 1),
|
||||
TransactionLink('b', 2)]
|
||||
|
||||
@ -3,7 +3,7 @@ import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def b():
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb import BigchainDB
|
||||
return BigchainDB()
|
||||
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ from abci.types_pb2 import (
|
||||
RequestEndBlock
|
||||
)
|
||||
|
||||
from bigchaindb.tendermint.core import CodeTypeOk, CodeTypeError
|
||||
from bigchaindb.core import CodeTypeOk, CodeTypeError
|
||||
|
||||
|
||||
pytestmark = [pytest.mark.tendermint, pytest.mark.bdb]
|
||||
@ -17,7 +17,7 @@ def encode_tx_to_bytes(transaction):
|
||||
|
||||
|
||||
def test_check_tx__signed_create_is_ok(b):
|
||||
from bigchaindb.tendermint import App
|
||||
from bigchaindb import App
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.crypto import generate_key_pair
|
||||
|
||||
@ -34,7 +34,7 @@ def test_check_tx__signed_create_is_ok(b):
|
||||
|
||||
|
||||
def test_check_tx__unsigned_create_is_error(b):
|
||||
from bigchaindb.tendermint import App
|
||||
from bigchaindb import App
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.crypto import generate_key_pair
|
||||
|
||||
@ -51,7 +51,7 @@ def test_check_tx__unsigned_create_is_error(b):
|
||||
|
||||
@pytest.mark.bdb
|
||||
def test_deliver_tx__valid_create_updates_db(b):
|
||||
from bigchaindb.tendermint import App
|
||||
from bigchaindb import App
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.crypto import generate_key_pair
|
||||
|
||||
@ -84,7 +84,7 @@ def test_deliver_tx__valid_create_updates_db(b):
|
||||
|
||||
|
||||
def test_deliver_tx__double_spend_fails(b):
|
||||
from bigchaindb.tendermint import App
|
||||
from bigchaindb import App
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.crypto import generate_key_pair
|
||||
|
||||
@ -113,7 +113,7 @@ def test_deliver_tx__double_spend_fails(b):
|
||||
|
||||
|
||||
def test_deliver_transfer_tx__double_spend_fails(b):
|
||||
from bigchaindb.tendermint import App
|
||||
from bigchaindb import App
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.crypto import generate_key_pair
|
||||
|
||||
@ -157,9 +157,9 @@ def test_deliver_transfer_tx__double_spend_fails(b):
|
||||
|
||||
|
||||
def test_end_block_return_validator_updates(b):
|
||||
from bigchaindb.tendermint import App
|
||||
from bigchaindb import App
|
||||
from bigchaindb.backend import query
|
||||
from bigchaindb.tendermint.core import encode_validator
|
||||
from bigchaindb.core import encode_validator
|
||||
from bigchaindb.backend.query import VALIDATOR_UPDATE_ID
|
||||
|
||||
app = App(b)
|
||||
@ -183,7 +183,7 @@ def test_end_block_return_validator_updates(b):
|
||||
|
||||
|
||||
def test_store_pre_commit_state_in_end_block(b, alice):
|
||||
from bigchaindb.tendermint import App
|
||||
from bigchaindb import App
|
||||
from bigchaindb.backend import query
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.backend.query import PRE_COMMIT_ID
|
||||
|
||||
@ -8,7 +8,7 @@ import pytest
|
||||
|
||||
@pytest.mark.tendermint
|
||||
def test_process_event_new_block():
|
||||
from bigchaindb.tendermint.event_stream import process_event
|
||||
from bigchaindb.event_stream import process_event
|
||||
|
||||
event = '{"jsonrpc": "2.0", "id": "test_stream_id#event", "result": {'\
|
||||
'"query": "tm.event=\'NewBlock\'", "data": { "type": "CF18EA939D3240",'\
|
||||
@ -46,7 +46,7 @@ def test_process_event_new_block():
|
||||
|
||||
@pytest.mark.tendermint
|
||||
def test_process_event_empty_block():
|
||||
from bigchaindb.tendermint.event_stream import process_event
|
||||
from bigchaindb.event_stream import process_event
|
||||
|
||||
event = '{"jsonrpc": "2.0", "id": "bigchaindb_stream_1524555674#event",'\
|
||||
'"result": {"query": "tm.event=\'NewBlock\'", "data": {"type": '\
|
||||
@ -67,7 +67,7 @@ def test_process_event_empty_block():
|
||||
|
||||
@pytest.mark.tendermint
|
||||
def test_process_unknown_event():
|
||||
from bigchaindb.tendermint.event_stream import process_event
|
||||
from bigchaindb.event_stream import process_event
|
||||
|
||||
event = '{"jsonrpc": "2.0", "id": "test_stream_id#event",'\
|
||||
' "result": { "query": "tm.event=\'UnknownEvent\'" }}'
|
||||
@ -80,7 +80,7 @@ def test_process_unknown_event():
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.abci
|
||||
async def test_subscribe_events(tendermint_ws_url, b):
|
||||
from bigchaindb.tendermint.event_stream import subscribe_events
|
||||
from bigchaindb.event_stream import subscribe_events
|
||||
from bigchaindb.common.crypto import generate_key_pair
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
|
||||
@ -12,8 +12,8 @@ from io import BytesIO
|
||||
@pytest.mark.tendermint
|
||||
@pytest.mark.bdb
|
||||
def test_app(tb):
|
||||
from bigchaindb.tendermint import App
|
||||
from bigchaindb.tendermint.utils import calculate_hash
|
||||
from bigchaindb import App
|
||||
from bigchaindb.tendermint_utils import calculate_hash
|
||||
from bigchaindb.common.crypto import generate_key_pair
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
@ -103,7 +103,7 @@ def test_upsert_validator(b, alice):
|
||||
from bigchaindb.backend.query import VALIDATOR_UPDATE_ID
|
||||
from bigchaindb.backend import query, connect
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.tendermint.utils import public_key_to_base64
|
||||
from bigchaindb.tendermint_utils import public_key_to_base64
|
||||
import time
|
||||
|
||||
conn = connect()
|
||||
|
||||
@ -47,7 +47,7 @@ def test_asset_is_separated_from_transaciton(b):
|
||||
|
||||
@pytest.mark.bdb
|
||||
def test_get_latest_block(tb):
|
||||
from bigchaindb.tendermint.lib import Block
|
||||
from bigchaindb.lib import Block
|
||||
|
||||
b = tb
|
||||
for i in range(10):
|
||||
@ -63,7 +63,7 @@ def test_get_latest_block(tb):
|
||||
|
||||
@pytest.mark.bdb
|
||||
@patch('bigchaindb.backend.query.get_block', return_value=None)
|
||||
@patch('bigchaindb.tendermint.lib.BigchainDB.get_latest_block', return_value={'height': 10})
|
||||
@patch('bigchaindb.BigchainDB.get_latest_block', return_value={'height': 10})
|
||||
def test_get_empty_block(_0, _1, tb):
|
||||
assert tb.get_block(5) == {'height': 5, 'transactions': []}
|
||||
|
||||
@ -86,7 +86,7 @@ def test_validation_error(b):
|
||||
def test_write_and_post_transaction(mock_post, b):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.crypto import generate_key_pair
|
||||
from bigchaindb.tendermint.utils import encode_transaction
|
||||
from bigchaindb.tendermint_utils import encode_transaction
|
||||
|
||||
alice = generate_key_pair()
|
||||
tx = Transaction.create([alice.public_key],
|
||||
|
||||
@ -12,7 +12,7 @@ pytestmark = pytest.mark.tendermint
|
||||
|
||||
|
||||
def test_encode_decode_transaction(b):
|
||||
from bigchaindb.tendermint.utils import (encode_transaction,
|
||||
from bigchaindb.tendermint_utils import (encode_transaction,
|
||||
decode_transaction)
|
||||
|
||||
asset = {
|
||||
@ -30,7 +30,7 @@ def test_encode_decode_transaction(b):
|
||||
|
||||
|
||||
def test_calculate_hash_no_key(b):
|
||||
from bigchaindb.tendermint.utils import calculate_hash
|
||||
from bigchaindb.tendermint_utils import calculate_hash
|
||||
|
||||
# pass an empty list
|
||||
assert calculate_hash([]) == ''
|
||||
@ -38,7 +38,7 @@ def test_calculate_hash_no_key(b):
|
||||
|
||||
# TODO test for the case of an empty list of hashes, and possibly other cases.
|
||||
def test_merkleroot():
|
||||
from bigchaindb.tendermint.utils import merkleroot
|
||||
from bigchaindb.tendermint_utils import merkleroot
|
||||
hashes = [sha3_256(i.encode()).digest() for i in 'abc']
|
||||
assert merkleroot(hashes) == (
|
||||
'78c7c394d3158c218916b7ae0ebdea502e0f4e85c08e3b371e3dfd824d389fa3')
|
||||
@ -54,14 +54,14 @@ SAMPLE_PUBLIC_KEY = {
|
||||
|
||||
|
||||
def test_convert_base64_public_key_to_address():
|
||||
from bigchaindb.tendermint.utils import public_key64_to_address
|
||||
from bigchaindb.tendermint_utils import public_key64_to_address
|
||||
|
||||
address = public_key64_to_address(SAMPLE_PUBLIC_KEY['pub_key']['value'])
|
||||
assert address == SAMPLE_PUBLIC_KEY['address']
|
||||
|
||||
|
||||
def test_public_key_encoding_decoding():
|
||||
from bigchaindb.tendermint.utils import (public_key_from_base64,
|
||||
from bigchaindb.tendermint_utils import (public_key_from_base64,
|
||||
public_key_to_base64)
|
||||
|
||||
public_key = public_key_from_base64(SAMPLE_PUBLIC_KEY['pub_key']['value'])
|
||||
|
||||
@ -1,292 +0,0 @@
|
||||
import pytest
|
||||
from pytest import raises
|
||||
|
||||
|
||||
class TestBlockModel(object):
|
||||
def test_block_initialization(self, monkeypatch):
|
||||
from bigchaindb.models import Block
|
||||
|
||||
monkeypatch.setattr('time.time', lambda: 1)
|
||||
|
||||
block = Block()
|
||||
assert block.transactions == []
|
||||
assert block.timestamp == '1'
|
||||
assert block.node_pubkey is None
|
||||
assert block.signature is None
|
||||
|
||||
with raises(TypeError):
|
||||
Block('not a list or None')
|
||||
|
||||
def test_block_serialization(self, b, alice):
|
||||
from bigchaindb.common.crypto import hash_data
|
||||
from bigchaindb.common.utils import gen_timestamp, serialize
|
||||
from bigchaindb.models import Block, Transaction
|
||||
|
||||
transactions = [Transaction.create([alice.public_key], [([alice.public_key], 1)])]
|
||||
timestamp = gen_timestamp()
|
||||
expected_block = {
|
||||
'timestamp': timestamp,
|
||||
'transactions': [tx.to_dict() for tx in transactions],
|
||||
'node_pubkey': alice.public_key,
|
||||
}
|
||||
expected = {
|
||||
'id': hash_data(serialize(expected_block)),
|
||||
'block': expected_block,
|
||||
'signature': None,
|
||||
}
|
||||
|
||||
block = Block(transactions, alice.public_key, timestamp)
|
||||
|
||||
assert block.to_dict() == expected
|
||||
|
||||
def test_block_invalid_serializaton(self):
|
||||
from bigchaindb.models import Block
|
||||
|
||||
block = Block([])
|
||||
with raises(ValueError):
|
||||
block.to_dict()
|
||||
|
||||
def test_block_deserialization(self, b, alice):
|
||||
from bigchaindb.common.crypto import hash_data
|
||||
from bigchaindb.common.utils import gen_timestamp, serialize
|
||||
from bigchaindb.models import Block, Transaction
|
||||
|
||||
transaction = Transaction.create([alice.public_key], [([alice.public_key], 1)])
|
||||
transaction.sign([alice.private_key])
|
||||
timestamp = gen_timestamp()
|
||||
expected = Block([transaction], alice.public_key, timestamp)
|
||||
|
||||
block = {
|
||||
'timestamp': timestamp,
|
||||
'transactions': [transaction.to_dict()],
|
||||
'node_pubkey': alice.public_key,
|
||||
}
|
||||
|
||||
block_body = {
|
||||
'id': hash_data(serialize(block)),
|
||||
'block': block,
|
||||
'signature': None,
|
||||
}
|
||||
|
||||
assert expected == Block.from_dict(block_body)
|
||||
|
||||
def test_block_invalid_id_deserialization(self, b, alice):
|
||||
from bigchaindb.common.exceptions import InvalidHash
|
||||
from bigchaindb.models import Block
|
||||
|
||||
block = {
|
||||
'id': 'an invalid id',
|
||||
'block': {
|
||||
'node_pubkey': alice.public_key,
|
||||
}
|
||||
}
|
||||
|
||||
with raises(InvalidHash):
|
||||
Block.from_dict(block)
|
||||
|
||||
def test_block_invalid_signature(self, b, alice):
|
||||
from bigchaindb.common.crypto import hash_data
|
||||
from bigchaindb.common.exceptions import InvalidSignature
|
||||
from bigchaindb.common.utils import gen_timestamp, serialize
|
||||
from bigchaindb.models import Block, Transaction
|
||||
|
||||
transaction = Transaction.create([alice.public_key], [([alice.public_key], 1)])
|
||||
transaction.sign([alice.private_key])
|
||||
timestamp = gen_timestamp()
|
||||
|
||||
block = {
|
||||
'timestamp': timestamp,
|
||||
'transactions': [transaction.to_dict()],
|
||||
'node_pubkey': alice.public_key,
|
||||
}
|
||||
|
||||
block_body = {
|
||||
'id': hash_data(serialize(block)),
|
||||
'block': block,
|
||||
'signature': 'an invalid signature',
|
||||
}
|
||||
|
||||
with raises(InvalidSignature):
|
||||
Block.from_dict(block_body).validate(b)
|
||||
|
||||
def test_compare_blocks(self, b, alice):
|
||||
from bigchaindb.models import Block, Transaction
|
||||
|
||||
transactions = [Transaction.create([alice.public_key], [([alice.public_key], 1)])]
|
||||
|
||||
assert Block() != 'invalid comparison'
|
||||
assert Block(transactions) == Block(transactions)
|
||||
|
||||
def test_sign_block(self, b, alice):
|
||||
from bigchaindb.common.crypto import PrivateKey, PublicKey
|
||||
from bigchaindb.common.utils import gen_timestamp, serialize
|
||||
from bigchaindb.models import Block, Transaction
|
||||
|
||||
transactions = [Transaction.create([alice.public_key], [([alice.public_key], 1)])]
|
||||
timestamp = gen_timestamp()
|
||||
expected_block = {
|
||||
'timestamp': timestamp,
|
||||
'transactions': [tx.to_dict() for tx in transactions],
|
||||
'node_pubkey': alice.public_key,
|
||||
}
|
||||
expected_block_serialized = serialize(expected_block).encode()
|
||||
expected = PrivateKey(alice.private_key).sign(expected_block_serialized)
|
||||
block = Block(transactions, alice.public_key, timestamp)
|
||||
block = block.sign(alice.private_key)
|
||||
assert block.signature == expected.decode()
|
||||
|
||||
public_key = PublicKey(alice.public_key)
|
||||
assert public_key.verify(expected_block_serialized, block.signature)
|
||||
|
||||
def test_block_dupe_tx(self, b, alice):
|
||||
from bigchaindb.models import Block, Transaction
|
||||
from bigchaindb.common.exceptions import DuplicateTransaction
|
||||
|
||||
tx = Transaction.create([alice.public_key], [([alice.public_key], 1)])
|
||||
block = Block([tx, tx], alice.public_key)
|
||||
block.sign(alice.private_key)
|
||||
b.store_block(block.to_dict())
|
||||
with raises(DuplicateTransaction):
|
||||
block.validate(b)
|
||||
|
||||
def test_decouple_assets(self, b, alice):
|
||||
from bigchaindb.models import Block, Transaction
|
||||
|
||||
assets = [
|
||||
{'msg': '1'},
|
||||
{'msg': '2'},
|
||||
{'msg': '3'},
|
||||
]
|
||||
|
||||
txs = []
|
||||
# create 3 assets
|
||||
for asset in assets:
|
||||
tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset=asset)
|
||||
tx.sign([alice.private_key])
|
||||
txs.append(tx)
|
||||
|
||||
# create a `TRANSFER` transaction.
|
||||
# the asset in `TRANSFER` transactions is not extracted
|
||||
tx = Transaction.transfer(txs[0].to_inputs(), [([alice.public_key], 1)],
|
||||
asset_id=txs[0].id)
|
||||
tx.sign([alice.private_key])
|
||||
txs.append(tx)
|
||||
|
||||
# create the block
|
||||
block = Block(txs)
|
||||
# decouple assets
|
||||
assets_from_block, block_dict = block.decouple_assets()
|
||||
|
||||
assert len(assets_from_block) == 3
|
||||
for i in range(3):
|
||||
assert assets_from_block[i]['data'] == assets[i]
|
||||
assert assets_from_block[i]['id'] == txs[i].id
|
||||
|
||||
# check the `TRANSFER` transaction was not changed
|
||||
assert block.transactions[3].to_dict() == \
|
||||
block_dict['block']['transactions'][3]
|
||||
|
||||
def test_couple_assets(self, b, alice):
|
||||
from bigchaindb.models import Block, Transaction
|
||||
|
||||
assets = [
|
||||
{'msg': '1'},
|
||||
{'msg': '2'},
|
||||
{'msg': '3'},
|
||||
]
|
||||
|
||||
txs = []
|
||||
# create 3 assets
|
||||
for asset in assets:
|
||||
tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset=asset)
|
||||
tx.sign([alice.private_key])
|
||||
txs.append(tx)
|
||||
|
||||
# create a `TRANSFER` transaction.
|
||||
# the asset in `TRANSFER` transactions is not extracted
|
||||
tx = Transaction.transfer(txs[0].to_inputs(), [([alice.public_key], 1)],
|
||||
asset_id=txs[0].id)
|
||||
tx.sign([alice.private_key])
|
||||
txs.append(tx)
|
||||
|
||||
# create the block
|
||||
block = Block(txs)
|
||||
# decouple assets
|
||||
assets_from_block, block_dict = block.decouple_assets()
|
||||
|
||||
# reconstruct the block
|
||||
block_dict_reconstructed = Block.couple_assets(block_dict,
|
||||
assets_from_block)
|
||||
|
||||
# check that the reconstructed block is the same as the original block
|
||||
assert block == Block.from_dict(block_dict_reconstructed)
|
||||
|
||||
def test_get_asset_ids(self, b, alice):
|
||||
from bigchaindb.models import Block, Transaction
|
||||
|
||||
assets = [
|
||||
{'msg': '1'},
|
||||
{'msg': '2'},
|
||||
{'msg': '3'},
|
||||
]
|
||||
|
||||
txs = []
|
||||
# create 3 assets
|
||||
for asset in assets:
|
||||
tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset=asset)
|
||||
tx.sign([alice.private_key])
|
||||
txs.append(tx)
|
||||
|
||||
# create a `TRANSFER` transaction.
|
||||
# the asset in `TRANSFER` transactions is not extracted
|
||||
tx = Transaction.transfer(txs[0].to_inputs(), [([alice.public_key], 1)],
|
||||
asset_id=txs[0].id)
|
||||
tx.sign([alice.private_key])
|
||||
txs.append(tx)
|
||||
|
||||
# create the block
|
||||
block = Block(txs)
|
||||
# decouple assets
|
||||
assets_from_block, block_dict = block.decouple_assets()
|
||||
|
||||
# get the asset_ids and check that they are the same as the `CREATE`
|
||||
# transactions
|
||||
asset_ids = Block.get_asset_ids(block_dict)
|
||||
assert asset_ids == [tx.id for tx in txs[:-1]]
|
||||
|
||||
@pytest.mark.bdb
|
||||
def test_from_db(self, b, alice):
|
||||
from bigchaindb.models import Block, Transaction
|
||||
|
||||
assets = [
|
||||
{'msg': '1'},
|
||||
{'msg': '2'},
|
||||
{'msg': '3'},
|
||||
]
|
||||
|
||||
txs = []
|
||||
# create 3 assets
|
||||
for asset in assets:
|
||||
tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset=asset)
|
||||
tx.sign([alice.private_key])
|
||||
txs.append(tx)
|
||||
|
||||
# create a `TRANSFER` transaction.
|
||||
# the asset in `TRANSFER` transactions is not extracted
|
||||
tx = Transaction.transfer(txs[0].to_inputs(), [([alice.public_key], 1)],
|
||||
asset_id=txs[0].id)
|
||||
tx.sign([alice.private_key])
|
||||
txs.append(tx)
|
||||
|
||||
# create the block
|
||||
block = Block(txs)
|
||||
# decouple assets
|
||||
assets_from_block, block_dict = block.decouple_assets()
|
||||
|
||||
# write the assets and block separately
|
||||
b.write_assets(assets_from_block)
|
||||
b.write_block(block)
|
||||
|
||||
# check the reconstructed block is the same as the original block
|
||||
block_from_db = Block.from_db(b, block_dict)
|
||||
assert block == block_from_db
|
||||
@ -35,7 +35,7 @@ def test_bigchain_instance_raises_when_not_configured(request, monkeypatch):
|
||||
import bigchaindb
|
||||
from bigchaindb import config_utils
|
||||
from bigchaindb.common import exceptions
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb import BigchainDB
|
||||
assert 'CONFIGURED' not in bigchaindb.config
|
||||
|
||||
# We need to disable ``bigchaindb.config_utils.autoconfigure`` to avoid reading
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
import pytest
|
||||
|
||||
|
||||
pytestmark = pytest.mark.tendermint
|
||||
|
||||
|
||||
@pytest.mark.skipif(reason='will be fixed in another PR')
|
||||
@pytest.fixture
|
||||
def config(request, monkeypatch):
|
||||
backend = request.config.getoption('--database-backend')
|
||||
@ -25,8 +29,9 @@ def config(request, monkeypatch):
|
||||
return config
|
||||
|
||||
|
||||
@pytest.mark.skipif(reason='will be fixed in another PR')
|
||||
def test_bigchain_class_default_initialization(config):
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb import BigchainDB
|
||||
from bigchaindb.consensus import BaseConsensusRules
|
||||
from bigchaindb.backend.connection import Connection
|
||||
bigchain = BigchainDB()
|
||||
@ -37,8 +42,9 @@ def test_bigchain_class_default_initialization(config):
|
||||
assert bigchain.consensus == BaseConsensusRules
|
||||
|
||||
|
||||
@pytest.mark.skipif(reason='will be fixed in another PR')
|
||||
def test_bigchain_class_initialization_with_parameters(config):
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb import BigchainDB
|
||||
from bigchaindb.backend import connect
|
||||
from bigchaindb.consensus import BaseConsensusRules
|
||||
init_db_kwargs = {
|
||||
@ -56,9 +62,10 @@ def test_bigchain_class_initialization_with_parameters(config):
|
||||
assert bigchain.consensus == BaseConsensusRules
|
||||
|
||||
|
||||
@pytest.mark.skipif(reason='will be fixed in another PR')
|
||||
def test_get_blocks_status_containing_tx(monkeypatch):
|
||||
from bigchaindb.backend import query as backend_query
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb import BigchainDB
|
||||
blocks = [
|
||||
{'id': 1}, {'id': 2}
|
||||
]
|
||||
@ -77,6 +84,8 @@ def test_get_spent_issue_1271(b, alice, bob, carol):
|
||||
[carol.public_key],
|
||||
[([carol.public_key], 8)],
|
||||
).sign([carol.private_key])
|
||||
assert b.validate_transaction(tx_1)
|
||||
b.store_bulk_transactions([tx_1])
|
||||
|
||||
tx_2 = Transaction.transfer(
|
||||
tx_1.to_inputs(),
|
||||
@ -85,6 +94,8 @@ def test_get_spent_issue_1271(b, alice, bob, carol):
|
||||
([carol.public_key], 4)],
|
||||
asset_id=tx_1.id,
|
||||
).sign([carol.private_key])
|
||||
assert b.validate_transaction(tx_2)
|
||||
b.store_bulk_transactions([tx_2])
|
||||
|
||||
tx_3 = Transaction.transfer(
|
||||
tx_2.to_inputs()[2:3],
|
||||
@ -92,20 +103,25 @@ def test_get_spent_issue_1271(b, alice, bob, carol):
|
||||
([carol.public_key], 3)],
|
||||
asset_id=tx_1.id,
|
||||
).sign([carol.private_key])
|
||||
assert b.validate_transaction(tx_3)
|
||||
b.store_bulk_transactions([tx_3])
|
||||
|
||||
tx_4 = Transaction.transfer(
|
||||
tx_2.to_inputs()[1:2] + tx_3.to_inputs()[0:1],
|
||||
[([bob.public_key], 3)],
|
||||
asset_id=tx_1.id,
|
||||
).sign([alice.private_key])
|
||||
assert b.validate_transaction(tx_4)
|
||||
b.store_bulk_transactions([tx_4])
|
||||
|
||||
tx_5 = Transaction.transfer(
|
||||
tx_2.to_inputs()[0:1],
|
||||
[([alice.public_key], 2)],
|
||||
asset_id=tx_1.id,
|
||||
).sign([bob.private_key])
|
||||
block_5 = b.create_block([tx_1, tx_2, tx_3, tx_4, tx_5])
|
||||
b.write_block(block_5)
|
||||
assert b.validate_transaction(tx_5)
|
||||
b.store_bulk_transactions([tx_5])
|
||||
|
||||
assert b.get_spent(tx_2.id, 0) == tx_5
|
||||
assert not b.get_spent(tx_5.id, 0)
|
||||
assert b.get_outputs_filtered(alice.public_key)
|
||||
|
||||
@ -4,7 +4,7 @@ import pytest
|
||||
@pytest.fixture
|
||||
def app(request):
|
||||
from bigchaindb.web import server
|
||||
from bigchaindb.tendermint.lib import BigchainDB
|
||||
from bigchaindb.lib import BigchainDB
|
||||
|
||||
if request.config.getoption('--database-backend') == 'localmongodb':
|
||||
app = server.create_app(debug=True, bigchaindb_factory=BigchainDB)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.tendermint.lib import Block
|
||||
from bigchaindb.lib import Block
|
||||
|
||||
BLOCKS_ENDPOINT = '/api/v1/blocks/'
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ def test_get_outputs_endpoint(client, user_pk):
|
||||
m = MagicMock()
|
||||
m.txid = 'a'
|
||||
m.output = 0
|
||||
with patch('bigchaindb.tendermint.lib.BigchainDB.get_outputs_filtered') as gof:
|
||||
with patch('bigchaindb.BigchainDB.get_outputs_filtered') as gof:
|
||||
gof.return_value = [m, m]
|
||||
res = client.get(OUTPUTS_ENDPOINT + '?public_key={}'.format(user_pk))
|
||||
assert res.json == [
|
||||
@ -27,7 +27,7 @@ def test_get_outputs_endpoint_unspent(client, user_pk):
|
||||
m = MagicMock()
|
||||
m.txid = 'a'
|
||||
m.output = 0
|
||||
with patch('bigchaindb.tendermint.lib.BigchainDB.get_outputs_filtered') as gof:
|
||||
with patch('bigchaindb.BigchainDB.get_outputs_filtered') as gof:
|
||||
gof.return_value = [m]
|
||||
params = '?spent=False&public_key={}'.format(user_pk)
|
||||
res = client.get(OUTPUTS_ENDPOINT + params)
|
||||
@ -41,7 +41,7 @@ def test_get_outputs_endpoint_spent(client, user_pk):
|
||||
m = MagicMock()
|
||||
m.txid = 'a'
|
||||
m.output = 0
|
||||
with patch('bigchaindb.tendermint.lib.BigchainDB.get_outputs_filtered') as gof:
|
||||
with patch('bigchaindb.BigchainDB.get_outputs_filtered') as gof:
|
||||
gof.return_value = [m]
|
||||
params = '?spent=true&public_key={}'.format(user_pk)
|
||||
res = client.get(OUTPUTS_ENDPOINT + params)
|
||||
|
||||
@ -372,7 +372,7 @@ def test_transactions_get_list_good(client):
|
||||
|
||||
asset_id = '1' * 64
|
||||
|
||||
with patch('bigchaindb.tendermint.BigchainDB.get_transactions_filtered', get_txs_patched):
|
||||
with patch('bigchaindb.BigchainDB.get_transactions_filtered', get_txs_patched):
|
||||
url = TX_ENDPOINT + '?asset_id=' + asset_id
|
||||
assert client.get(url).json == [
|
||||
['asset_id', asset_id],
|
||||
@ -389,7 +389,7 @@ def test_transactions_get_list_good(client):
|
||||
def test_transactions_get_list_bad(client):
|
||||
def should_not_be_called():
|
||||
assert False
|
||||
with patch('bigchaindb.tendermint.BigchainDB.get_transactions_filtered',
|
||||
with patch('bigchaindb.BigchainDB.get_transactions_filtered',
|
||||
lambda *_, **__: should_not_be_called()):
|
||||
# Test asset id validated
|
||||
url = TX_ENDPOINT + '?asset_id=' + '1' * 63
|
||||
@ -404,7 +404,7 @@ def test_transactions_get_list_bad(client):
|
||||
|
||||
@pytest.mark.tendermint
|
||||
def test_return_only_valid_transaction(client):
|
||||
from bigchaindb.tendermint import BigchainDB
|
||||
from bigchaindb import BigchainDB
|
||||
|
||||
def get_transaction_patched(status):
|
||||
def inner(self, tx_id, include_status):
|
||||
@ -415,12 +415,12 @@ def test_return_only_valid_transaction(client):
|
||||
# UNDECIDED or VALID block, as well as transactions from the backlog.
|
||||
# As the endpoint uses `get_transaction`, we don't have to test
|
||||
# against invalid transactions here.
|
||||
with patch('bigchaindb.tendermint.BigchainDB.get_transaction',
|
||||
with patch('bigchaindb.BigchainDB.get_transaction',
|
||||
get_transaction_patched(BigchainDB.TX_UNDECIDED)):
|
||||
url = '{}{}'.format(TX_ENDPOINT, '123')
|
||||
assert client.get(url).status_code == 404
|
||||
|
||||
with patch('bigchaindb.tendermint.BigchainDB.get_transaction',
|
||||
with patch('bigchaindb.BigchainDB.get_transaction',
|
||||
get_transaction_patched(BigchainDB.TX_IN_BACKLOG)):
|
||||
url = '{}{}'.format(TX_ENDPOINT, '123')
|
||||
assert client.get(url).status_code == 404
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user