mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Merge branch 'tendermint' into 1995-mode-API
This commit is contained in:
commit
ff50d243bc
@ -9,6 +9,7 @@ import base58
|
|||||||
from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256
|
from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256
|
||||||
from cryptoconditions.exceptions import (
|
from cryptoconditions.exceptions import (
|
||||||
ParsingError, ASN1DecodeError, ASN1EncodeError, UnsupportedTypeError)
|
ParsingError, ASN1DecodeError, ASN1EncodeError, UnsupportedTypeError)
|
||||||
|
from sha3 import sha3_256
|
||||||
|
|
||||||
from bigchaindb.common.crypto import PrivateKey, hash_data
|
from bigchaindb.common.crypto import PrivateKey, hash_data
|
||||||
from bigchaindb.common.exceptions import (KeypairMismatchException,
|
from bigchaindb.common.exceptions import (KeypairMismatchException,
|
||||||
@ -812,13 +813,16 @@ class Transaction(object):
|
|||||||
# this should never happen, but then again, never say never.
|
# this should never happen, but then again, never say never.
|
||||||
input_ = deepcopy(input_)
|
input_ = deepcopy(input_)
|
||||||
public_key = input_.owners_before[0]
|
public_key = input_.owners_before[0]
|
||||||
|
message = sha3_256(message.encode())
|
||||||
|
if input_.fulfills:
|
||||||
|
message.update('{}{}'.format(
|
||||||
|
input_.fulfills.txid, input_.fulfills.output).encode())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# cryptoconditions makes no assumptions of the encoding of the
|
# cryptoconditions makes no assumptions of the encoding of the
|
||||||
# message to sign or verify. It only accepts bytestrings
|
# message to sign or verify. It only accepts bytestrings
|
||||||
input_.fulfillment.sign(
|
input_.fulfillment.sign(
|
||||||
message.encode(),
|
message.digest(), base58.b58decode(key_pairs[public_key].encode()))
|
||||||
base58.b58decode(key_pairs[public_key].encode()),
|
|
||||||
)
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise KeypairMismatchException('Public key {} is not a pair to '
|
raise KeypairMismatchException('Public key {} is not a pair to '
|
||||||
'any of the private keys'
|
'any of the private keys'
|
||||||
@ -836,6 +840,11 @@ class Transaction(object):
|
|||||||
key_pairs (dict): The keys to sign the Transaction with.
|
key_pairs (dict): The keys to sign the Transaction with.
|
||||||
"""
|
"""
|
||||||
input_ = deepcopy(input_)
|
input_ = deepcopy(input_)
|
||||||
|
message = sha3_256(message.encode())
|
||||||
|
if input_.fulfills:
|
||||||
|
message.update('{}{}'.format(
|
||||||
|
input_.fulfills.txid, input_.fulfills.output).encode())
|
||||||
|
|
||||||
for owner_before in set(input_.owners_before):
|
for owner_before in set(input_.owners_before):
|
||||||
# TODO: CC should throw a KeypairMismatchException, instead of
|
# TODO: CC should throw a KeypairMismatchException, instead of
|
||||||
# our manual mapping here
|
# our manual mapping here
|
||||||
@ -863,7 +872,8 @@ class Transaction(object):
|
|||||||
# cryptoconditions makes no assumptions of the encoding of the
|
# cryptoconditions makes no assumptions of the encoding of the
|
||||||
# message to sign or verify. It only accepts bytestrings
|
# message to sign or verify. It only accepts bytestrings
|
||||||
for subffill in subffills:
|
for subffill in subffills:
|
||||||
subffill.sign(message.encode(), base58.b58decode(private_key.encode()))
|
subffill.sign(
|
||||||
|
message.digest(), base58.b58decode(private_key.encode()))
|
||||||
return input_
|
return input_
|
||||||
|
|
||||||
def inputs_valid(self, outputs=None):
|
def inputs_valid(self, outputs=None):
|
||||||
@ -931,7 +941,7 @@ class Transaction(object):
|
|||||||
for i, cond in enumerate(output_condition_uris))
|
for i, cond in enumerate(output_condition_uris))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _input_valid(input_, operation, tx_serialized, output_condition_uri=None):
|
def _input_valid(input_, operation, message, output_condition_uri=None):
|
||||||
"""Validates a single Input against a single Output.
|
"""Validates a single Input against a single Output.
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
@ -942,8 +952,7 @@ class Transaction(object):
|
|||||||
input_ (:class:`~bigchaindb.common.transaction.
|
input_ (:class:`~bigchaindb.common.transaction.
|
||||||
Input`) The Input to be signed.
|
Input`) The Input to be signed.
|
||||||
operation (str): The type of Transaction.
|
operation (str): The type of Transaction.
|
||||||
tx_serialized (str): The Transaction used as a message when
|
message (str): The fulfillment message.
|
||||||
initially signing it.
|
|
||||||
output_condition_uri (str, optional): An Output to check the
|
output_condition_uri (str, optional): An Output to check the
|
||||||
Input against.
|
Input against.
|
||||||
|
|
||||||
@ -964,12 +973,17 @@ class Transaction(object):
|
|||||||
else:
|
else:
|
||||||
output_valid = output_condition_uri == ccffill.condition_uri
|
output_valid = output_condition_uri == ccffill.condition_uri
|
||||||
|
|
||||||
|
message = sha3_256(message.encode())
|
||||||
|
if input_.fulfills:
|
||||||
|
message.update('{}{}'.format(
|
||||||
|
input_.fulfills.txid, input_.fulfills.output).encode())
|
||||||
|
|
||||||
# NOTE: We pass a timestamp to `.validate`, as in case of a timeout
|
# NOTE: We pass a timestamp to `.validate`, as in case of a timeout
|
||||||
# condition we'll have to validate against it
|
# condition we'll have to validate against it
|
||||||
|
|
||||||
# cryptoconditions makes no assumptions of the encoding of the
|
# cryptoconditions makes no assumptions of the encoding of the
|
||||||
# message to sign or verify. It only accepts bytestrings
|
# message to sign or verify. It only accepts bytestrings
|
||||||
ffill_valid = parsed_ffill.validate(message=tx_serialized.encode())
|
ffill_valid = parsed_ffill.validate(message=message.digest())
|
||||||
return output_valid and ffill_valid
|
return output_valid and ffill_valid
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
from os import getenv
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
from bigchaindb.common.utils import gen_timestamp
|
from bigchaindb.common.utils import gen_timestamp
|
||||||
@ -10,8 +11,8 @@ from bigchaindb.events import EventTypes, Event
|
|||||||
from bigchaindb.tendermint.utils import decode_transaction_base64
|
from bigchaindb.tendermint.utils import decode_transaction_base64
|
||||||
|
|
||||||
|
|
||||||
HOST = 'localhost'
|
HOST = getenv('TENDERMINT_HOST', 'localhost')
|
||||||
PORT = 46657
|
PORT = int(getenv('TENDERMINT_PORT', 46657))
|
||||||
URL = f'ws://{HOST}:{PORT}/websocket'
|
URL = f'ws://{HOST}:{PORT}/websocket'
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -31,7 +31,7 @@ services:
|
|||||||
- "9984"
|
- "9984"
|
||||||
command: bigchaindb -l DEBUG start
|
command: bigchaindb -l DEBUG start
|
||||||
tendermint:
|
tendermint:
|
||||||
image: tendermint/tendermint
|
image: tendermint/tendermint:0.13
|
||||||
volumes:
|
volumes:
|
||||||
- ./tmdata:/tendermint
|
- ./tmdata:/tendermint
|
||||||
entrypoint: ''
|
entrypoint: ''
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM mongo:3.4.4
|
FROM mongo:3.4.10
|
||||||
LABEL maintainer "dev@bigchaindb.com"
|
LABEL maintainer "dev@bigchaindb.com"
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
docker build -t bigchaindb/mongodb:3.2 .
|
docker build -t bigchaindb/mongodb:3.3 .
|
||||||
|
|
||||||
docker push bigchaindb/mongodb:3.2
|
docker push bigchaindb/mongodb:3.3
|
||||||
|
@ -65,9 +65,11 @@ if [[ -z "${REPLICA_SET_NAME:?REPLICA_SET_NAME not specified. Exiting!}" || \
|
|||||||
-z "${MONGODB_IP:?MONGODB_IP not specified. Exiting!}" || \
|
-z "${MONGODB_IP:?MONGODB_IP not specified. Exiting!}" || \
|
||||||
-z "${MONGODB_KEY_FILE_PATH:?MONGODB_KEY_FILE_PATH not specified. Exiting!}" || \
|
-z "${MONGODB_KEY_FILE_PATH:?MONGODB_KEY_FILE_PATH not specified. Exiting!}" || \
|
||||||
-z "${MONGODB_CA_FILE_PATH:?MONGODB_CA_FILE_PATH not specified. Exiting!}" || \
|
-z "${MONGODB_CA_FILE_PATH:?MONGODB_CA_FILE_PATH not specified. Exiting!}" || \
|
||||||
-z "${MONGODB_CRL_FILE_PATH:?MONGODB_CRL_FILE_PATH not specified. Exiting!}" || \
|
-z "${MONGODB_CRL_FILE_PATH:?MONGODB_CRL_FILE_PATH not specified. Exiting!}" ]] ; then
|
||||||
-z "${STORAGE_ENGINE_CACHE_SIZE:=''}" ]] ; then
|
# Not handling the STORAGE_ENGINE_CACHE_SIZE because
|
||||||
#-z "${MONGODB_KEY_FILE_PASSWORD:?MongoDB Key File Password not specified. Exiting!}" || \
|
# it is optional. If not specified the default cache
|
||||||
|
# size is: max((50% RAM - 1GB), 256MB)
|
||||||
|
echo "Missing required enviroment variable(s)."
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
echo REPLICA_SET_NAME="$REPLICA_SET_NAME"
|
echo REPLICA_SET_NAME="$REPLICA_SET_NAME"
|
||||||
|
2
setup.py
2
setup.py
@ -80,7 +80,7 @@ install_requires = [
|
|||||||
'multipipes~=0.1.0',
|
'multipipes~=0.1.0',
|
||||||
'jsonschema~=2.5.1',
|
'jsonschema~=2.5.1',
|
||||||
'pyyaml~=3.12',
|
'pyyaml~=3.12',
|
||||||
'aiohttp~=2.0',
|
'aiohttp~=2.3',
|
||||||
'python-rapidjson-schema==0.1.1',
|
'python-rapidjson-schema==0.1.1',
|
||||||
'statsd==3.2.1',
|
'statsd==3.2.1',
|
||||||
'abci~=0.3.0',
|
'abci~=0.3.0',
|
||||||
|
@ -479,7 +479,11 @@ def test_validate_tx_simple_create_signature(user_input, user_output, user_priv,
|
|||||||
|
|
||||||
tx = Transaction(Transaction.CREATE, asset_definition, [user_input], [user_output])
|
tx = Transaction(Transaction.CREATE, asset_definition, [user_input], [user_output])
|
||||||
expected = deepcopy(user_output)
|
expected = deepcopy(user_output)
|
||||||
message = str(tx).encode()
|
tx_dict = tx.to_dict()
|
||||||
|
tx_dict['inputs'][0]['fulfillment'] = None
|
||||||
|
serialized_tx = json.dumps(tx_dict, sort_keys=True,
|
||||||
|
separators=(',', ':'), ensure_ascii=True)
|
||||||
|
message = sha3_256(serialized_tx.encode()).digest()
|
||||||
expected.fulfillment.sign(message, b58decode(user_priv))
|
expected.fulfillment.sign(message, b58decode(user_priv))
|
||||||
tx.sign([user_priv])
|
tx.sign([user_priv])
|
||||||
|
|
||||||
@ -539,7 +543,11 @@ def test_validate_tx_threshold_create_signature(user_user2_threshold_input,
|
|||||||
tx = Transaction(Transaction.CREATE, asset_definition,
|
tx = Transaction(Transaction.CREATE, asset_definition,
|
||||||
[user_user2_threshold_input],
|
[user_user2_threshold_input],
|
||||||
[user_user2_threshold_output])
|
[user_user2_threshold_output])
|
||||||
message = str(tx).encode()
|
tx_dict = tx.to_dict()
|
||||||
|
tx_dict['inputs'][0]['fulfillment'] = None
|
||||||
|
serialized_tx = json.dumps(tx_dict, sort_keys=True,
|
||||||
|
separators=(',', ':'), ensure_ascii=True)
|
||||||
|
message = sha3_256(serialized_tx.encode()).digest()
|
||||||
expected = deepcopy(user_user2_threshold_output)
|
expected = deepcopy(user_user2_threshold_output)
|
||||||
expected.fulfillment.subconditions[0]['body'].sign(
|
expected.fulfillment.subconditions[0]['body'].sign(
|
||||||
message, b58decode(user_priv))
|
message, b58decode(user_priv))
|
||||||
@ -570,11 +578,18 @@ def test_validate_tx_threshold_duplicated_pk(user_pub, user_priv,
|
|||||||
|
|
||||||
tx = Transaction(Transaction.CREATE, asset_definition,
|
tx = Transaction(Transaction.CREATE, asset_definition,
|
||||||
[threshold_input], [threshold_output])
|
[threshold_input], [threshold_output])
|
||||||
|
|
||||||
|
tx_dict = tx.to_dict()
|
||||||
|
tx_dict['inputs'][0]['fulfillment'] = None
|
||||||
|
serialized_tx = json.dumps(tx_dict, sort_keys=True,
|
||||||
|
separators=(',', ':'), ensure_ascii=True)
|
||||||
|
message = sha3_256(serialized_tx.encode()).digest()
|
||||||
|
|
||||||
expected = deepcopy(threshold_input)
|
expected = deepcopy(threshold_input)
|
||||||
expected.fulfillment.subconditions[0]['body'].sign(
|
expected.fulfillment.subconditions[0]['body'].sign(
|
||||||
str(tx).encode(), b58decode(user_priv))
|
message, b58decode(user_priv))
|
||||||
expected.fulfillment.subconditions[1]['body'].sign(
|
expected.fulfillment.subconditions[1]['body'].sign(
|
||||||
str(tx).encode(), b58decode(user_priv))
|
message, b58decode(user_priv))
|
||||||
|
|
||||||
tx.sign([user_priv, user_priv])
|
tx.sign([user_priv, user_priv])
|
||||||
|
|
||||||
@ -807,7 +822,6 @@ def test_outputs_to_inputs(tx):
|
|||||||
def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub,
|
def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub,
|
||||||
user2_output, user_priv):
|
user2_output, user_priv):
|
||||||
from bigchaindb.common.transaction import Transaction
|
from bigchaindb.common.transaction import Transaction
|
||||||
from bigchaindb.common.utils import serialize
|
|
||||||
from .utils import validate_transaction_model
|
from .utils import validate_transaction_model
|
||||||
|
|
||||||
expected = {
|
expected = {
|
||||||
@ -839,8 +853,14 @@ def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub,
|
|||||||
transfer_tx = transfer_tx.to_dict()
|
transfer_tx = transfer_tx.to_dict()
|
||||||
|
|
||||||
expected_input = deepcopy(inputs[0])
|
expected_input = deepcopy(inputs[0])
|
||||||
expected_input.fulfillment.sign(
|
json_serialized_tx = json.dumps(expected, sort_keys=True,
|
||||||
serialize(expected).encode(), b58decode(user_priv))
|
separators=(',', ':'), ensure_ascii=True)
|
||||||
|
message = sha3_256(json_serialized_tx.encode())
|
||||||
|
message.update('{}{}'.format(
|
||||||
|
expected['inputs'][0]['fulfills']['transaction_id'],
|
||||||
|
expected['inputs'][0]['fulfills']['output_index'],
|
||||||
|
).encode())
|
||||||
|
expected_input.fulfillment.sign(message.digest(), b58decode(user_priv))
|
||||||
expected_ffill = expected_input.fulfillment.serialize_uri()
|
expected_ffill = expected_input.fulfillment.serialize_uri()
|
||||||
transfer_ffill = transfer_tx['inputs'][0]['fulfillment']
|
transfer_ffill = transfer_tx['inputs'][0]['fulfillment']
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user