Add unit transaction_mode_types (#2648)

Signed-off-by: Mike Klimontov <klimontovm@gmail.com>
This commit is contained in:
Mike Klimontov 2019-06-12 17:28:24 +03:00 committed by Troy McConaghy
parent a5452169b9
commit c801c833fc
16 changed files with 113 additions and 68 deletions

View File

@ -2,14 +2,14 @@
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
# Code is Apache-2.0 and docs are CC-BY-4.0
from itertools import repeat
from importlib import import_module
import logging
from importlib import import_module
from itertools import repeat
import bigchaindb
from bigchaindb.common.exceptions import ConfigurationError
from bigchaindb.backend.exceptions import ConnectionError
from bigchaindb.backend.utils import get_bigchaindb_config_value, get_bigchaindb_config_value_or_key_error
from bigchaindb.common.exceptions import ConfigurationError
BACKENDS = {
'localmongodb': 'bigchaindb.backend.localmongodb.connection.LocalMongoDBConnection',
@ -47,10 +47,10 @@ def connect(backend=None, host=None, port=None, name=None, max_tries=None,
Authentication failure after connecting to the database.
"""
backend = backend or bigchaindb.config['database']['backend']
host = host or bigchaindb.config['database']['host']
port = port or bigchaindb.config['database']['port']
dbname = name or bigchaindb.config['database']['name']
backend = backend or get_bigchaindb_config_value_or_key_error('backend')
host = host or get_bigchaindb_config_value_or_key_error('host')
port = port or get_bigchaindb_config_value_or_key_error('port')
dbname = name or get_bigchaindb_config_value_or_key_error('name')
# Not sure how to handle this here. This setting is only relevant for
# mongodb.
# I added **kwargs for both RethinkDBConnection and MongoDBConnection
@ -60,15 +60,15 @@ def connect(backend=None, host=None, port=None, name=None, max_tries=None,
# UPD: RethinkDBConnection is not here anymore cause we no longer support RethinkDB.
# The problem described above might be reconsidered next time we introduce a backend,
# if it ever happens.
replicaset = replicaset or bigchaindb.config['database'].get('replicaset')
ssl = ssl if ssl is not None else bigchaindb.config['database'].get('ssl', False)
login = login or bigchaindb.config['database'].get('login')
password = password or bigchaindb.config['database'].get('password')
ca_cert = ca_cert or bigchaindb.config['database'].get('ca_cert', None)
certfile = certfile or bigchaindb.config['database'].get('certfile', None)
keyfile = keyfile or bigchaindb.config['database'].get('keyfile', None)
keyfile_passphrase = keyfile_passphrase or bigchaindb.config['database'].get('keyfile_passphrase', None)
crlfile = crlfile or bigchaindb.config['database'].get('crlfile', None)
replicaset = replicaset or get_bigchaindb_config_value('replicaset')
ssl = ssl if ssl is not None else get_bigchaindb_config_value('ssl', False)
login = login or get_bigchaindb_config_value('login')
password = password or get_bigchaindb_config_value('password')
ca_cert = ca_cert or get_bigchaindb_config_value('ca_cert')
certfile = certfile or get_bigchaindb_config_value('certfile')
keyfile = keyfile or get_bigchaindb_config_value('keyfile')
keyfile_passphrase = keyfile_passphrase or get_bigchaindb_config_value('keyfile_passphrase', None)
crlfile = crlfile or get_bigchaindb_config_value('crlfile')
try:
module_name, _, class_name = BACKENDS[backend].rpartition('.')
@ -117,7 +117,7 @@ class Connection:
self.host = host or dbconf['host']
self.port = port or dbconf['port']
self.dbname = dbname or dbconf['name']
self.connection_timeout = connection_timeout if connection_timeout is not None\
self.connection_timeout = connection_timeout if connection_timeout is not None \
else dbconf['connection_timeout']
self.max_tries = max_tries if max_tries is not None else dbconf['max_tries']
self.max_tries_counter = range(self.max_tries) if self.max_tries != 0 else repeat(0)

View File

@ -7,13 +7,13 @@ from ssl import CERT_REQUIRED
import pymongo
import bigchaindb
from bigchaindb.utils import Lazy
from bigchaindb.common.exceptions import ConfigurationError
from bigchaindb.backend.connection import Connection
from bigchaindb.backend.exceptions import (DuplicateKeyError,
OperationError,
ConnectionError)
from bigchaindb.backend.connection import Connection
from bigchaindb.backend.utils import get_bigchaindb_config_value
from bigchaindb.common.exceptions import ConfigurationError
from bigchaindb.utils import Lazy
logger = logging.getLogger(__name__)
@ -33,15 +33,15 @@ class LocalMongoDBConnection(Connection):
"""
super().__init__(**kwargs)
self.replicaset = replicaset or bigchaindb.config['database'].get('replicaset')
self.ssl = ssl if ssl is not None else bigchaindb.config['database'].get('ssl', False)
self.login = login or bigchaindb.config['database'].get('login')
self.password = password or bigchaindb.config['database'].get('password')
self.ca_cert = ca_cert or bigchaindb.config['database'].get('ca_cert', None)
self.certfile = certfile or bigchaindb.config['database'].get('certfile', None)
self.keyfile = keyfile or bigchaindb.config['database'].get('keyfile', None)
self.keyfile_passphrase = keyfile_passphrase or bigchaindb.config['database'].get('keyfile_passphrase', None)
self.crlfile = crlfile or bigchaindb.config['database'].get('crlfile', None)
self.replicaset = replicaset or get_bigchaindb_config_value('replicaset')
self.ssl = ssl if ssl is not None else get_bigchaindb_config_value('ssl', False)
self.login = login or get_bigchaindb_config_value('login')
self.password = password or get_bigchaindb_config_value('password')
self.ca_cert = ca_cert or get_bigchaindb_config_value('ca_cert')
self.certfile = certfile or get_bigchaindb_config_value('certfile')
self.keyfile = keyfile or get_bigchaindb_config_value('keyfile')
self.keyfile_passphrase = keyfile_passphrase or get_bigchaindb_config_value('keyfile_passphrase')
self.crlfile = crlfile or get_bigchaindb_config_value('crlfile')
@property
def db(self):

View File

@ -2,6 +2,8 @@
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
# Code is Apache-2.0 and docs are CC-BY-4.0
import bigchaindb
class ModuleDispatchRegistrationError(Exception):
"""Raised when there is a problem registering dispatched functions for a
@ -21,6 +23,16 @@ def module_dispatch_registrar(module):
('`{module}` does not contain a single-dispatchable '
'function named `{func}`. The module being registered '
'was not implemented correctly!').format(
func=func_name, module=module.__name__)) from ex
func=func_name, module=module.__name__)) from ex
return wrapper
return dispatch_wrapper
def get_bigchaindb_config_value(key, default_value=None):
return bigchaindb.config['database'].get(key, default_value)
def get_bigchaindb_config_value_or_key_error(key):
return bigchaindb.config['database'][key]

View File

@ -16,6 +16,7 @@ import sys
from bigchaindb.core import rollback
from bigchaindb.migrations.chain_migration_election import ChainMigrationElection
from bigchaindb.utils import load_node_key
from bigchaindb.common.transaction_mode_types import BROADCAST_TX_COMMIT
from bigchaindb.common.exceptions import (DatabaseDoesNotExist,
ValidationError)
from bigchaindb.elections.vote import Vote
@ -131,7 +132,7 @@ def create_new_election(sk, bigchain, election_class, data):
logger.error(fd_404)
return False
resp = bigchain.write_transaction(election, 'broadcast_tx_commit')
resp = bigchain.write_transaction(election, BROADCAST_TX_COMMIT)
if resp == (202, ''):
logger.info('[SUCCESS] Submitted proposal with id: {}'.format(election.id))
return election.id
@ -206,7 +207,7 @@ def run_election_approve(args, bigchain):
tx.id).sign([key.private_key])
approval.validate(bigchain)
resp = bigchain.write_transaction(approval, 'broadcast_tx_commit')
resp = bigchain.write_transaction(approval, BROADCAST_TX_COMMIT)
if resp == (202, ''):
logger.info('[SUCCESS] Your vote has been submitted')
@ -261,7 +262,6 @@ def run_drop(args):
return
conn = backend.connect()
dbname = bigchaindb.config['database']['name']
try:
schema.drop_database(conn, dbname)
except DatabaseDoesNotExist:

View File

@ -0,0 +1,7 @@
# Copyright BigchainDB GmbH and BigchainDB contributors
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
# Code is Apache-2.0 and docs are CC-BY-4.0
BROADCAST_TX_COMMIT = 'broadcast_tx_commit'
BROADCAST_TX_ASYNC = 'broadcast_tx_async'
BROADCAST_TX_SYNC = 'broadcast_tx_sync'

View File

@ -9,6 +9,7 @@ MongoDB.
import logging
from collections import namedtuple
from uuid import uuid4
import rapidjson
try:
@ -25,6 +26,9 @@ from bigchaindb.models import Transaction
from bigchaindb.common.exceptions import (SchemaValidationError,
ValidationError,
DoubleSpend)
from bigchaindb.common.transaction_mode_types import (BROADCAST_TX_COMMIT,
BROADCAST_TX_ASYNC,
BROADCAST_TX_SYNC)
from bigchaindb.tendermint_utils import encode_transaction, merkleroot
from bigchaindb import exceptions as core_exceptions
from bigchaindb.validation import BaseValidationRules
@ -56,9 +60,9 @@ class BigchainDB(object):
A connection to the database.
"""
config_utils.autoconfigure()
self.mode_commit = 'broadcast_tx_commit'
self.mode_list = ('broadcast_tx_async',
'broadcast_tx_sync',
self.mode_commit = BROADCAST_TX_COMMIT
self.mode_list = (BROADCAST_TX_ASYNC,
BROADCAST_TX_SYNC,
self.mode_commit)
self.tendermint_host = bigchaindb.config['tendermint']['host']
self.tendermint_port = bigchaindb.config['tendermint']['port']

View File

@ -2,15 +2,18 @@
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
# Code is Apache-2.0 and docs are CC-BY-4.0
from bigchaindb.backend.schema import validate_language_key
from bigchaindb.common.exceptions import (InvalidSignature,
DuplicateTransaction)
from bigchaindb.common.schema import validate_transaction_schema
from bigchaindb.common.transaction import Transaction
from bigchaindb.common.utils import (validate_txn_obj, validate_key)
from bigchaindb.common.schema import validate_transaction_schema
from bigchaindb.backend.schema import validate_language_key
class Transaction(Transaction):
ASSET = 'asset'
METADATA = 'metadata'
DATA = 'data'
def validate(self, bigchain, current_transactions=[]):
"""Validate transaction spend
@ -46,10 +49,10 @@ class Transaction(Transaction):
@classmethod
def validate_schema(cls, tx_body):
validate_transaction_schema(tx_body)
validate_txn_obj('asset', tx_body['asset'], 'data', validate_key)
validate_txn_obj('metadata', tx_body, 'metadata', validate_key)
validate_language_key(tx_body['asset'], 'data')
validate_language_key(tx_body, 'metadata')
validate_txn_obj(cls.ASSET, tx_body[cls.ASSET], cls.DATA, validate_key)
validate_txn_obj(cls.METADATA, tx_body, cls.METADATA, validate_key)
validate_language_key(tx_body[cls.ASSET], cls.DATA)
validate_language_key(tx_body, cls.METADATA)
class FastTransaction:

View File

@ -36,7 +36,10 @@ def base_ws_uri():
customized (typically when running behind NAT, firewall, etc.)
"""
scheme = config['wsserver']['advertised_scheme']
host = config['wsserver']['advertised_host']
port = config['wsserver']['advertised_port']
config_wsserver = config['wsserver']
scheme = config_wsserver['advertised_scheme']
host = config_wsserver['advertised_host']
port = config_wsserver['advertised_port']
return '{}://{}:{}'.format(scheme, host, port)

View File

@ -4,6 +4,10 @@
import re
from bigchaindb.common.transaction_mode_types import (BROADCAST_TX_COMMIT,
BROADCAST_TX_ASYNC,
BROADCAST_TX_SYNC)
def valid_txid(txid):
if re.match('^[a-fA-F0-9]{64}$', txid):
@ -38,9 +42,9 @@ def valid_operation(op):
def valid_mode(mode):
if mode == 'async':
return 'broadcast_tx_async'
return BROADCAST_TX_ASYNC
if mode == 'sync':
return 'broadcast_tx_sync'
return BROADCAST_TX_SYNC
if mode == 'commit':
return 'broadcast_tx_commit'
return BROADCAST_TX_COMMIT
raise ValueError('Mode must be "async", "sync" or "commit"')

View File

@ -11,6 +11,7 @@ import logging
from flask import current_app, request, jsonify
from flask_restful import Resource, reqparse
from bigchaindb.common.transaction_mode_types import BROADCAST_TX_ASYNC
from bigchaindb.common.exceptions import SchemaValidationError, ValidationError
from bigchaindb.web.views.base import make_error
from bigchaindb.web.views import parameters
@ -62,7 +63,7 @@ class TransactionListApi(Resource):
"""
parser = reqparse.RequestParser()
parser.add_argument('mode', type=parameters.valid_mode,
default='broadcast_tx_async')
default=BROADCAST_TX_ASYNC)
args = parser.parse_args()
mode = str(args['mode'])

View File

@ -22,6 +22,7 @@ from pymongo import MongoClient
from bigchaindb import ValidatorElection
from bigchaindb.common import crypto
from bigchaindb.common.transaction_mode_types import BROADCAST_TX_COMMIT
from bigchaindb.tendermint_utils import key_from_base64
from bigchaindb.backend import schema, query
from bigchaindb.common.crypto import (key_pair_from_ed25519_key,
@ -272,7 +273,7 @@ def signed_create_tx(alice, create_tx):
@pytest.fixture
def posted_create_tx(b, signed_create_tx):
res = b.post_transaction(signed_create_tx, 'broadcast_tx_commit')
res = b.post_transaction(signed_create_tx, BROADCAST_TX_COMMIT)
assert res.status_code == 200
return signed_create_tx

View File

@ -11,6 +11,8 @@ import pytest
from abci.server import ProtocolHandler
from abci.encoding import read_messages
from bigchaindb.common.transaction_mode_types import BROADCAST_TX_COMMIT, BROADCAST_TX_SYNC
from bigchaindb.version import __tm_supported_versions__
from io import BytesIO
@ -120,7 +122,7 @@ def test_post_transaction_responses(tendermint_ws_url, b):
asset=None)\
.sign([alice.private_key])
code, message = b.write_transaction(tx, 'broadcast_tx_commit')
code, message = b.write_transaction(tx, BROADCAST_TX_COMMIT)
assert code == 202
tx_transfer = Transaction.transfer(tx.to_inputs(),
@ -128,7 +130,7 @@ def test_post_transaction_responses(tendermint_ws_url, b):
asset_id=tx.id)\
.sign([alice.private_key])
code, message = b.write_transaction(tx_transfer, 'broadcast_tx_commit')
code, message = b.write_transaction(tx_transfer, BROADCAST_TX_COMMIT)
assert code == 202
carly = generate_key_pair()
@ -137,7 +139,7 @@ def test_post_transaction_responses(tendermint_ws_url, b):
[([carly.public_key], 1)],
asset_id=tx.id,
).sign([alice.private_key])
for mode in ('broadcast_tx_sync', 'broadcast_tx_commit'):
for mode in (BROADCAST_TX_SYNC, BROADCAST_TX_COMMIT):
code, message = b.write_transaction(double_spend, mode)
assert code == 500
assert message == 'Transaction validation failed'

View File

@ -5,6 +5,7 @@
import os
from unittest.mock import patch
try:
from hashlib import sha3_256
except ImportError:
@ -15,6 +16,9 @@ import pytest
from pymongo import MongoClient
from bigchaindb import backend
from bigchaindb.common.transaction_mode_types import (BROADCAST_TX_COMMIT,
BROADCAST_TX_ASYNC,
BROADCAST_TX_SYNC)
from bigchaindb.lib import Block
@ -103,20 +107,20 @@ def test_write_and_post_transaction(mock_post, b):
.sign([alice.private_key]).to_dict()
tx = b.validate_transaction(tx)
b.write_transaction(tx, 'broadcast_tx_async')
b.write_transaction(tx, BROADCAST_TX_ASYNC)
assert mock_post.called
args, kwargs = mock_post.call_args
assert 'broadcast_tx_async' == kwargs['json']['method']
assert BROADCAST_TX_ASYNC == kwargs['json']['method']
encoded_tx = [encode_transaction(tx.to_dict())]
assert encoded_tx == kwargs['json']['params']
@patch('requests.post')
@pytest.mark.parametrize('mode', [
'broadcast_tx_async',
'broadcast_tx_sync',
'broadcast_tx_commit'
BROADCAST_TX_SYNC,
BROADCAST_TX_ASYNC,
BROADCAST_TX_COMMIT
])
def test_post_transaction_valid_modes(mock_post, b, mode):
from bigchaindb.models import Transaction

View File

@ -11,6 +11,7 @@ from bigchaindb.upsert_validator import ValidatorElection
from bigchaindb.common.exceptions import AmountError
from bigchaindb.common.crypto import generate_key_pair
from bigchaindb.common.exceptions import ValidationError
from bigchaindb.common.transaction_mode_types import BROADCAST_TX_COMMIT
from bigchaindb.elections.vote import Vote
from tests.utils import generate_block, gen_vote
@ -241,13 +242,13 @@ def test_upsert_validator(b, node_key, node_keys, ed25519_node_keys):
election = ValidatorElection.generate([node_key.public_key],
voters,
new_validator, None).sign([node_key.private_key])
code, message = b.write_transaction(election, 'broadcast_tx_commit')
code, message = b.write_transaction(election, BROADCAST_TX_COMMIT)
assert code == 202
assert b.get_transaction(election.id)
tx_vote = gen_vote(election, 0, ed25519_node_keys)
assert tx_vote.validate(b)
code, message = b.write_transaction(tx_vote, 'broadcast_tx_commit')
code, message = b.write_transaction(tx_vote, BROADCAST_TX_COMMIT)
assert code == 202
resp = b.get_validators()

View File

@ -11,6 +11,7 @@ from functools import singledispatch
from bigchaindb.backend.localmongodb.connection import LocalMongoDBConnection
from bigchaindb.backend.schema import TABLES
from bigchaindb.common import crypto
from bigchaindb.common.transaction_mode_types import BROADCAST_TX_COMMIT
from bigchaindb.elections.election import Election, Vote
from bigchaindb.tendermint_utils import key_to_base64
@ -36,7 +37,7 @@ def generate_block(bigchain):
asset=None)\
.sign([alice.private_key])
code, message = bigchain.write_transaction(tx, 'broadcast_tx_commit')
code, message = bigchain.write_transaction(tx, BROADCAST_TX_COMMIT)
assert code == 202

View File

@ -11,7 +11,9 @@ from cryptoconditions import Ed25519Sha256
from sha3 import sha3_256
from bigchaindb.common import crypto
from bigchaindb.common.transaction_mode_types import (BROADCAST_TX_COMMIT,
BROADCAST_TX_ASYNC,
BROADCAST_TX_SYNC)
TX_ENDPOINT = '/api/v1/transactions/'
@ -404,10 +406,10 @@ def test_transactions_get_list_bad(client):
@patch('requests.post')
@pytest.mark.parametrize('mode', [
('', 'broadcast_tx_async'),
('?mode=async', 'broadcast_tx_async'),
('?mode=sync', 'broadcast_tx_sync'),
('?mode=commit', 'broadcast_tx_commit'),
('', BROADCAST_TX_ASYNC),
('?mode=async', BROADCAST_TX_ASYNC),
('?mode=sync', BROADCAST_TX_SYNC),
('?mode=commit', BROADCAST_TX_COMMIT),
])
def test_post_transaction_valid_modes(mock_post, client, mode):
from bigchaindb.models import Transaction