1
0
mirror of https://github.com/bigchaindb/bigchaindb.git synced 2024-06-26 11:16:44 +02:00

Merge branch 'master' into more-ways-to-add-tx-to-backlog

This commit is contained in:
troymc 2016-05-11 17:20:55 +02:00
commit fad0be47c1
21 changed files with 154 additions and 112 deletions

View File

@ -92,9 +92,12 @@ def run_gather_metrics(args):
num_transactions_received += block_num_transactions
elapsed_time = time_now - initial_time
elapsed_time = elapsed_time if elapsed_time != 0 else 1
percent_complete = round((num_transactions_received / num_transactions) * 100)
transactions_per_second = round(num_transactions_received / elapsed_time)
if elapsed_time != 0:
transactions_per_second = round(num_transactions_received / elapsed_time)
else:
transactions_per_second = float('nan')
logger.info('\t{:<20} {:<20} {:<20} {:<20}'.format(time_now, block_num_transactions,
transactions_per_second, percent_complete))
@ -103,9 +106,9 @@ def run_gather_metrics(args):
break
except KeyboardInterrupt:
logger.info('Interrupted. Exiting early...')
# close files
csv_file.close()
finally:
# close files
csv_file.close()
def main():

View File

@ -7,6 +7,7 @@ import rethinkdb as r
import bigchaindb
from bigchaindb import Bigchain
from bigchaindb.monitor import Monitor
from bigchaindb.util import ProcessGroup
logger = logging.getLogger(__name__)
@ -180,7 +181,9 @@ class Block(object):
# add results to the queue
for result in initial_results:
q_initial.put(result)
q_initial.put('stop')
for i in range(mp.cpu_count()):
q_initial.put('stop')
return q_initial
@ -203,17 +206,21 @@ class Block(object):
self._start()
logger.info('exiting block module...')
def kill(self):
for i in range(mp.cpu_count()):
self.q_new_transaction.put('stop')
def _start(self):
"""
Initialize, spawn, and start the processes
"""
# initialize the processes
p_filter = mp.Process(name='filter_transactions', target=self.filter_by_assignee)
p_validate = mp.Process(name='validate_transactions', target=self.validate_transactions)
p_blocks = mp.Process(name='create_blocks', target=self.create_blocks)
p_write = mp.Process(name='write_blocks', target=self.write_blocks)
p_delete = mp.Process(name='delete_transactions', target=self.delete_transactions)
p_filter = ProcessGroup(name='filter_transactions', target=self.filter_by_assignee)
p_validate = ProcessGroup(name='validate_transactions', target=self.validate_transactions)
p_blocks = ProcessGroup(name='create_blocks', target=self.create_blocks)
p_write = ProcessGroup(name='write_blocks', target=self.write_blocks)
p_delete = ProcessGroup(name='delete_transactions', target=self.delete_transactions)
# start the processes
p_filter.start()
@ -222,9 +229,3 @@ class Block(object):
p_write.start()
p_delete.start()
# join processes
p_filter.join()
p_validate.join()
p_blocks.join()
p_write.join()
p_delete.join()

View File

@ -16,6 +16,7 @@ import copy
import json
import logging
import collections
from functools import lru_cache
from pkg_resources import iter_entry_points, ResolutionError
@ -218,6 +219,7 @@ def autoconfigure(filename=None, config=None, force=False):
set_config(newconfig) # sets bigchaindb.config
@lru_cache()
def load_consensus_plugin(name=None):
"""Find and load the chosen consensus plugin.

View File

@ -15,6 +15,7 @@ class AbstractConsensusRules(metaclass=ABCMeta):
All methods listed below must be implemented.
"""
@staticmethod
@abstractmethod
def validate_transaction(bigchain, transaction):
"""Validate a transaction.
@ -31,8 +32,8 @@ class AbstractConsensusRules(metaclass=ABCMeta):
Descriptive exceptions indicating the reason the transaction failed.
See the `exceptions` module for bigchain-native error classes.
"""
raise NotImplementedError
@staticmethod
@abstractmethod
def validate_block(bigchain, block):
"""Validate a block.
@ -49,8 +50,8 @@ class AbstractConsensusRules(metaclass=ABCMeta):
Descriptive exceptions indicating the reason the block failed.
See the `exceptions` module for bigchain-native error classes.
"""
raise NotImplementedError
@staticmethod
@abstractmethod
def create_transaction(*args, **kwargs):
"""Create a new transaction.
@ -61,8 +62,8 @@ class AbstractConsensusRules(metaclass=ABCMeta):
Returns:
dict: newly constructed transaction.
"""
raise NotImplementedError
@staticmethod
@abstractmethod
def sign_transaction(transaction, *args, **kwargs):
"""Sign a transaction.
@ -74,20 +75,19 @@ class AbstractConsensusRules(metaclass=ABCMeta):
Returns:
dict: transaction with any signatures applied.
"""
raise NotImplementedError
@staticmethod
@abstractmethod
def verify_signature(signed_transaction):
"""Verify the signature of a transaction.
def validate_fulfillments(signed_transaction):
"""Validate the fulfillments of a transaction.
Args:
signed_transaction (dict): signed transaction to verify
Returns:
bool: True if the transaction's required signature data is present
bool: True if the transaction's required fulfillments are present
and correct, False otherwise.
"""
raise NotImplementedError
class BaseConsensusRules(AbstractConsensusRules):
@ -157,8 +157,8 @@ class BaseConsensusRules(AbstractConsensusRules):
if calculated_hash != transaction['id']:
raise exceptions.InvalidHash()
# Check signature
if not util.verify_signature(transaction):
# Check fulfillments
if not util.validate_fulfillments(transaction):
raise exceptions.InvalidSignature()
return transaction
@ -216,10 +216,10 @@ class BaseConsensusRules(AbstractConsensusRules):
return util.sign_tx(transaction, private_key)
@staticmethod
def verify_signature(signed_transaction):
"""Verify the signature of a transaction.
def validate_fulfillments(signed_transaction):
"""Validate the fulfillments of a transaction.
Refer to the documentation of ``bigchaindb.util.verify_signature``
Refer to the documentation of ``bigchaindb.util.validate_fulfillments``
"""
return util.verify_signature(signed_transaction)
return util.validate_fulfillments(signed_transaction)

View File

@ -25,16 +25,18 @@ class Bigchain(object):
consensus_plugin=None):
"""Initialize the Bigchain instance
There are three ways in which the Bigchain instance can get its parameters.
The order by which the parameters are chosen are:
1. Setting them by passing them to the `__init__` method itself.
2. Setting them as environment variables
3. Reading them from the `config.json` file.
A Bigchain instance has several configuration parameters (e.g. host).
If a parameter value is passed as an argument to the Bigchain
__init__ method, then that is the value it will have.
Otherwise, the parameter value will be the value from the local
configuration file. If it's not set in that file, then the value
will come from an environment variable. If that environment variable
isn't set, then the parameter will have its default value (defined in
bigchaindb.__init__).
Args:
host (str): hostname where the rethinkdb is running.
port (int): port in which rethinkb is running (usually 28015).
host (str): hostname where RethinkDB is running.
port (int): port in which RethinkDB is running (usually 28015).
dbname (str): the name of the database to connect to (usually bigchain).
public_key (str): the base58 encoded public key for the ED25519 curve.
private_key (str): the base58 encoded private key for the ED25519 curve.
@ -86,17 +88,17 @@ class Bigchain(object):
return self.consensus.sign_transaction(transaction, *args, **kwargs)
def verify_signature(self, signed_transaction, *args, **kwargs):
"""Verify the signature(s) of a transaction.
def validate_fulfillments(self, signed_transaction, *args, **kwargs):
"""Validate the fulfillment(s) of a transaction.
Refer to the documentation of your consensus plugin.
Returns:
bool: True if the transaction's required signature data is present
bool: True if the transaction's required fulfillments are present
and correct, False otherwise.
"""
return self.consensus.verify_signature(
return self.consensus.validate_fulfillments(
signed_transaction, *args, **kwargs)
def write_transaction(self, signed_transaction, durability='soft'):

View File

@ -358,7 +358,7 @@ def fulfill_simple_signature_fulfillment(fulfillment, parsed_fulfillment, fulfil
Args:
fulfillment (dict): BigchainDB fulfillment to fulfill.
parsed_fulfillment (object): cryptoconditions.Ed25519Fulfillment instance.
parsed_fulfillment (cryptoconditions.Ed25519Fulfillment): cryptoconditions.Ed25519Fulfillment instance.
fulfillment_message (dict): message to sign.
key_pairs (dict): dictionary of (public_key, private_key) pairs.
@ -380,16 +380,16 @@ def fulfill_simple_signature_fulfillment(fulfillment, parsed_fulfillment, fulfil
def fulfill_threshold_signature_fulfillment(fulfillment, parsed_fulfillment, fulfillment_message, key_pairs):
"""Fulfill a cryptoconditions.ThresholdSha256Fulfillment
Args:
fulfillment (dict): BigchainDB fulfillment to fulfill.
parsed_fulfillment (object): cryptoconditions.ThresholdSha256Fulfillment instance.
fulfillment_message (dict): message to sign.
key_pairs (dict): dictionary of (public_key, private_key) pairs.
Args:
fulfillment (dict): BigchainDB fulfillment to fulfill.
parsed_fulfillment (cryptoconditions.ThresholdSha256Fulfillment): cryptoconditions.ThresholdSha256Fulfillment instance.
fulfillment_message (dict): message to sign.
key_pairs (dict): dictionary of (public_key, private_key) pairs.
Returns:
object: fulfilled cryptoconditions.ThresholdSha256Fulfillment
Returns:
object: fulfilled cryptoconditions.ThresholdSha256Fulfillment
"""
"""
parsed_fulfillment_copy = copy.deepcopy(parsed_fulfillment)
parsed_fulfillment.subconditions = []
@ -421,11 +421,11 @@ def check_hash_and_signature(transaction):
raise exceptions.InvalidHash()
# Check signature
if not verify_signature(transaction):
if not validate_fulfillments(transaction):
raise exceptions.InvalidSignature()
def verify_signature(signed_transaction):
def validate_fulfillments(signed_transaction):
"""Verify the signature of a transaction
A valid transaction should have been signed `current_owner` corresponding private key.

View File

@ -75,8 +75,8 @@ def create_transaction():
tx = util.transform_create(tx)
tx = bigchain.consensus.sign_transaction(tx, private_key=bigchain.me_private)
if not bigchain.consensus.verify_signature(tx):
val['error'] = 'Invalid transaction signature'
if not bigchain.consensus.validate_fulfillments(tx):
val['error'] = 'Invalid transaction fulfillments'
with monitor.timer('write_transaction', rate=bigchaindb.config['statsd']['rate']):
val = bigchain.write_transaction(tx)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -30,7 +30,7 @@ validate_transaction(bigchain, transaction)
validate_block(bigchain, block)
create_transaction(*args, **kwargs)
sign_transaction(transaction, *args, **kwargs)
verify_signature(transaction)
validate_fulfillments(transaction)
```
Together, these functions are sufficient for most customizations. For example:

View File

@ -22,9 +22,9 @@ Table of Contents
python-driver-api-examples
local-rethinkdb-cluster
deploy-on-aws
json-serialization
cryptography
models
json-serialization
developer-interface
consensus
monitoring

View File

@ -12,7 +12,6 @@ First, make sure you have RethinkDB and BigchainDB _installed and running_, i.e.
```text
$ rethinkdb
$ bigchaindb configure
$ bigchaindb init
$ bigchaindb start
```
@ -44,20 +43,20 @@ In BigchainDB, only the federation nodes are allowed to create digital assets, b
```python
from bigchaindb import crypto
# create a test user
# Create a test user
testuser1_priv, testuser1_pub = crypto.generate_key_pair()
# define a digital asset data payload
# Define a digital asset data payload
digital_asset_payload = {'msg': 'Hello BigchainDB!'}
# a create transaction uses the operation `CREATE` and has no inputs
# A create transaction uses the operation `CREATE` and has no inputs
tx = b.create_transaction(b.me, testuser1_pub, None, 'CREATE', payload=digital_asset_payload)
# all transactions need to be signed by the user creating the transaction
# All transactions need to be signed by the user creating the transaction
tx_signed = b.sign_transaction(tx, b.me_private)
# write the transaction to the bigchain
# the transaction will be stored in a backlog where it will be validated,
# Write the transaction to the bigchain.
# The transaction will be stored in a backlog where it will be validated,
# included in a block, and written to the bigchain
b.write_transaction(tx_signed)
```
@ -66,7 +65,7 @@ b.write_transaction(tx_signed)
After a couple of seconds, we can check if the transactions was included in the bigchain:
```python
# retrieve a transaction from the bigchain
# Retrieve a transaction from the bigchain
tx_retrieved = b.get_transaction(tx_signed['id'])
tx_retrieved
```
@ -119,16 +118,16 @@ tx_retrieved
The new owner of the digital asset is now `BwuhqQX8FPsmqYiRV2CSZYWWsSWgSSQQFHjqxKEuqkPs`, which is the public key of `testuser1`.
Note that the current owner with public key `3LQ5dTiddXymDhNzETB1rEkp4mA7fEV1Qeiu5ghHiJm9` refers to one of the federation nodes that actually created the asset and assigned it to `testuser1`.
Note that the current owner (with public key `3LQ5dTiddXymDhNzETB1rEkp4mA7fEV1Qeiu5ghHiJm9`) is the federation node which created the asset and assigned it to `testuser1`.
## Transfer the Digital Asset
Now that `testuser1` has a digital asset assigned to him, he can transfer it to another user. Transfer transactions require an input. The input will be the transaction id of a digital asset that was assigned to `testuser1`, which in our case is `cdb6331f26ecec0ee7e67e4d5dcd63734e7f75bbd1ebe40699fc6d2960ae4cb2`.
Now that `testuser1` has a digital asset assigned to him, he can transfer it to another user. Transfer transactions require an input. The input will be the transaction id of a digital asset that was assigned to `testuser1`, which in our case is `933cd83a419d2735822a2154c84176a2f419cbd449a74b94e592ab807af23861`.
BigchainDB makes use of the crypto-conditions library to both cryptographically lock and unlock transactions.
The locking script is refered to as a `condition` and a corresponding `fulfillment` unlocks the condition of the `input_tx`.
Since a transaction can have multiple outputs with each their own (crypto)condition, each transaction input should also refer to the condition index `cid`.
Since a transaction can have multiple outputs with each its own (crypto)condition, each transaction input should also refer to the condition index `cid`.
![BigchainDB transactions connecting fulfillments with conditions](./_static/tx_single_condition_single_fulfillment_v1.png)
@ -230,14 +229,16 @@ DoubleSpend: input `{'cid': 0, 'txid': '933cd83a419d2735822a2154c84176a2f419cbd4
## Multiple Owners
When creating a transaction to a group of people with shared ownership of the asset, one can simply provide a list of `new_owners`:
To create a new digital asset with _multiple_ owners, one can simply provide a list of `new_owners`:
```python
# Create a new asset and assign it to multiple owners
tx_multisig = b.create_transaction(b.me, [testuser1_pub, testuser2_pub], None, 'CREATE')
# Have the federation sign the transaction
# Have the federation node sign the transaction
tx_multisig_signed = b.sign_transaction(tx_multisig, b.me_private)
# Write the transaction
b.write_transaction(tx_multisig_signed)
# Check if the transaction is already in the bigchain
@ -320,7 +321,7 @@ tx_multisig_transfer = b.create_transaction([testuser1_pub, testuser2_pub], test
# Sign with both private keys
tx_multisig_transfer_signed = b.sign_transaction(tx_multisig_transfer, [testuser1_priv, testuser2_priv])
# Write to bigchain
# Write the transaction
b.write_transaction(tx_multisig_transfer_signed)
# Check if the transaction is already in the bigchain
@ -330,7 +331,6 @@ tx_multisig_transfer_retrieved
```python
{
"assignee":"3LQ5dTiddXymDhNzETB1rEkp4mA7fEV1Qeiu5ghHiJm9",
"id":"e689e23f774e7c562eeb310c7c712b34fb6210bea5deb9175e48b68810029150",
"transaction":{
"conditions":[
@ -394,7 +394,7 @@ owned_mimo_inputs = b.get_owned_ids(testuser1_pub)
# Check the number of assets
print(len(owned_mimo_inputs))
# Create a TRANSFER transaction with all the assets
# Create a signed TRANSFER transaction with all the assets
tx_mimo = b.create_transaction(testuser1_pub, testuser2_pub, owned_mimo_inputs, 'TRANSFER')
tx_mimo_signed = b.sign_transaction(tx_mimo, testuser1_priv)
@ -694,7 +694,7 @@ threshold_tx_transfer['transaction']['fulfillments'][0]['fulfillment'] = thresho
# Optional validation checks
assert threshold_fulfillment.validate(threshold_tx_fulfillment_message) == True
assert b.verify_signature(threshold_tx_transfer) == True
assert b.validate_fulfillments(threshold_tx_transfer) == True
assert b.validate_transaction(threshold_tx_transfer)
b.write_transaction(threshold_tx_transfer)
@ -703,7 +703,6 @@ threshold_tx_transfer
```python
{
"assignee":"3LQ5dTiddXymDhNzETB1rEkp4mA7fEV1Qeiu5ghHiJm9",
"id":"a45b2340c59df7422a5788b3c462dee708a18cdf09d1a10bd26be3f31af4b8d7",
"transaction":{
"conditions":[
@ -750,9 +749,13 @@ threshold_tx_transfer
### Hash-locked Conditions
By creating a hash of a difficult-to-guess 256-bit random or pseudo-random integer it is possible to create a condition which the creator can trivially fulfill by publishing the random value. However, for anyone else, the condition is cryptographically hard to fulfill, because they would have to find a preimage for the given condition hash.
A hash-lock condition on an asset is like a password condition: anyone with the secret preimage (like a password) can fulfill the hash-lock condition and transfer the asset to themselves.
One possible usecase might be to redeem a digital voucher when given a secret (voucher code).
Under the hood, fulfilling a hash-lock condition amounts to finding a string (a "preimage") which, when hashed, results in a given value. It's easy to verify that a given preimage hashes to the given value, but it's computationally difficult to _find_ a string which hashes to the given value. The only practical way to get a valid preimage is to get it from the original creator (possibly via intermediaries).
One possible use case is to distribute preimages as "digital vouchers." The first person to redeem a voucher will get the associated asset.
A federation node can create an asset with a hash-lock condition and no `new_owners`. Anyone who can fullfill the hash-lock condition can transfer the asset to themselves.
```python
# Create a hash-locked asset without any new_owners
@ -771,7 +774,7 @@ hashlock_tx['transaction']['conditions'].append({
'new_owners': None
})
# Conditions have been updated, so hash needs updating
# Conditions have been updated, so the hash needs updating
hashlock_tx['id'] = util.get_hash_data(hashlock_tx)
# The asset needs to be signed by the current_owner
@ -787,7 +790,6 @@ hashlock_tx_signed
```python
{
"assignee":"FmLm6MxCABc8TsiZKdeYaZKo5yZWMM6Vty7Q1B6EgcP2",
"id":"604c520244b7ff63604527baf269e0cbfb887122f503703120fd347d6b99a237",
"transaction":{
"conditions":[
@ -817,22 +819,22 @@ hashlock_tx_signed
}
```
In order to redeem the asset, one needs to create a fulfillment the correct secret as a preimage:
In order to redeem the asset, one needs to create a fulfillment with the correct secret:
```python
hashlockuser_priv, hashlockuser_pub = crypto.generate_key_pair()
# create hashlock fulfillment tx
# Create hashlock fulfillment tx
hashlock_fulfill_tx = b.create_transaction(None, hashlockuser_pub, {'txid': hashlock_tx['id'], 'cid': 0}, 'TRANSFER')
# provide a wrong secret
# Provide a wrong secret
hashlock_fulfill_tx_fulfillment = cc.PreimageSha256Fulfillment(preimage=b'')
hashlock_fulfill_tx['transaction']['fulfillments'][0]['fulfillment'] = \
hashlock_fulfill_tx_fulfillment.serialize_uri()
assert b.is_valid_transaction(hashlock_fulfill_tx) == False
# provide the right secret
# Provide the right secret
hashlock_fulfill_tx_fulfillment = cc.PreimageSha256Fulfillment(preimage=secret)
hashlock_fulfill_tx['transaction']['fulfillments'][0]['fulfillment'] = \
hashlock_fulfill_tx_fulfillment.serialize_uri()
@ -846,7 +848,6 @@ hashlock_fulfill_tx
```python
{
"assignee":"FmLm6MxCABc8TsiZKdeYaZKo5yZWMM6Vty7Q1B6EgcP2",
"id":"fe6871bf3ca62eb61c52c5555cec2e07af51df817723f0cb76e5cf6248f449d2",
"transaction":{
"conditions":[

View File

@ -35,6 +35,10 @@ docs_require = [
'sphinx-rtd-theme>=0.1.9',
]
benchmarks_require = [
'line-profiler==1.0',
]
setup(
name='BigchainDB',
version=version['__version__'],
@ -88,7 +92,7 @@ setup(
tests_require=tests_require,
extras_require={
'test': tests_require,
'dev': dev_require + tests_require + docs_require,
'dev': dev_require + tests_require + docs_require + benchmarks_require,
'docs': docs_require,
},
)

3
speed-tests/README.md Normal file
View File

@ -0,0 +1,3 @@
# Speed Tests
This folder contains tests related to the code performance of a single node.

View File

@ -0,0 +1,25 @@
from line_profiler import LineProfiler
import bigchaindb
def speedtest_validate_transaction():
# create a transaction
b = bigchaindb.Bigchain()
tx = b.create_transaction(b.me, b.me, None, 'CREATE')
tx_signed = b.sign_transaction(tx, b.me_private)
# setup the profiler
profiler = LineProfiler()
profiler.enable_by_count()
profiler.add_function(bigchaindb.Bigchain.validate_transaction)
# validate_transaction 1000 times
for i in range(1000):
b.validate_transaction(tx_signed)
profiler.print_stats()
if __name__ == '__main__':
speedtest_validate_transaction()

View File

@ -37,7 +37,7 @@ class TestBigchainApi(object):
@pytest.mark.usefixtures('inputs')
def test_create_transaction_transfer(self, b, user_vk, user_sk):
input_tx = b.get_owned_ids(user_vk).pop()
assert b.verify_signature(b.get_transaction(input_tx['txid'])) == True
assert b.validate_fulfillments(b.get_transaction(input_tx['txid'])) == True
tx = b.create_transaction(user_vk, b.me, input_tx, 'TRANSFER')
@ -46,8 +46,8 @@ class TestBigchainApi(object):
tx_signed = b.sign_transaction(tx, user_sk)
assert b.verify_signature(tx) == False
assert b.verify_signature(tx_signed) == True
assert b.validate_fulfillments(tx) == False
assert b.validate_fulfillments(tx_signed) == True
def test_transaction_hash(self, b, user_vk):
payload = {'cats': 'are awesome'}
@ -73,7 +73,7 @@ class TestBigchainApi(object):
tx_signed = b.sign_transaction(tx, user_sk)
assert tx_signed['transaction']['fulfillments'][0]['fulfillment'] is not None
assert b.verify_signature(tx_signed)
assert b.validate_fulfillments(tx_signed)
def test_serializer(self, b, user_vk):
tx = b.create_transaction(user_vk, user_vk, None, 'CREATE')
@ -714,8 +714,8 @@ class TestBigchainBlock(object):
# run bootstrap
initial_results = block.bootstrap()
# we should have gotten a queue with 100 results
assert initial_results.qsize() - 1 == 100
# we should have gotten a queue with 100 results minus the poison pills
assert initial_results.qsize() - mp.cpu_count() == 100
def test_start(self, b, user_vk):
# start with 100 transactions in the backlog and 100 in the changefeed
@ -736,7 +736,9 @@ class TestBigchainBlock(object):
tx = b.sign_transaction(tx, b.me_private)
b.write_transaction(tx)
new_transactions.put(tx)
new_transactions.put('stop')
for i in range(mp.cpu_count()):
new_transactions.put('stop')
# create a block instance
block = Block(new_transactions)
@ -744,6 +746,8 @@ class TestBigchainBlock(object):
# start the block processes
block.start()
time.sleep(6)
assert new_transactions.qsize() == 0
assert r.table('backlog').count() == 0
assert r.table('bigchain').count() == 2
@ -755,20 +759,14 @@ class TestBigchainBlock(object):
# create block instance
block = Block(new_transactions)
# create block_process
p_block = mp.Process(target=block.start)
# start block process
p_block.start()
block.start()
# wait for 6 seconds to give it time for an empty queue exception to occur
time.sleep(6)
# send the poison pill
new_transactions.put('stop')
# join the process
p_block.join()
block.kill()
def test_duplicated_transactions(self):
pytest.skip('We may have duplicates in the initial_results and changefeed')
@ -1218,7 +1216,7 @@ class TestCryptoconditions(object):
assert fulfillment['current_owners'][0] == b.me
assert fulfillment_from_uri.public_key.to_ascii().decode() == b.me
assert b.verify_signature(tx_signed) == True
assert b.validate_fulfillments(tx_signed) == True
assert b.is_valid_transaction(tx_signed) == tx_signed
@pytest.mark.usefixtures('inputs')
@ -1250,7 +1248,7 @@ class TestCryptoconditions(object):
assert fulfillment['current_owners'][0] == user_vk
assert fulfillment_from_uri.public_key.to_ascii().decode() == user_vk
assert fulfillment_from_uri.condition.serialize_uri() == prev_condition['uri']
assert b.verify_signature(tx_signed) == True
assert b.validate_fulfillments(tx_signed) == True
assert b.is_valid_transaction(tx_signed) == tx_signed
def test_override_condition_create(self, b, user_vk):
@ -1268,7 +1266,7 @@ class TestCryptoconditions(object):
assert fulfillment['current_owners'][0] == b.me
assert fulfillment_from_uri.public_key.to_ascii().decode() == b.me
assert b.verify_signature(tx_signed) == True
assert b.validate_fulfillments(tx_signed) == True
assert b.is_valid_transaction(tx_signed) == tx_signed
@pytest.mark.usefixtures('inputs')
@ -1290,7 +1288,7 @@ class TestCryptoconditions(object):
assert fulfillment['current_owners'][0] == user_vk
assert fulfillment_from_uri.public_key.to_ascii().decode() == user_vk
assert b.verify_signature(tx_signed) == True
assert b.validate_fulfillments(tx_signed) == True
assert b.is_valid_transaction(tx_signed) == tx_signed
def test_override_fulfillment_create(self, b, user_vk):
@ -1302,7 +1300,7 @@ class TestCryptoconditions(object):
tx['transaction']['fulfillments'][0]['fulfillment'] = fulfillment.serialize_uri()
assert b.verify_signature(tx) == True
assert b.validate_fulfillments(tx) == True
assert b.is_valid_transaction(tx) == tx
@pytest.mark.usefixtures('inputs')
@ -1319,7 +1317,7 @@ class TestCryptoconditions(object):
tx['transaction']['fulfillments'][0]['fulfillment'] = fulfillment.serialize_uri()
assert b.verify_signature(tx) == True
assert b.validate_fulfillments(tx) == True
assert b.is_valid_transaction(tx) == tx
@pytest.mark.usefixtures('inputs')
@ -1573,7 +1571,7 @@ class TestCryptoconditions(object):
assert tx_transfer_signed['transaction']['fulfillments'][0]['fulfillment'] \
== expected_fulfillment.serialize_uri()
assert b.verify_signature(tx_transfer_signed) is True
assert b.validate_fulfillments(tx_transfer_signed) is True
def test_create_asset_with_hashlock_condition(self, b):
hashlock_tx = b.create_transaction(b.me, None, None, 'CREATE')

View File

@ -233,7 +233,7 @@ assert threshold_fulfillment.validate(threshold_tx_fulfillment_message) == True
threshold_tx_transfer['transaction']['fulfillments'][0]['fulfillment'] = threshold_fulfillment.serialize_uri()
assert b.verify_signature(threshold_tx_transfer) == True
assert b.validate_fulfillments(threshold_tx_transfer) == True
assert b.validate_transaction(threshold_tx_transfer) == threshold_tx_transfer

View File

@ -51,7 +51,7 @@ def test_client_can_create_assets(mock_requests_post, client):
assert tx['transaction']['conditions'][0]['new_owners'][0] == client.public_key
assert tx['transaction']['fulfillments'][0]['input'] is None
assert util.verify_signature(tx)
assert util.validate_fulfillments(tx)
def test_client_can_transfer_assets(mock_requests_post, mock_bigchaindb_sign, client):

View File

@ -34,7 +34,7 @@ def test_transform_create(b, user_sk, user_vk):
assert tx['transaction']['fulfillments'][0]['current_owners'][0] == b.me
assert tx['transaction']['conditions'][0]['new_owners'][0] == user_vk
assert util.verify_signature(tx)
assert util.validate_fulfillments(tx)
def test_empty_pool_is_populated_with_instances(mock_queue):

View File

@ -58,12 +58,15 @@ def test_load_consensus_plugin_raises_with_invalid_subclass(monkeypatch):
# Monkeypatch entry_point.load to return something other than a
# ConsensusRules instance
from bigchaindb import config_utils
import time
monkeypatch.setattr(config_utils,
'iter_entry_points',
lambda *args: [type('entry_point', (object), {'load': lambda: object})])
with pytest.raises(TypeError):
config_utils.load_consensus_plugin()
# Since the function is decorated with `lru_cache`, we need to
# "miss" the cache using a name that has not been used previously
config_utils.load_consensus_plugin(str(time.time()))
def test_map_leafs_iterator():