Skip to content

Commit

Permalink
Add unit transaction_mode_types (#2648)
Browse files Browse the repository at this point in the history
Signed-off-by: Mike Klimontov <klimontovm@gmail.com>
  • Loading branch information
fcennecf authored and ttmc committed Jun 12, 2019
1 parent a545216 commit c801c83
Show file tree
Hide file tree
Showing 16 changed files with 113 additions and 68 deletions.
36 changes: 18 additions & 18 deletions bigchaindb/backend/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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
Expand All @@ -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('.')
Expand Down Expand Up @@ -117,7 +117,7 @@ def __init__(self, host=None, port=None, dbname=None,
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)
Expand Down
26 changes: 13 additions & 13 deletions bigchaindb/backend/localmongodb/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@

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__)

Expand All @@ -33,15 +33,15 @@ def __init__(self, replicaset=None, ssl=None, login=None, password=None,
"""

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):
Expand Down
14 changes: 13 additions & 1 deletion bigchaindb/backend/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -21,6 +23,16 @@ def wrapper(func):
('`{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]
6 changes: 3 additions & 3 deletions bigchaindb/commands/bigchaindb.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions bigchaindb/common/transaction_mode_types.py
Original file line number Diff line number Diff line change
@@ -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'
10 changes: 7 additions & 3 deletions bigchaindb/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import logging
from collections import namedtuple
from uuid import uuid4

import rapidjson

try:
Expand All @@ -25,6 +26,9 @@
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
Expand Down Expand Up @@ -56,9 +60,9 @@ def __init__(self, connection=None):
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']
Expand Down
15 changes: 9 additions & 6 deletions bigchaindb/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -46,10 +49,10 @@ def from_dict(cls, tx_body):
@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:
Expand Down
9 changes: 6 additions & 3 deletions bigchaindb/web/views/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
10 changes: 7 additions & 3 deletions bigchaindb/web/views/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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"')
3 changes: 2 additions & 1 deletion bigchaindb/web/views/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
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
Expand Down Expand Up @@ -62,7 +63,7 @@ def post(self):
"""
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'])

Expand Down
3 changes: 2 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

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,
Expand Down Expand Up @@ -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

Expand Down
8 changes: 5 additions & 3 deletions tests/tendermint/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

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

Expand Down Expand Up @@ -120,15 +122,15 @@ 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(),
[([bob.public_key], 1)],
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()
Expand All @@ -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'
Expand Down
14 changes: 9 additions & 5 deletions tests/tendermint/test_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
from unittest.mock import patch


try:
from hashlib import sha3_256
except ImportError:
Expand All @@ -15,6 +16,9 @@
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


Expand Down Expand Up @@ -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
Expand Down

0 comments on commit c801c83

Please sign in to comment.