mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-06-26 11:16:44 +02:00
Resolved conflicts in fabfile.py
This commit is contained in:
commit
c0648f7145
|
@ -526,22 +526,22 @@ class Bigchain(object):
|
|||
|
||||
return block
|
||||
|
||||
def vote(self, block, previous_block_id, decision, invalid_reason=None):
|
||||
def vote(self, block_id, previous_block_id, decision, invalid_reason=None):
|
||||
"""Cast your vote on the block given the previous_block_hash and the decision (valid/invalid)
|
||||
return the block to the updated in the database.
|
||||
|
||||
Args:
|
||||
block (dict): Block to vote.
|
||||
block_id (str): The id of the block to vote.
|
||||
previous_block_id (str): The id of the previous block.
|
||||
decision (bool): Whether the block is valid or invalid.
|
||||
invalid_reason (Optional[str]): Reason the block is invalid
|
||||
"""
|
||||
|
||||
if block['id'] == previous_block_id:
|
||||
if block_id == previous_block_id:
|
||||
raise exceptions.CyclicBlockchainError()
|
||||
|
||||
vote = {
|
||||
'voting_for_block': block['id'],
|
||||
'voting_for_block': block_id,
|
||||
'previous_block': previous_block_id,
|
||||
'is_block_valid': decision,
|
||||
'invalid_reason': invalid_reason,
|
||||
|
|
|
@ -18,55 +18,91 @@ def get_conn():
|
|||
bigchaindb.config['database']['port'])
|
||||
|
||||
|
||||
def get_database_name():
|
||||
return bigchaindb.config['database']['name']
|
||||
|
||||
|
||||
def create_database(conn, dbname):
|
||||
if r.db_list().contains(dbname).run(conn):
|
||||
raise exceptions.DatabaseAlreadyExists('Database `{}` already exists'.format(dbname))
|
||||
|
||||
logger.info('Create database `%s`.', dbname)
|
||||
r.db_create(dbname).run(conn)
|
||||
|
||||
|
||||
def create_table(conn, dbname, table_name):
|
||||
logger.info('Create `%s` table.', table_name)
|
||||
# create the table
|
||||
r.db(dbname).table_create(table_name).run(conn)
|
||||
|
||||
|
||||
def create_bigchain_secondary_index(conn, dbname):
|
||||
logger.info('Create `bigchain` secondary index.')
|
||||
# to order blocks by timestamp
|
||||
r.db(dbname).table('bigchain')\
|
||||
.index_create('block_timestamp', r.row['block']['timestamp'])\
|
||||
.run(conn)
|
||||
# to query the bigchain for a transaction id
|
||||
r.db(dbname).table('bigchain')\
|
||||
.index_create('transaction_id',
|
||||
r.row['block']['transactions']['id'], multi=True)\
|
||||
.run(conn)
|
||||
# secondary index for payload data by UUID
|
||||
r.db(dbname).table('bigchain')\
|
||||
.index_create('payload_uuid',
|
||||
r.row['block']['transactions']['transaction']['data']['uuid'], multi=True)\
|
||||
.run(conn)
|
||||
|
||||
# wait for rethinkdb to finish creating secondary indexes
|
||||
r.db(dbname).table('bigchain').index_wait().run(conn)
|
||||
|
||||
|
||||
def create_backlog_secondary_index(conn, dbname):
|
||||
logger.info('Create `backlog` secondary index.')
|
||||
# to order transactions by timestamp
|
||||
r.db(dbname).table('backlog')\
|
||||
.index_create('transaction_timestamp',
|
||||
r.row['transaction']['timestamp'])\
|
||||
.run(conn)
|
||||
# compound index to read transactions from the backlog per assignee
|
||||
r.db(dbname).table('backlog')\
|
||||
.index_create('assignee__transaction_timestamp',
|
||||
[r.row['assignee'], r.row['transaction']['timestamp']])\
|
||||
.run(conn)
|
||||
|
||||
# wait for rethinkdb to finish creating secondary indexes
|
||||
r.db(dbname).table('backlog').index_wait().run(conn)
|
||||
|
||||
|
||||
def create_votes_secondary_index(conn, dbname):
|
||||
logger.info('Create `votes` secondary index.')
|
||||
# compound index to order votes by block id and node
|
||||
r.db(dbname).table('votes')\
|
||||
.index_create('block_and_voter',
|
||||
[r.row['vote']['voting_for_block'],
|
||||
r.row['node_pubkey']])\
|
||||
.run(conn)
|
||||
|
||||
# wait for rethinkdb to finish creating secondary indexes
|
||||
r.db(dbname).table('votes').index_wait().run(conn)
|
||||
|
||||
|
||||
def init():
|
||||
# Try to access the keypair, throws an exception if it does not exist
|
||||
b = bigchaindb.Bigchain()
|
||||
|
||||
conn = get_conn()
|
||||
dbname = bigchaindb.config['database']['name']
|
||||
dbname = get_database_name()
|
||||
create_database(conn, dbname)
|
||||
|
||||
if r.db_list().contains(dbname).run(conn):
|
||||
raise exceptions.DatabaseAlreadyExists('Database `{}` already exists'.format(dbname))
|
||||
table_names = ['bigchain', 'backlog', 'votes']
|
||||
for table_name in table_names:
|
||||
create_table(conn, dbname, table_name)
|
||||
create_bigchain_secondary_index(conn, dbname)
|
||||
create_backlog_secondary_index(conn, dbname)
|
||||
create_votes_secondary_index(conn, dbname)
|
||||
|
||||
logger.info('Create:')
|
||||
logger.info(' - database `%s`', dbname)
|
||||
r.db_create(dbname).run(conn)
|
||||
|
||||
logger.info(' - tables')
|
||||
# create the tables
|
||||
r.db(dbname).table_create('bigchain').run(conn)
|
||||
r.db(dbname).table_create('backlog').run(conn)
|
||||
r.db(dbname).table_create('votes').run(conn)
|
||||
|
||||
logger.info(' - indexes')
|
||||
# create the secondary indexes
|
||||
# to order blocks by timestamp
|
||||
r.db(dbname).table('bigchain').index_create('block_timestamp', r.row['block']['timestamp']).run(conn)
|
||||
# to order transactions by timestamp
|
||||
r.db(dbname).table('backlog').index_create('transaction_timestamp', r.row['transaction']['timestamp']).run(conn)
|
||||
# to query the bigchain for a transaction id
|
||||
r.db(dbname).table('bigchain').index_create('transaction_id',
|
||||
r.row['block']['transactions']['id'], multi=True).run(conn)
|
||||
# compound index to read transactions from the backlog per assignee
|
||||
r.db(dbname).table('backlog')\
|
||||
.index_create('assignee__transaction_timestamp', [r.row['assignee'], r.row['transaction']['timestamp']])\
|
||||
.run(conn)
|
||||
|
||||
# compound index to order votes by block id and node
|
||||
r.db(dbname).table('votes').index_create('block_and_voter',
|
||||
[r.row['vote']['voting_for_block'], r.row['node_pubkey']]).run(conn)
|
||||
|
||||
# secondary index for payload data by UUID
|
||||
r.db(dbname).table('bigchain')\
|
||||
.index_create('payload_uuid', r.row['block']['transactions']['transaction']['data']['uuid'], multi=True)\
|
||||
.run(conn)
|
||||
|
||||
# wait for rethinkdb to finish creating secondary indexes
|
||||
r.db(dbname).table('backlog').index_wait().run(conn)
|
||||
r.db(dbname).table('bigchain').index_wait().run(conn)
|
||||
r.db(dbname).table('votes').index_wait().run(conn)
|
||||
|
||||
logger.info(' - genesis block')
|
||||
logger.info('Create genesis block.')
|
||||
b.create_genesis_block()
|
||||
logger.info('Done, have fun!')
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ class Voter(object):
|
|||
return
|
||||
|
||||
validated_block, previous_block_id, decision = elem
|
||||
vote = b.vote(validated_block, previous_block_id, decision)
|
||||
vote = b.vote(validated_block['id'], previous_block_id, decision)
|
||||
self.q_voted_block.put((validated_block, vote))
|
||||
|
||||
def update_block(self):
|
||||
|
@ -156,7 +156,8 @@ class Voter(object):
|
|||
return
|
||||
|
||||
block, vote = elem
|
||||
logger.info('updating block %s and with vote %s', block, vote)
|
||||
pretty_vote = 'valid' if vote['vote']['is_block_valid'] else 'invalid'
|
||||
logger.info('voting %s for block %s', pretty_vote, block['id'])
|
||||
b.write_vote(block, vote)
|
||||
|
||||
def bootstrap(self):
|
||||
|
|
|
@ -94,6 +94,8 @@ chmod +x add2known_hosts.sh
|
|||
# Rollout base packages (dependencies) needed before
|
||||
# storage backend (RethinkDB) and BigchainDB can be rolled out
|
||||
fab install_base_software
|
||||
fab get_pip3
|
||||
fab upgrade_setuptools
|
||||
|
||||
if [ "$WHAT_TO_DEPLOY" == "servers" ]; then
|
||||
# (Re)create the RethinkDB configuration file conf/rethinkdb.conf
|
||||
|
|
52
deploy-cluster-aws/fabfile.py
vendored
52
deploy-cluster-aws/fabfile.py
vendored
|
@ -52,24 +52,48 @@ def set_host(host_index):
|
|||
@task
|
||||
@parallel
|
||||
def install_base_software():
|
||||
# new from Troy April 5, 2016. Why? See http://tinyurl.com/lccfrsj
|
||||
# sudo('rm -rf /var/lib/apt/lists/*')
|
||||
# sudo('apt-get -y clean')
|
||||
# from before:
|
||||
# This deletes the dir where "apt-get update" stores the list of packages
|
||||
sudo('rm -rf /var/lib/apt/lists/')
|
||||
# Re-create that directory, and its subdirectory named "partial"
|
||||
sudo('mkdir -p /var/lib/apt/lists/partial/')
|
||||
# Repopulate the list of packages in /var/lib/apt/lists/
|
||||
# See https://tinyurl.com/zjvj9g3
|
||||
sudo('apt-get -y update')
|
||||
# Configure all unpacked but unconfigured packages.
|
||||
# See https://tinyurl.com/zf24hm5
|
||||
sudo('dpkg --configure -a')
|
||||
# Attempt to correct a system with broken dependencies in place.
|
||||
# See https://tinyurl.com/zpktd7l
|
||||
sudo('apt-get -y -f install')
|
||||
# For some reason, repeating the last three things makes this
|
||||
# installation process more reliable...
|
||||
sudo('apt-get -y update')
|
||||
sudo('dpkg --configure -a')
|
||||
sudo('apt-get -y -f install')
|
||||
sudo('apt-get -y install build-essential wget bzip2 ca-certificates \
|
||||
libglib2.0-0 libxext6 libsm6 libxrender1 \
|
||||
git gcc g++ python3-dev libboost-python-dev \
|
||||
software-properties-common python-software-properties \
|
||||
python3-setuptools ipython3 sysstat s3cmd')
|
||||
sudo('easy_install3 pip')
|
||||
# It seems that breaking apart
|
||||
# sudo('pip3 install --upgrade pip wheel setuptools')
|
||||
# into three separate statements is more reliable:
|
||||
# Install the base dependencies not already installed.
|
||||
sudo('apt-get -y install git g++ python3-dev')
|
||||
sudo('apt-get -y -f install')
|
||||
|
||||
|
||||
# Get an up-to-date Python 3 version of pip
|
||||
@task
|
||||
@parallel
|
||||
def get_pip3():
|
||||
# One way:
|
||||
# sudo('apt-get -y install python3-setuptools')
|
||||
# sudo('easy_install3 pip')
|
||||
# Another way:
|
||||
sudo('apt-get -y install python3-pip')
|
||||
# Upgrade pip
|
||||
sudo('pip3 install --upgrade pip')
|
||||
sudo('pip3 install --upgrade wheel')
|
||||
# Check the version of pip3
|
||||
run('pip3 --version')
|
||||
|
||||
|
||||
# Upgrade setuptools
|
||||
@task
|
||||
@parallel
|
||||
def upgrade_setuptools():
|
||||
sudo('pip3 install --upgrade setuptools')
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
The HTTP Client-Server API
|
||||
==========================
|
||||
|
||||
Note: The HTTP client-server API is currently quite rudimentary. For example, there is no ability to do complex queries using the HTTP API. We plan to add querying capabilities in the future. If you want to build a full-featured proof-of-concept, we suggest you use :doc:`the Python Server API <../nodes/python-server-api-examples>` for now.
|
||||
Note: The HTTP client-server API is currently quite rudimentary. For example, there is no ability to do complex queries using the HTTP API. We plan to add querying capabilities in the future. If you want to build a full-featured proof-of-concept, we suggest you use :doc:`the Python Server API <../drivers-clients/python-server-api-examples>` for now.
|
||||
|
||||
When you start Bigchaindb using `bigchaindb start`, an HTTP API is exposed at the address stored in the BigchainDB node configuration settings. The default is for that address to be:
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ BigchainDB Drivers & Clients
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
python-server-api-examples
|
||||
http-client-server-api
|
||||
python-driver-api-examples
|
||||
example-apps
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
# The Python Server API by Example
|
||||
|
||||
This section gives an example of using the Python Server API to interact _directly_ with a BigchainDB node running BigchainDB Server. That is, in this example, the Python code and BigchainDB Server run on the same machine.
|
||||
**Currently, the HTTP Client-Server API is very rudimentary, so you may want to use the Python Server API to develop prototype clients and applications, for now. Keep in mind that in the future, clients will only be able to use the HTTP Client-Server API (and possibly other Client-Server APIs) to communicate with BigchainDB nodes.**
|
||||
|
||||
(One can also interact with a BigchainDB node via other APIs, including the HTTP Client-Server API.)
|
||||
This section has examples of using the Python Server API to interact _directly_ with a BigchainDB node running BigchainDB Server. That is, in these examples, the Python code and BigchainDB Server run on the same machine.
|
||||
|
||||
One can also interact with a BigchainDB node via other APIs, including the HTTP Client-Server API.
|
||||
|
||||
We create a digital asset, sign it, write it to a BigchainDB Server instance, read it, transfer it to a different user, and then attempt to transfer it to another user, resulting in a double-spend error.
|
||||
|
||||
## Getting Started
|
||||
|
||||
|
@ -32,6 +33,7 @@ In a federation of BigchainDB nodes, each node has its own `Bigchain` instance.
|
|||
|
||||
The `Bigchain` class is the main API for all BigchainDB interactions, right now. It does things that BigchainDB nodes do, but it also does things that BigchainDB clients do. In the future, it will be refactored into different parts. The `Bigchain` class is documented [elsewhere (link)](../appendices/the-Bigchain-class.html).
|
||||
|
||||
|
||||
## Create a Digital Asset
|
||||
|
||||
At a high level, a "digital asset" is something which can be represented digitally and can be assigned to a user. In BigchainDB, users are identified by their public key, and the data payload in a digital asset is represented using a generic [Python dict](https://docs.python.org/3.4/tutorial/datastructures.html#dictionaries).
|
|
@ -13,4 +13,3 @@ BigchainDB Nodes
|
|||
running-unit-tests
|
||||
configuration
|
||||
bigchaindb-cli
|
||||
python-server-api-examples
|
||||
|
|
|
@ -35,4 +35,4 @@ bigchaindb start
|
|||
|
||||
That's it!
|
||||
|
||||
For now, you can get a good sense of how to work with BigchainDB by going through [the examples in the section on the Python Server API](nodes/python-server-api-examples.html).
|
||||
For now, you can get a good sense of how to work with BigchainDB by going through [the examples in the section on the Python Server API](drivers-clients/python-server-api-examples.html).
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# BigchainDB and Smart Contracts
|
||||
|
||||
BigchainDB isn’t intended for running smart contracts. That said, it can do many of the things that smart contracts are used to do. For example, the owners of an asset can impose conditions that must be fulfilled by anyone wishing to transfer the asset to new owners; see the [section on conditions](models.html#conditions-and-fulfillments). BigchainDB also [supports a form of escrow](../nodes/python-server-api-examples.html#escrow).
|
||||
BigchainDB isn’t intended for running smart contracts. That said, it can do many of the things that smart contracts are used to do. For example, the owners of an asset can impose conditions that must be fulfilled by anyone wishing to transfer the asset to new owners; see the [section on conditions](models.html#conditions-and-fulfillments). BigchainDB also [supports a form of escrow](../drivers-clients/python-server-api-examples.html#escrow).
|
||||
|
|
|
@ -139,7 +139,7 @@ class TestBigchainApi(object):
|
|||
b.write_block(block, durability='hard')
|
||||
|
||||
# vote the block invalid
|
||||
vote = b.vote(block, b.get_last_voted_block()['id'], False)
|
||||
vote = b.vote(block['id'], b.get_last_voted_block()['id'], False)
|
||||
b.write_vote(block, vote)
|
||||
response = b.get_transaction(tx_signed["id"])
|
||||
|
||||
|
@ -280,13 +280,13 @@ class TestBigchainApi(object):
|
|||
# make sure all the blocks are written at the same time
|
||||
monkeypatch.setattr(util, 'timestamp', lambda: '1')
|
||||
|
||||
b.write_vote(block_1, b.vote(block_1, b.get_last_voted_block()['id'], True))
|
||||
b.write_vote(block_1, b.vote(block_1['id'], b.get_last_voted_block()['id'], True))
|
||||
assert b.get_last_voted_block()['id'] == block_1['id']
|
||||
|
||||
b.write_vote(block_2, b.vote(block_2, b.get_last_voted_block()['id'], True))
|
||||
b.write_vote(block_2, b.vote(block_2['id'], b.get_last_voted_block()['id'], True))
|
||||
assert b.get_last_voted_block()['id'] == block_2['id']
|
||||
|
||||
b.write_vote(block_3, b.vote(block_3, b.get_last_voted_block()['id'], True))
|
||||
b.write_vote(block_3, b.vote(block_3['id'], b.get_last_voted_block()['id'], True))
|
||||
assert b.get_last_voted_block()['id'] == block_3['id']
|
||||
|
||||
|
||||
|
@ -305,15 +305,15 @@ class TestBigchainApi(object):
|
|||
|
||||
# make sure all the blocks are written at different timestamps
|
||||
monkeypatch.setattr(util, 'timestamp', lambda: '1')
|
||||
b.write_vote(block_1, b.vote(block_1, b.get_last_voted_block()['id'], True))
|
||||
b.write_vote(block_1, b.vote(block_1['id'], b.get_last_voted_block()['id'], True))
|
||||
assert b.get_last_voted_block()['id'] == block_1['id']
|
||||
|
||||
monkeypatch.setattr(util, 'timestamp', lambda: '2')
|
||||
b.write_vote(block_2, b.vote(block_2, b.get_last_voted_block()['id'], True))
|
||||
b.write_vote(block_2, b.vote(block_2['id'], b.get_last_voted_block()['id'], True))
|
||||
assert b.get_last_voted_block()['id'] == block_2['id']
|
||||
|
||||
monkeypatch.setattr(util, 'timestamp', lambda: '3')
|
||||
b.write_vote(block_3, b.vote(block_3, b.get_last_voted_block()['id'], True))
|
||||
b.write_vote(block_3, b.vote(block_3['id'], b.get_last_voted_block()['id'], True))
|
||||
assert b.get_last_voted_block()['id'] == block_3['id']
|
||||
|
||||
def test_no_vote_written_if_block_already_has_vote(self, b):
|
||||
|
@ -323,11 +323,11 @@ class TestBigchainApi(object):
|
|||
|
||||
b.write_block(block_1, durability='hard')
|
||||
|
||||
b.write_vote(block_1, b.vote(block_1, genesis['id'], True))
|
||||
b.write_vote(block_1, b.vote(block_1['id'], genesis['id'], True))
|
||||
retrieved_block_1 = r.table('bigchain').get(block_1['id']).run(b.conn)
|
||||
|
||||
# try to vote again on the retrieved block, should do nothing
|
||||
b.write_vote(retrieved_block_1, b.vote(retrieved_block_1, genesis['id'], True))
|
||||
b.write_vote(retrieved_block_1, b.vote(retrieved_block_1['id'], genesis['id'], True))
|
||||
retrieved_block_2 = r.table('bigchain').get(block_1['id']).run(b.conn)
|
||||
|
||||
assert retrieved_block_1 == retrieved_block_2
|
||||
|
@ -337,8 +337,8 @@ class TestBigchainApi(object):
|
|||
block_1 = dummy_block()
|
||||
b.write_block(block_1, durability='hard')
|
||||
# insert duplicate votes
|
||||
vote_1 = b.vote(block_1, b.get_last_voted_block()['id'], True)
|
||||
vote_2 = b.vote(block_1, b.get_last_voted_block()['id'], True)
|
||||
vote_1 = b.vote(block_1['id'], b.get_last_voted_block()['id'], True)
|
||||
vote_2 = b.vote(block_1['id'], b.get_last_voted_block()['id'], True)
|
||||
vote_2['node_pubkey'] = 'aaaaaaa'
|
||||
r.table('votes').insert(vote_1).run(b.conn)
|
||||
r.table('votes').insert(vote_2).run(b.conn)
|
||||
|
@ -355,7 +355,7 @@ class TestBigchainApi(object):
|
|||
b.write_block(block_1, durability='hard')
|
||||
# insert duplicate votes
|
||||
for i in range(2):
|
||||
r.table('votes').insert(b.vote(block_1, genesis['id'], True)).run(b.conn)
|
||||
r.table('votes').insert(b.vote(block_1['id'], genesis['id'], True)).run(b.conn)
|
||||
|
||||
from bigchaindb.exceptions import MultipleVotesError
|
||||
with pytest.raises(MultipleVotesError) as excinfo:
|
||||
|
@ -372,7 +372,7 @@ class TestBigchainApi(object):
|
|||
b.create_genesis_block()
|
||||
block_1 = dummy_block()
|
||||
b.write_block(block_1, durability='hard')
|
||||
vote_1 = b.vote(block_1, b.get_last_voted_block()['id'], True)
|
||||
vote_1 = b.vote(block_1['id'], b.get_last_voted_block()['id'], True)
|
||||
# mangle the signature
|
||||
vote_1['signature'] = 'a' * 87
|
||||
r.table('votes').insert(vote_1).run(b.conn)
|
||||
|
@ -816,9 +816,9 @@ class TestBigchainBlock(object):
|
|||
b.write_block(block_2, durability='hard')
|
||||
b.write_block(block_3, durability='hard')
|
||||
|
||||
b.write_vote(block_1, b.vote(block_1, b.get_last_voted_block()['id'], True))
|
||||
b.write_vote(block_2, b.vote(block_2, b.get_last_voted_block()['id'], True))
|
||||
b.write_vote(block_3, b.vote(block_3, b.get_last_voted_block()['id'], True))
|
||||
b.write_vote(block_1, b.vote(block_1['id'], b.get_last_voted_block()['id'], True))
|
||||
b.write_vote(block_2, b.vote(block_2['id'], b.get_last_voted_block()['id'], True))
|
||||
b.write_vote(block_3, b.vote(block_3['id'], b.get_last_voted_block()['id'], True))
|
||||
|
||||
q_revert_delete = mp.Queue()
|
||||
|
||||
|
@ -1115,7 +1115,7 @@ class TestMultipleInputs(object):
|
|||
b.write_block(block, durability='hard')
|
||||
|
||||
# vote the block VALID
|
||||
vote = b.vote(block, genesis['id'], True)
|
||||
vote = b.vote(block['id'], genesis['id'], True)
|
||||
b.write_vote(block, vote)
|
||||
|
||||
# get input
|
||||
|
@ -1131,7 +1131,7 @@ class TestMultipleInputs(object):
|
|||
b.write_block(block, durability='hard')
|
||||
|
||||
# vote the block invalid
|
||||
vote = b.vote(block, b.get_last_voted_block()['id'], False)
|
||||
vote = b.vote(block['id'], b.get_last_voted_block()['id'], False)
|
||||
b.write_vote(block, vote)
|
||||
|
||||
owned_inputs_user1 = b.get_owned_ids(user_vk)
|
||||
|
@ -1245,7 +1245,7 @@ class TestMultipleInputs(object):
|
|||
b.write_block(block, durability='hard')
|
||||
|
||||
# vote the block VALID
|
||||
vote = b.vote(block, genesis['id'], True)
|
||||
vote = b.vote(block['id'], genesis['id'], True)
|
||||
b.write_vote(block, vote)
|
||||
|
||||
# get input
|
||||
|
@ -1262,7 +1262,7 @@ class TestMultipleInputs(object):
|
|||
b.write_block(block, durability='hard')
|
||||
|
||||
# vote the block invalid
|
||||
vote = b.vote(block, b.get_last_voted_block()['id'], False)
|
||||
vote = b.vote(block['id'], b.get_last_voted_block()['id'], False)
|
||||
b.write_vote(block, vote)
|
||||
response = b.get_transaction(tx_signed["id"])
|
||||
spent_inputs_user1 = b.get_spent(owned_inputs_user1[0])
|
||||
|
|
|
@ -37,6 +37,113 @@ def test_init_creates_db_tables_and_indexes():
|
|||
'assignee__transaction_timestamp').run(conn) is True
|
||||
|
||||
|
||||
def test_create_database():
|
||||
conn = utils.get_conn()
|
||||
dbname = utils.get_database_name()
|
||||
|
||||
# The db is set up by fixtures so we need to remove it
|
||||
# and recreate it just with one table
|
||||
r.db_drop(dbname).run(conn)
|
||||
utils.create_database(conn, dbname)
|
||||
assert r.db_list().contains(dbname).run(conn) is True
|
||||
|
||||
|
||||
def test_create_bigchain_table():
|
||||
conn = utils.get_conn()
|
||||
dbname = utils.get_database_name()
|
||||
|
||||
# The db is set up by fixtures so we need to remove it
|
||||
# and recreate it just with one table
|
||||
r.db_drop(dbname).run(conn)
|
||||
utils.create_database(conn, dbname)
|
||||
utils.create_table(conn, dbname, 'bigchain')
|
||||
|
||||
assert r.db(dbname).table_list().contains('bigchain').run(conn) is True
|
||||
assert r.db(dbname).table_list().contains('backlog').run(conn) is False
|
||||
assert r.db(dbname).table_list().contains('votes').run(conn) is False
|
||||
|
||||
|
||||
def test_create_bigchain_secondary_index():
|
||||
conn = utils.get_conn()
|
||||
dbname = utils.get_database_name()
|
||||
|
||||
# The db is set up by fixtures so we need to remove it
|
||||
# and recreate it just with one table
|
||||
r.db_drop(dbname).run(conn)
|
||||
utils.create_database(conn, dbname)
|
||||
utils.create_table(conn, dbname, 'bigchain')
|
||||
utils.create_bigchain_secondary_index(conn, dbname)
|
||||
|
||||
assert r.db(dbname).table('bigchain').index_list().contains(
|
||||
'block_timestamp').run(conn) is True
|
||||
assert r.db(dbname).table('bigchain').index_list().contains(
|
||||
'transaction_id').run(conn) is True
|
||||
assert r.db(dbname).table('bigchain').index_list().contains(
|
||||
'payload_uuid').run(conn) is True
|
||||
|
||||
|
||||
def test_create_backlog_table():
|
||||
conn = utils.get_conn()
|
||||
dbname = utils.get_database_name()
|
||||
|
||||
# The db is set up by fixtures so we need to remove it
|
||||
# and recreate it just with one table
|
||||
r.db_drop(dbname).run(conn)
|
||||
utils.create_database(conn, dbname)
|
||||
utils.create_table(conn, dbname, 'backlog')
|
||||
|
||||
assert r.db(dbname).table_list().contains('backlog').run(conn) is True
|
||||
assert r.db(dbname).table_list().contains('bigchain').run(conn) is False
|
||||
assert r.db(dbname).table_list().contains('votes').run(conn) is False
|
||||
|
||||
|
||||
def test_create_backlog_secondary_index():
|
||||
conn = utils.get_conn()
|
||||
dbname = utils.get_database_name()
|
||||
|
||||
# The db is set up by fixtures so we need to remove it
|
||||
# and recreate it just with one table
|
||||
r.db_drop(dbname).run(conn)
|
||||
utils.create_database(conn, dbname)
|
||||
utils.create_table(conn, dbname, 'backlog')
|
||||
utils.create_backlog_secondary_index(conn, dbname)
|
||||
|
||||
assert r.db(dbname).table('backlog').index_list().contains(
|
||||
'transaction_timestamp').run(conn) is True
|
||||
assert r.db(dbname).table('backlog').index_list().contains(
|
||||
'assignee__transaction_timestamp').run(conn) is True
|
||||
|
||||
|
||||
def test_create_votes_table():
|
||||
conn = utils.get_conn()
|
||||
dbname = utils.get_database_name()
|
||||
|
||||
# The db is set up by fixtures so we need to remove it
|
||||
# and recreate it just with one table
|
||||
r.db_drop(dbname).run(conn)
|
||||
utils.create_database(conn, dbname)
|
||||
utils.create_table(conn, dbname, 'votes')
|
||||
|
||||
assert r.db(dbname).table_list().contains('votes').run(conn) is True
|
||||
assert r.db(dbname).table_list().contains('bigchain').run(conn) is False
|
||||
assert r.db(dbname).table_list().contains('backlog').run(conn) is False
|
||||
|
||||
|
||||
def test_create_votes_secondary_index():
|
||||
conn = utils.get_conn()
|
||||
dbname = utils.get_database_name()
|
||||
|
||||
# The db is set up by fixtures so we need to remove it
|
||||
# and recreate it just with one table
|
||||
r.db_drop(dbname).run(conn)
|
||||
utils.create_database(conn, dbname)
|
||||
utils.create_table(conn, dbname, 'votes')
|
||||
utils.create_votes_secondary_index(conn, dbname)
|
||||
|
||||
assert r.db(dbname).table('votes').index_list().contains(
|
||||
'block_and_voter').run(conn) is True
|
||||
|
||||
|
||||
def test_init_fails_if_db_exists():
|
||||
conn = utils.get_conn()
|
||||
dbname = bigchaindb.config['database']['name']
|
||||
|
|
|
@ -237,7 +237,7 @@ class TestBigchainVoter(object):
|
|||
# create valid block
|
||||
block = dummy_block()
|
||||
# retrieve vote
|
||||
vote = b.vote(block, 'abc', True)
|
||||
vote = b.vote(block['id'], 'abc', True)
|
||||
|
||||
# assert vote is correct
|
||||
assert vote['vote']['voting_for_block'] == block['id']
|
||||
|
@ -251,7 +251,7 @@ class TestBigchainVoter(object):
|
|||
# create valid block
|
||||
block = dummy_block()
|
||||
# retrieve vote
|
||||
vote = b.vote(block, 'abc', False)
|
||||
vote = b.vote(block['id'], 'abc', False)
|
||||
|
||||
# assert vote is correct
|
||||
assert vote['vote']['voting_for_block'] == block['id']
|
||||
|
@ -372,15 +372,15 @@ class TestBlockElection(object):
|
|||
test_block['block']['voters'] = [key_pair[1] for key_pair in key_pairs]
|
||||
|
||||
# fake "yes" votes
|
||||
valid_vote = [member.vote(test_block, 'abc', True)
|
||||
valid_vote = [member.vote(test_block['id'], 'abc', True)
|
||||
for member in test_federation]
|
||||
|
||||
# fake "no" votes
|
||||
invalid_vote = [member.vote(test_block, 'abc', False)
|
||||
invalid_vote = [member.vote(test_block['id'], 'abc', False)
|
||||
for member in test_federation]
|
||||
|
||||
# fake "yes" votes with incorrect signatures
|
||||
improperly_signed_valid_vote = [member.vote(test_block, 'abc', True) for
|
||||
improperly_signed_valid_vote = [member.vote(test_block['id'], 'abc', True) for
|
||||
member in test_federation]
|
||||
[vote['vote'].update(this_should_ruin_things='lol')
|
||||
for vote in improperly_signed_valid_vote]
|
||||
|
@ -448,11 +448,11 @@ class TestBlockElection(object):
|
|||
test_block['block']['voters'] = [key_pair[1] for key_pair in key_pairs]
|
||||
|
||||
# fake "yes" votes
|
||||
valid_vote = [member.vote(test_block, 'abc', True)
|
||||
valid_vote = [member.vote(test_block['id'], 'abc', True)
|
||||
for member in test_federation]
|
||||
|
||||
# fake "no" votes
|
||||
invalid_vote = [member.vote(test_block, 'abc', False)
|
||||
invalid_vote = [member.vote(test_block['id'], 'abc', False)
|
||||
for member in test_federation]
|
||||
|
||||
r.table('votes').insert(valid_vote[:2], durability='hard').run(b.conn)
|
||||
|
@ -490,12 +490,12 @@ class TestBlockElection(object):
|
|||
test_block_2['block']['voters'] = [key_pair[1] for key_pair in key_pairs]
|
||||
|
||||
# votes for block one
|
||||
vote_1 = [member.vote(test_block_1, 'abc', True)
|
||||
vote_1 = [member.vote(test_block_1['id'], 'abc', True)
|
||||
for member in test_federation]
|
||||
|
||||
# votes for block two
|
||||
vote_2 = [member.vote(test_block_2, 'abc', True) for member in test_federation[:2]] + \
|
||||
[member.vote(test_block_2, 'abc', False) for member in test_federation[2:]]
|
||||
vote_2 = [member.vote(test_block_2['id'], 'abc', True) for member in test_federation[:2]] + \
|
||||
[member.vote(test_block_2['id'], 'abc', False) for member in test_federation[2:]]
|
||||
|
||||
# construct valid block
|
||||
r.table('votes').insert(vote_1, durability='hard').run(b.conn)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import copy
|
||||
from unittest.mock import mock_open, patch
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -9,6 +10,19 @@ from bigchaindb import exceptions
|
|||
ORIGINAL_CONFIG = copy.deepcopy(bigchaindb._config)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ignore_local_config_file(monkeypatch):
|
||||
"""
|
||||
This fixture's purpose is to override the one under
|
||||
:module:`tests/conftest.py` so that the original behaviour of
|
||||
:func:`bigchaindb.config_utils.file_config` is restored, so that it can be
|
||||
tested.
|
||||
|
||||
"""
|
||||
from bigchaindb.config_utils import file_config
|
||||
monkeypatch.setattr('bigchaindb.config_utils.file_config', file_config)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=True)
|
||||
def clean_config(monkeypatch):
|
||||
monkeypatch.setattr('bigchaindb.config', copy.deepcopy(ORIGINAL_CONFIG))
|
||||
|
@ -205,3 +219,21 @@ def test_update_config(monkeypatch):
|
|||
assert bigchaindb.config['database']['host'] == 'test-host'
|
||||
assert bigchaindb.config['database']['name'] == 'bigchaindb_other'
|
||||
assert bigchaindb.config['database']['port'] == 28016
|
||||
|
||||
|
||||
def test_file_config():
|
||||
from bigchaindb.config_utils import file_config, CONFIG_DEFAULT_PATH
|
||||
with patch('builtins.open', mock_open(read_data='{}')) as m:
|
||||
config = file_config()
|
||||
m.assert_called_once_with(CONFIG_DEFAULT_PATH)
|
||||
assert config == {}
|
||||
|
||||
|
||||
def test_write_config():
|
||||
from bigchaindb.config_utils import write_config, CONFIG_DEFAULT_PATH
|
||||
m = mock_open()
|
||||
with patch('builtins.open', m):
|
||||
write_config({})
|
||||
m.assert_called_once_with(CONFIG_DEFAULT_PATH, 'w')
|
||||
handle = m()
|
||||
handle.write.assert_called_once_with('{}')
|
Loading…
Reference in New Issue
Block a user