mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Merge remote-tracking branch 'remotes/origin/feat/128/multiple-input-output' into feat/127/crypto-conditions-ilp-bigchain-integration
Conflicts: bigchaindb/consensus.py bigchaindb/util.py
This commit is contained in:
commit
ce945e3409
@ -1,3 +1,4 @@
|
|||||||
|
import copy
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
|
|
||||||
import bigchaindb.exceptions as exceptions
|
import bigchaindb.exceptions as exceptions
|
||||||
@ -119,9 +120,11 @@ class BaseConsensusRules(AbstractConsensusRules):
|
|||||||
# If the operation is CREATE the transaction should have no inputs and
|
# If the operation is CREATE the transaction should have no inputs and
|
||||||
# should be signed by a federation node
|
# should be signed by a federation node
|
||||||
if transaction['transaction']['operation'] == 'CREATE':
|
if transaction['transaction']['operation'] == 'CREATE':
|
||||||
if transaction['transaction']['inputs']:
|
# TODO: for now lets assume a CREATE transaction only has one fulfillment
|
||||||
|
if transaction['transaction']['fulfillments'][0]['input']:
|
||||||
raise ValueError('A CREATE operation has no inputs')
|
raise ValueError('A CREATE operation has no inputs')
|
||||||
if transaction['transaction']['current_owner'] not in (
|
# TODO: fow now lets assume a CREATE transaction only has one current_owner
|
||||||
|
if transaction['transaction']['fulfillments'][0]['current_owners'][0] not in (
|
||||||
bigchain.federation_nodes + [bigchain.me]):
|
bigchain.federation_nodes + [bigchain.me]):
|
||||||
raise exceptions.OperationError(
|
raise exceptions.OperationError(
|
||||||
'Only federation nodes can use the operation `CREATE`')
|
'Only federation nodes can use the operation `CREATE`')
|
||||||
@ -156,6 +159,11 @@ class BaseConsensusRules(AbstractConsensusRules):
|
|||||||
'input `{}` was already spent'.format(inp))
|
'input `{}` was already spent'.format(inp))
|
||||||
|
|
||||||
# Check hash of the transaction
|
# Check hash of the transaction
|
||||||
|
# remove the fulfillment messages (signatures)
|
||||||
|
transaction_data = copy.deepcopy(transaction)
|
||||||
|
for fulfillment in transaction_data['transaction']['fulfillments']:
|
||||||
|
fulfillment['fulfillment'] = None
|
||||||
|
|
||||||
calculated_hash = crypto.hash_data(util.serialize(
|
calculated_hash = crypto.hash_data(util.serialize(
|
||||||
transaction['transaction']))
|
transaction['transaction']))
|
||||||
if calculated_hash != transaction['id']:
|
if calculated_hash != transaction['id']:
|
||||||
|
@ -388,7 +388,7 @@ class Bigchain(object):
|
|||||||
raise GenesisBlockAlreadyExistsError('Cannot create the Genesis block')
|
raise GenesisBlockAlreadyExistsError('Cannot create the Genesis block')
|
||||||
|
|
||||||
payload = {'message': 'Hello World from the BigchainDB'}
|
payload = {'message': 'Hello World from the BigchainDB'}
|
||||||
transaction = self.create_transaction(self.me, self.me, None, 'GENESIS', payload=payload)
|
transaction = self.create_transaction([self.me], [self.me], None, 'GENESIS', payload=payload)
|
||||||
transaction_signed = self.sign_transaction(transaction, self.me_private)
|
transaction_signed = self.sign_transaction(transaction, self.me_private)
|
||||||
|
|
||||||
# create the block
|
# create the block
|
||||||
|
@ -239,7 +239,7 @@ def sign_tx(transaction, private_key):
|
|||||||
|
|
||||||
for fulfillment in transaction['transaction']['fulfillments']:
|
for fulfillment in transaction['transaction']['fulfillments']:
|
||||||
fulfillment_message = common_data.copy()
|
fulfillment_message = common_data.copy()
|
||||||
if transaction['transaction']['operation'] == 'CREATE':
|
if transaction['transaction']['operation'] in ['CREATE', 'GENESIS']:
|
||||||
fulfillment_message.update({
|
fulfillment_message.update({
|
||||||
'input': None,
|
'input': None,
|
||||||
'condition': None
|
'condition': None
|
||||||
@ -279,6 +279,7 @@ def check_hash_and_signature(transaction):
|
|||||||
|
|
||||||
|
|
||||||
def verify_signature(signed_transaction):
|
def verify_signature(signed_transaction):
|
||||||
|
# TODO: The name should change. This will be the validation of the fulfillments
|
||||||
"""Verify the signature of a transaction
|
"""Verify the signature of a transaction
|
||||||
|
|
||||||
A valid transaction should have been signed `current_owner` corresponding private key.
|
A valid transaction should have been signed `current_owner` corresponding private key.
|
||||||
@ -290,16 +291,38 @@ def verify_signature(signed_transaction):
|
|||||||
bool: True if the signature is correct, False otherwise.
|
bool: True if the signature is correct, False otherwise.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
data = signed_transaction.copy()
|
b = bigchaindb.Bigchain()
|
||||||
|
|
||||||
# if assignee field in the transaction, remove it
|
common_data = {
|
||||||
if 'assignee' in data:
|
'operation': signed_transaction['transaction']['operation'],
|
||||||
data.pop('assignee')
|
'timestamp': signed_transaction['transaction']['timestamp'],
|
||||||
|
'data': signed_transaction['transaction']['data'],
|
||||||
|
'version': signed_transaction['version'],
|
||||||
|
'id': signed_transaction['id']
|
||||||
|
}
|
||||||
|
|
||||||
signature = data.pop('signature')
|
for fulfillment in signed_transaction['transaction']['fulfillments']:
|
||||||
public_key_base58 = signed_transaction['transaction']['current_owner']
|
fulfillment_message = common_data.copy()
|
||||||
public_key = crypto.VerifyingKey(public_key_base58)
|
fulfillment_message.update({
|
||||||
return public_key.verify(serialize(data), signature)
|
'input': fulfillment['input'],
|
||||||
|
'condition': None,
|
||||||
|
})
|
||||||
|
|
||||||
|
# if not a `CREATE` transaction
|
||||||
|
if fulfillment['input']:
|
||||||
|
# get previous condition
|
||||||
|
previous_tx = b.get_transaction(fulfillment['input']['txid'])
|
||||||
|
conditions = sorted(previous_tx['transaction']['conditions'], key=lambda d: d['cid'])
|
||||||
|
fulfillment_message['condition'] = conditions[fulfillment['cid']]
|
||||||
|
|
||||||
|
# verify the signature (for now lets assume there is only one owner)
|
||||||
|
vk = crypto.VerifyingKey(fulfillment['current_owners'][0])
|
||||||
|
|
||||||
|
is_valid = vk.verify(serialize(fulfillment_message), fulfillment['fulfillment'])
|
||||||
|
if not is_valid:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def transform_create(tx):
|
def transform_create(tx):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user