Merge pull request #1294 from bigchaindb/bug/1291/threshold-conditions-duplicated-pks

_sign_threshold now signs all subconditions for a public key
This commit is contained in:
Rodolphe Marques 2017-03-17 10:32:21 +01:00 committed by GitHub
commit e97cee8c84
2 changed files with 49 additions and 13 deletions

View File

@ -768,20 +768,19 @@ class Transaction(object):
key_pairs (dict): The keys to sign the Transaction with.
"""
input_ = deepcopy(input_)
for owner_before in input_.owners_before:
try:
# TODO: CC should throw a KeypairMismatchException, instead of
# our manual mapping here
for owner_before in set(input_.owners_before):
# TODO: CC should throw a KeypairMismatchException, instead of
# our manual mapping here
# TODO FOR CC: Naming wise this is not so smart,
# `get_subcondition` in fact doesn't return a
# condition but a fulfillment
# TODO FOR CC: Naming wise this is not so smart,
# `get_subcondition` in fact doesn't return a
# condition but a fulfillment
# TODO FOR CC: `get_subcondition` is singular. One would not
# expect to get a list back.
ccffill = input_.fulfillment
subffill = ccffill.get_subcondition_from_vk(owner_before)[0]
except IndexError:
# TODO FOR CC: `get_subcondition` is singular. One would not
# expect to get a list back.
ccffill = input_.fulfillment
subffills = ccffill.get_subcondition_from_vk(owner_before)
if not subffills:
raise KeypairMismatchException('Public key {} cannot be found '
'in the fulfillment'
.format(owner_before))
@ -794,7 +793,8 @@ class Transaction(object):
# cryptoconditions makes no assumptions of the encoding of the
# message to sign or verify. It only accepts bytestrings
subffill.sign(tx_serialized.encode(), private_key)
for subffill in subffills:
subffill.sign(tx_serialized.encode(), private_key)
self.inputs[index] = input_
def inputs_valid(self, outputs=None):

View File

@ -590,6 +590,42 @@ def test_validate_tx_threshold_create_signature(user_user2_threshold_input,
validate_transaction_model(tx)
def test_validate_tx_threshold_duplicated_pk(user_pub, user_priv,
asset_definition):
from copy import deepcopy
from cryptoconditions import Ed25519Fulfillment, ThresholdSha256Fulfillment
from bigchaindb.common.transaction import Input, Output, Transaction
from bigchaindb.common.crypto import PrivateKey
threshold = ThresholdSha256Fulfillment(threshold=2)
threshold.add_subfulfillment(Ed25519Fulfillment(public_key=user_pub))
threshold.add_subfulfillment(Ed25519Fulfillment(public_key=user_pub))
threshold_input = Input(threshold, [user_pub, user_pub])
threshold_output = Output(threshold, [user_pub, user_pub])
tx = Transaction(Transaction.CREATE, asset_definition,
[threshold_input], [threshold_output])
expected = deepcopy(threshold_input)
expected.fulfillment.subconditions[0]['body'].sign(str(tx).encode(),
PrivateKey(user_priv))
expected.fulfillment.subconditions[1]['body'].sign(str(tx).encode(),
PrivateKey(user_priv))
tx.sign([user_priv, user_priv])
subconditions = tx.inputs[0].fulfillment.subconditions
expected_subconditions = expected.fulfillment.subconditions
assert subconditions[0]['body'].to_dict()['signature'] == \
expected_subconditions[0]['body'].to_dict()['signature']
assert subconditions[1]['body'].to_dict()['signature'] == \
expected_subconditions[1]['body'].to_dict()['signature']
assert tx.inputs[0].to_dict()['fulfillment'] == \
expected.fulfillment.serialize_uri()
assert tx.inputs_valid() is True
def test_multiple_input_validation_of_transfer_tx(user_input, user_output,
user_priv, user2_pub,
user2_priv, user3_pub,