mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
fulfillment_message with output_condition
added tests
This commit is contained in:
parent
a3fa8393ac
commit
c623ca56d0
@ -480,7 +480,8 @@ def get_fulfillment_message(transaction, fulfillment, serialized=False):
|
|||||||
# or created on the fly it this is a `CREATE` transaction
|
# or created on the fly it this is a `CREATE` transaction
|
||||||
fulfillment_message.update({
|
fulfillment_message.update({
|
||||||
'input': fulfillment['input'],
|
'input': fulfillment['input'],
|
||||||
'condition': None,
|
'input_condition': None,
|
||||||
|
'output_condition': None
|
||||||
})
|
})
|
||||||
|
|
||||||
# if `TRANSFER` transaction
|
# if `TRANSFER` transaction
|
||||||
@ -489,12 +490,14 @@ def get_fulfillment_message(transaction, fulfillment, serialized=False):
|
|||||||
previous_tx = b.get_transaction(fulfillment['input']['txid'])
|
previous_tx = b.get_transaction(fulfillment['input']['txid'])
|
||||||
conditions = sorted(previous_tx['transaction']['conditions'], key=lambda d: d['cid'])
|
conditions = sorted(previous_tx['transaction']['conditions'], key=lambda d: d['cid'])
|
||||||
fulfillment_message['input_condition'] = conditions[fulfillment['input']['cid']]
|
fulfillment_message['input_condition'] = conditions[fulfillment['input']['cid']]
|
||||||
|
fulfillment_message['output_condition'] = transaction['transaction']['conditions'][fulfillment['input']['cid']]
|
||||||
# if `CREATE` transaction
|
# if `CREATE` transaction
|
||||||
# there is no previous transaction so we need to create one on the fly
|
# there is no previous transaction so we need to create one on the fly
|
||||||
else:
|
else:
|
||||||
current_owner = transaction['transaction']['fulfillments'][0]['current_owners'][0]
|
current_owner = transaction['transaction']['fulfillments'][0]['current_owners'][0]
|
||||||
condition = json.loads(cc.Ed25519Fulfillment(public_key=current_owner).serialize_json())
|
condition = json.loads(cc.Ed25519Fulfillment(public_key=current_owner).serialize_json())
|
||||||
fulfillment_message['input_condition'] = {'condition': {'details': condition}}
|
fulfillment_message['input_condition'] = {'condition': {'details': condition}}
|
||||||
|
fulfillment_message['output_condition'] = transaction['transaction']['conditions'][0]
|
||||||
if serialized:
|
if serialized:
|
||||||
return serialize(fulfillment_message)
|
return serialize(fulfillment_message)
|
||||||
return fulfillment_message
|
return fulfillment_message
|
||||||
|
@ -1202,6 +1202,86 @@ class TestMultipleInputs(object):
|
|||||||
assert b.get_spent(inp) is None
|
assert b.get_spent(inp) is None
|
||||||
|
|
||||||
|
|
||||||
|
class TestFulfillmentMessage(object):
|
||||||
|
def test_fulfillment_message_create(self, b, user_vk):
|
||||||
|
tx = b.create_transaction(b.me, user_vk, None, 'CREATE', payload={'pay': 'load'})
|
||||||
|
original_fulfillment = tx['transaction']['fulfillments'][0]
|
||||||
|
fulfillment_message = util.get_fulfillment_message(tx, original_fulfillment)
|
||||||
|
|
||||||
|
assert sorted(fulfillment_message) == ['data', 'id', 'input', 'input_condition',
|
||||||
|
'operation', 'output_condition', 'timestamp', 'version']
|
||||||
|
|
||||||
|
assert fulfillment_message['data']['payload'] == tx['transaction']['data']['payload']
|
||||||
|
assert fulfillment_message['id'] == tx['id']
|
||||||
|
assert fulfillment_message['input'] == original_fulfillment['input']
|
||||||
|
assert fulfillment_message['input_condition']['condition']['details']['public_key'] == \
|
||||||
|
original_fulfillment['current_owners'][0]
|
||||||
|
assert fulfillment_message['operation'] == tx['transaction']['operation']
|
||||||
|
assert fulfillment_message['timestamp'] == tx['transaction']['timestamp']
|
||||||
|
assert fulfillment_message['version'] == tx['version']
|
||||||
|
assert fulfillment_message['output_condition'] == tx['transaction']['conditions'][0]
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures('inputs')
|
||||||
|
def test_fulfillment_message_transfer(self, b, user_vk):
|
||||||
|
input_tx = b.get_owned_ids(user_vk).pop()
|
||||||
|
assert b.validate_fulfillments(b.get_transaction(input_tx['txid'])) == True
|
||||||
|
|
||||||
|
tx = b.create_transaction(user_vk, b.me, input_tx, 'TRANSFER', payload={'pay': 'load'})
|
||||||
|
|
||||||
|
original_fulfillment = tx['transaction']['fulfillments'][0]
|
||||||
|
fulfillment_message = util.get_fulfillment_message(tx, original_fulfillment)
|
||||||
|
|
||||||
|
assert sorted(fulfillment_message) == ['data', 'id', 'input', 'input_condition',
|
||||||
|
'operation', 'output_condition', 'timestamp', 'version']
|
||||||
|
|
||||||
|
assert fulfillment_message['data']['payload'] == tx['transaction']['data']['payload']
|
||||||
|
assert fulfillment_message['id'] == tx['id']
|
||||||
|
assert fulfillment_message['input'] == original_fulfillment['input']
|
||||||
|
assert fulfillment_message['input_condition']['new_owners'] == original_fulfillment['current_owners']
|
||||||
|
assert fulfillment_message['operation'] == tx['transaction']['operation']
|
||||||
|
assert fulfillment_message['timestamp'] == tx['transaction']['timestamp']
|
||||||
|
assert fulfillment_message['version'] == tx['version']
|
||||||
|
assert fulfillment_message['output_condition'] == tx['transaction']['conditions'][0]
|
||||||
|
|
||||||
|
def test_fulfillment_message_multiple_current_owners_multiple_new_owners_multiple_inputs(self, b, user_vk):
|
||||||
|
# create a new users
|
||||||
|
user2_sk, user2_vk = crypto.generate_key_pair()
|
||||||
|
user3_sk, user3_vk = crypto.generate_key_pair()
|
||||||
|
user4_sk, user4_vk = crypto.generate_key_pair()
|
||||||
|
|
||||||
|
# create inputs to spend
|
||||||
|
transactions = []
|
||||||
|
for i in range(5):
|
||||||
|
tx = b.create_transaction(b.me, [user_vk, user2_vk], None, 'CREATE')
|
||||||
|
tx_signed = b.sign_transaction(tx, b.me_private)
|
||||||
|
transactions.append(tx_signed)
|
||||||
|
block = b.create_block(transactions)
|
||||||
|
b.write_block(block, durability='hard')
|
||||||
|
|
||||||
|
# get input
|
||||||
|
owned_inputs = b.get_owned_ids(user_vk)
|
||||||
|
inp = owned_inputs[:3]
|
||||||
|
|
||||||
|
# create a transaction
|
||||||
|
tx = b.create_transaction([user_vk, user2_vk], [user3_vk, user4_vk], inp, 'TRANSFER', payload={'pay': 'load'})
|
||||||
|
|
||||||
|
for original_fulfillment in tx['transaction']['fulfillments']:
|
||||||
|
fulfillment_message = util.get_fulfillment_message(tx, original_fulfillment)
|
||||||
|
|
||||||
|
assert sorted(fulfillment_message) == ['data', 'id', 'input', 'input_condition',
|
||||||
|
'operation', 'output_condition', 'timestamp', 'version']
|
||||||
|
|
||||||
|
assert fulfillment_message['data']['payload'] == tx['transaction']['data']['payload']
|
||||||
|
assert fulfillment_message['id'] == tx['id']
|
||||||
|
assert fulfillment_message['input'] == original_fulfillment['input']
|
||||||
|
assert fulfillment_message['input_condition']['new_owners'] == original_fulfillment['current_owners']
|
||||||
|
assert fulfillment_message['operation'] == tx['transaction']['operation']
|
||||||
|
assert fulfillment_message['timestamp'] == tx['transaction']['timestamp']
|
||||||
|
assert fulfillment_message['version'] == tx['version']
|
||||||
|
assert fulfillment_message['output_condition'] == \
|
||||||
|
tx['transaction']['conditions'][original_fulfillment['input']['cid']]
|
||||||
|
|
||||||
|
|
||||||
class TestCryptoconditions(object):
|
class TestCryptoconditions(object):
|
||||||
def test_fulfillment_transaction_create(self, b, user_vk):
|
def test_fulfillment_transaction_create(self, b, user_vk):
|
||||||
tx = b.create_transaction(b.me, user_vk, None, 'CREATE')
|
tx = b.create_transaction(b.me, user_vk, None, 'CREATE')
|
||||||
@ -1306,7 +1386,7 @@ class TestCryptoconditions(object):
|
|||||||
assert b.is_valid_transaction(tx) == tx
|
assert b.is_valid_transaction(tx) == tx
|
||||||
|
|
||||||
@pytest.mark.usefixtures('inputs')
|
@pytest.mark.usefixtures('inputs')
|
||||||
def test_override_fulfillment_transfer(self, b, user_vk, user_sk):
|
def test_override_fulfillment_transfer(self, b, user_vk, user_sk):
|
||||||
# create valid transaction
|
# create valid transaction
|
||||||
other_sk, other_vk = crypto.generate_key_pair()
|
other_sk, other_vk = crypto.generate_key_pair()
|
||||||
prev_tx_id = b.get_owned_ids(user_vk).pop()
|
prev_tx_id = b.get_owned_ids(user_vk).pop()
|
||||||
@ -1323,7 +1403,7 @@ class TestCryptoconditions(object):
|
|||||||
assert b.is_valid_transaction(tx) == tx
|
assert b.is_valid_transaction(tx) == tx
|
||||||
|
|
||||||
@pytest.mark.usefixtures('inputs')
|
@pytest.mark.usefixtures('inputs')
|
||||||
def test_override_condition_and_fulfillment_transfer(self, b, user_vk, user_sk):
|
def test_override_condition_and_fulfillment_transfer(self, b, user_vk, user_sk):
|
||||||
other_sk, other_vk = crypto.generate_key_pair()
|
other_sk, other_vk = crypto.generate_key_pair()
|
||||||
first_input_tx = b.get_owned_ids(user_vk).pop()
|
first_input_tx = b.get_owned_ids(user_vk).pop()
|
||||||
first_tx = b.create_transaction(user_vk, other_vk, first_input_tx, 'TRANSFER')
|
first_tx = b.create_transaction(user_vk, other_vk, first_input_tx, 'TRANSFER')
|
||||||
@ -1560,7 +1640,8 @@ class TestCryptoconditions(object):
|
|||||||
tx_transfer_signed = b.sign_transaction(tx_transfer, [user_sk, user2_sk])
|
tx_transfer_signed = b.sign_transaction(tx_transfer, [user_sk, user2_sk])
|
||||||
|
|
||||||
# expected fulfillment
|
# expected fulfillment
|
||||||
expected_fulfillment = cc.Fulfillment.from_json(tx_create['transaction']['conditions'][0]['condition']['details'])
|
expected_fulfillment = cc.Fulfillment.from_json(
|
||||||
|
tx_create['transaction']['conditions'][0]['condition']['details'])
|
||||||
subfulfillment1 = expected_fulfillment.subconditions[0]['body']
|
subfulfillment1 = expected_fulfillment.subconditions[0]['body']
|
||||||
subfulfillment2 = expected_fulfillment.subconditions[1]['body']
|
subfulfillment2 = expected_fulfillment.subconditions[1]['body']
|
||||||
|
|
||||||
@ -1571,7 +1652,7 @@ class TestCryptoconditions(object):
|
|||||||
subfulfillment2.sign(util.serialize(expected_fulfillment_message), crypto.SigningKey(user2_sk))
|
subfulfillment2.sign(util.serialize(expected_fulfillment_message), crypto.SigningKey(user2_sk))
|
||||||
|
|
||||||
assert tx_transfer_signed['transaction']['fulfillments'][0]['fulfillment'] \
|
assert tx_transfer_signed['transaction']['fulfillments'][0]['fulfillment'] \
|
||||||
== expected_fulfillment.serialize_uri()
|
== expected_fulfillment.serialize_uri()
|
||||||
|
|
||||||
assert b.validate_fulfillments(tx_transfer_signed) is True
|
assert b.validate_fulfillments(tx_transfer_signed) is True
|
||||||
|
|
||||||
@ -1696,7 +1777,8 @@ class TestCryptoconditions(object):
|
|||||||
|
|
||||||
# try doublespending
|
# try doublespending
|
||||||
user2_sk, user2_vk = crypto.generate_key_pair()
|
user2_sk, user2_vk = crypto.generate_key_pair()
|
||||||
hashlock_doublespend_tx = b.create_transaction(None, user2_vk, {'txid': hashlock_tx['id'], 'cid': 0}, 'TRANSFER')
|
hashlock_doublespend_tx = b.create_transaction(None, user2_vk, {'txid': hashlock_tx['id'], 'cid': 0},
|
||||||
|
'TRANSFER')
|
||||||
|
|
||||||
hashlock_doublespend_tx_fulfillment = cc.PreimageSha256Fulfillment(preimage=secret)
|
hashlock_doublespend_tx_fulfillment = cc.PreimageSha256Fulfillment(preimage=secret)
|
||||||
hashlock_doublespend_tx['transaction']['fulfillments'][0]['fulfillment'] = \
|
hashlock_doublespend_tx['transaction']['fulfillments'][0]['fulfillment'] = \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user