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
|
||||
|
||||
import bigchaindb.exceptions as exceptions
|
||||
@ -119,9 +120,11 @@ class BaseConsensusRules(AbstractConsensusRules):
|
||||
# If the operation is CREATE the transaction should have no inputs and
|
||||
# should be signed by a federation node
|
||||
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')
|
||||
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]):
|
||||
raise exceptions.OperationError(
|
||||
'Only federation nodes can use the operation `CREATE`')
|
||||
@ -156,6 +159,11 @@ class BaseConsensusRules(AbstractConsensusRules):
|
||||
'input `{}` was already spent'.format(inp))
|
||||
|
||||
# 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(
|
||||
transaction['transaction']))
|
||||
if calculated_hash != transaction['id']:
|
||||
|
@ -388,7 +388,7 @@ class Bigchain(object):
|
||||
raise GenesisBlockAlreadyExistsError('Cannot create the Genesis block')
|
||||
|
||||
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)
|
||||
|
||||
# create the block
|
||||
|
@ -239,7 +239,7 @@ def sign_tx(transaction, private_key):
|
||||
|
||||
for fulfillment in transaction['transaction']['fulfillments']:
|
||||
fulfillment_message = common_data.copy()
|
||||
if transaction['transaction']['operation'] == 'CREATE':
|
||||
if transaction['transaction']['operation'] in ['CREATE', 'GENESIS']:
|
||||
fulfillment_message.update({
|
||||
'input': None,
|
||||
'condition': None
|
||||
@ -279,6 +279,7 @@ def check_hash_and_signature(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
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
data = signed_transaction.copy()
|
||||
b = bigchaindb.Bigchain()
|
||||
|
||||
# if assignee field in the transaction, remove it
|
||||
if 'assignee' in data:
|
||||
data.pop('assignee')
|
||||
common_data = {
|
||||
'operation': signed_transaction['transaction']['operation'],
|
||||
'timestamp': signed_transaction['transaction']['timestamp'],
|
||||
'data': signed_transaction['transaction']['data'],
|
||||
'version': signed_transaction['version'],
|
||||
'id': signed_transaction['id']
|
||||
}
|
||||
|
||||
signature = data.pop('signature')
|
||||
public_key_base58 = signed_transaction['transaction']['current_owner']
|
||||
public_key = crypto.VerifyingKey(public_key_base58)
|
||||
return public_key.verify(serialize(data), signature)
|
||||
for fulfillment in signed_transaction['transaction']['fulfillments']:
|
||||
fulfillment_message = common_data.copy()
|
||||
fulfillment_message.update({
|
||||
'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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user