mirror of
https://github.com/planetmint/planetmint.git
synced 2025-11-26 23:45:47 +00:00
* 31 restructue documentation (#138) * removed korean documentation Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * removed CN and KOR readme Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * changed to the press theme Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * first changes Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * fixe H3 vs H1 issues Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * added missing png Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * added missing file Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * fixed warnings Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * moved documents Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * removed obsolete files Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * removed obsolete folder Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * removed obs. file Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * added some final changes Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * removed obs. reference Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * moved chain migration to election types (#109) Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * Final zenroom (#147) * zenroom fixes Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * expl. defined the aiohttp package Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * increased version number and fixed a zenroom runtime bug Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * added fialing zenroom tx signing test Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * extended test to pass zenrooom validation, but to fail planetmint validation. Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * added manual tx crafting Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * added zenroom fulfillment verification Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * the last mile before integration Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * zenroom unit tests are passing Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * simplified zenroom unit tests Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * removed obsolte lines from the zenroom tests Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * fixed acceptance tests Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * adjusted zenroom integraiton tests Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * fixed linting errors Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * simplified zenroom unit test Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * increased version number Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * using cryptoconditions without print message Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * increased cc usage to 0.9.9 readded daemon proceses Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * increased version to 0.9.6 Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * fixed deployment issue for 0.9.6 Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * adjusted get_assets and from_db for tarantool Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added comment Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * improve usability of zenroom (#159) * improve usability of zenroom * * increased version * fixed test cases * added changelog Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> Co-authored-by: Jürgen Eckel <juergen@riddleandcode.com> * migrated to AGPLv3 Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * 150 add cryptoconditions documentation (#166) * added smaller logos fixed reference issue Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * fixed some erros and typos Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * added cryptoconditions reference to the subproject Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * docker all in one now install tarantool Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added user to integration init.lua Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * updated integration test setup for tarantool Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * removed print statements Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * updated changelog Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * fixed error messaging Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * fixed exception verification Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * fixed printing of testdata Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> Co-authored-by: Jürgen Eckel <eckelj@users.noreply.github.com> Co-authored-by: Lorenz Herzberger <64837895+LaurentDeMontBlanc@users.noreply.github.com> Co-authored-by: Alberto Lerda <30939098+albertolerda@users.noreply.github.com> Co-authored-by: Jürgen Eckel <juergen@riddleandcode.com>
571 lines
22 KiB
Python
571 lines
22 KiB
Python
# Copyright © 2020 Interplanetary Database Association e.V.,
|
|
# Planetmint and IPDB software contributors.
|
|
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
|
|
# Code is Apache-2.0 and docs are CC-BY-4.0
|
|
|
|
|
|
import pytest
|
|
import random
|
|
|
|
from planetmint.transactions.types.assets.create import Create
|
|
from planetmint.transactions.types.assets.transfer import Transfer
|
|
from planetmint.transactions.common.exceptions import DoubleSpend
|
|
|
|
|
|
# CREATE divisible asset
|
|
# Single input
|
|
# Single owners_before
|
|
# Single output
|
|
# Single owners_after
|
|
def test_single_in_single_own_single_out_single_own_create(alice, user_pk, b):
|
|
|
|
tx = Create.generate([alice.public_key], [([user_pk], 100)], asset={'name': random.random()})
|
|
tx_signed = tx.sign([alice.private_key])
|
|
|
|
assert tx_signed.validate(b) == tx_signed
|
|
assert len(tx_signed.outputs) == 1
|
|
assert tx_signed.outputs[0].amount == 100
|
|
assert len(tx_signed.inputs) == 1
|
|
|
|
|
|
# CREATE divisible asset
|
|
# Single input
|
|
# Single owners_before
|
|
# Multiple outputs
|
|
# Single owners_after per output
|
|
def test_single_in_single_own_multiple_out_single_own_create(alice, user_pk, b):
|
|
|
|
tx = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk], 50)],
|
|
asset={'name': random.random()})
|
|
tx_signed = tx.sign([alice.private_key])
|
|
|
|
assert tx_signed.validate(b) == tx_signed
|
|
assert len(tx_signed.outputs) == 2
|
|
assert tx_signed.outputs[0].amount == 50
|
|
assert tx_signed.outputs[1].amount == 50
|
|
assert len(tx_signed.inputs) == 1
|
|
|
|
|
|
# CREATE divisible asset
|
|
# Single input
|
|
# Single owners_before
|
|
# Single output
|
|
# Multiple owners_after
|
|
def test_single_in_single_own_single_out_multiple_own_create(alice, user_pk, b):
|
|
|
|
tx = Create.generate([alice.public_key], [([user_pk, user_pk], 100)], asset={'name': random.random()})
|
|
tx_signed = tx.sign([alice.private_key])
|
|
|
|
assert tx_signed.validate(b) == tx_signed
|
|
assert len(tx_signed.outputs) == 1
|
|
assert tx_signed.outputs[0].amount == 100
|
|
|
|
output = tx_signed.outputs[0].to_dict()
|
|
assert 'subconditions' in output['condition']['details']
|
|
assert len(output['condition']['details']['subconditions']) == 2
|
|
|
|
assert len(tx_signed.inputs) == 1
|
|
|
|
|
|
# CREATE divisible asset
|
|
# Single input
|
|
# Single owners_before
|
|
# Multiple outputs
|
|
# Mix: one output with a single owners_after, one output with multiple
|
|
# owners_after
|
|
def test_single_in_single_own_multiple_out_mix_own_create(alice, user_pk, b):
|
|
|
|
tx = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk, user_pk], 50)],
|
|
asset={'name': random.random()})
|
|
tx_signed = tx.sign([alice.private_key])
|
|
|
|
assert tx_signed.validate(b) == tx_signed
|
|
assert len(tx_signed.outputs) == 2
|
|
assert tx_signed.outputs[0].amount == 50
|
|
assert tx_signed.outputs[1].amount == 50
|
|
|
|
output_cid1 = tx_signed.outputs[1].to_dict()
|
|
assert 'subconditions' in output_cid1['condition']['details']
|
|
assert len(output_cid1['condition']['details']['subconditions']) == 2
|
|
|
|
assert len(tx_signed.inputs) == 1
|
|
|
|
|
|
# CREATE divisible asset
|
|
# Single input
|
|
# Multiple owners_before
|
|
# Output combinations already tested above
|
|
def test_single_in_multiple_own_single_out_single_own_create(alice, b, user_pk,
|
|
user_sk):
|
|
from planetmint.transactions.common.utils import _fulfillment_to_details
|
|
|
|
tx = Create.generate([alice.public_key, user_pk], [([user_pk], 100)], asset={'name': random.random()})
|
|
tx_signed = tx.sign([alice.private_key, user_sk])
|
|
assert tx_signed.validate(b) == tx_signed
|
|
assert len(tx_signed.outputs) == 1
|
|
assert tx_signed.outputs[0].amount == 100
|
|
assert len(tx_signed.inputs) == 1
|
|
|
|
ffill = _fulfillment_to_details(tx_signed.inputs[0].fulfillment)
|
|
assert 'subconditions' in ffill
|
|
assert len(ffill['subconditions']) == 2
|
|
|
|
|
|
# TRANSFER divisible asset
|
|
# Single input
|
|
# Single owners_before
|
|
# Single output
|
|
# Single owners_after
|
|
def test_single_in_single_own_single_out_single_own_transfer(alice, b, user_pk,
|
|
user_sk):
|
|
|
|
# CREATE divisible asset
|
|
tx_create = Create.generate([alice.public_key], [([user_pk], 100)], asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# TRANSFER
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(), [([alice.public_key], 100)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([user_sk])
|
|
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
assert tx_transfer_signed.validate(b)
|
|
assert len(tx_transfer_signed.outputs) == 1
|
|
assert tx_transfer_signed.outputs[0].amount == 100
|
|
assert len(tx_transfer_signed.inputs) == 1
|
|
|
|
|
|
# TRANSFER divisible asset
|
|
# Single input
|
|
# Single owners_before
|
|
# Multiple output
|
|
# Single owners_after
|
|
def test_single_in_single_own_multiple_out_single_own_transfer(alice, b, user_pk,
|
|
user_sk):
|
|
|
|
# CREATE divisible asset
|
|
tx_create = Create.generate([alice.public_key], [([user_pk], 100)], asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# TRANSFER
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(),
|
|
[([alice.public_key], 50), ([alice.public_key], 50)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([user_sk])
|
|
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
|
assert len(tx_transfer_signed.outputs) == 2
|
|
assert tx_transfer_signed.outputs[0].amount == 50
|
|
assert tx_transfer_signed.outputs[1].amount == 50
|
|
assert len(tx_transfer_signed.inputs) == 1
|
|
|
|
|
|
# TRANSFER divisible asset
|
|
# Single input
|
|
# Single owners_before
|
|
# Single output
|
|
# Multiple owners_after
|
|
def test_single_in_single_own_single_out_multiple_own_transfer(alice, b, user_pk,
|
|
user_sk):
|
|
|
|
# CREATE divisible asset
|
|
tx_create = Create.generate([alice.public_key], [([user_pk], 100)], asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# TRANSFER
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(),
|
|
[([alice.public_key, alice.public_key], 100)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([user_sk])
|
|
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
|
assert len(tx_transfer_signed.outputs) == 1
|
|
assert tx_transfer_signed.outputs[0].amount == 100
|
|
|
|
condition = tx_transfer_signed.outputs[0].to_dict()
|
|
assert 'subconditions' in condition['condition']['details']
|
|
assert len(condition['condition']['details']['subconditions']) == 2
|
|
|
|
assert len(tx_transfer_signed.inputs) == 1
|
|
b.store_bulk_transactions([tx_transfer_signed])
|
|
with pytest.raises(DoubleSpend):
|
|
tx_transfer_signed.validate(b)
|
|
|
|
|
|
# TRANSFER divisible asset
|
|
# Single input
|
|
# Single owners_before
|
|
# Multiple outputs
|
|
# Mix: one output with a single owners_after, one output with multiple
|
|
# owners_after
|
|
def test_single_in_single_own_multiple_out_mix_own_transfer(alice, b, user_pk,
|
|
user_sk):
|
|
|
|
# CREATE divisible asset
|
|
tx_create = Create.generate([alice.public_key], [([user_pk], 100)], asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# TRANSFER
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(),
|
|
[([alice.public_key], 50), ([alice.public_key, alice.public_key], 50)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([user_sk])
|
|
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
|
assert len(tx_transfer_signed.outputs) == 2
|
|
assert tx_transfer_signed.outputs[0].amount == 50
|
|
assert tx_transfer_signed.outputs[1].amount == 50
|
|
|
|
output_cid1 = tx_transfer_signed.outputs[1].to_dict()
|
|
assert 'subconditions' in output_cid1['condition']['details']
|
|
assert len(output_cid1['condition']['details']['subconditions']) == 2
|
|
|
|
assert len(tx_transfer_signed.inputs) == 1
|
|
|
|
b.store_bulk_transactions([tx_transfer_signed])
|
|
with pytest.raises(DoubleSpend):
|
|
tx_transfer_signed.validate(b)
|
|
|
|
|
|
# TRANSFER divisible asset
|
|
# Single input
|
|
# Multiple owners_before
|
|
# Single output
|
|
# Single owners_after
|
|
def test_single_in_multiple_own_single_out_single_own_transfer(alice, b, user_pk,
|
|
user_sk):
|
|
from planetmint.transactions.common.utils import _fulfillment_to_details
|
|
|
|
# CREATE divisible asset
|
|
tx_create = Create.generate([alice.public_key], [([alice.public_key, user_pk], 100)],
|
|
asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# TRANSFER
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(), [([alice.public_key], 100)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([alice.private_key, user_sk])
|
|
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
|
assert len(tx_transfer_signed.outputs) == 1
|
|
assert tx_transfer_signed.outputs[0].amount == 100
|
|
assert len(tx_transfer_signed.inputs) == 1
|
|
|
|
ffill = _fulfillment_to_details(tx_transfer_signed.inputs[0].fulfillment)
|
|
assert 'subconditions' in ffill
|
|
assert len(ffill['subconditions']) == 2
|
|
|
|
b.store_bulk_transactions([tx_transfer_signed])
|
|
with pytest.raises(DoubleSpend):
|
|
tx_transfer_signed.validate(b)
|
|
|
|
|
|
# TRANSFER divisible asset
|
|
# Multiple inputs
|
|
# Single owners_before per input
|
|
# Single output
|
|
# Single owners_after
|
|
def test_multiple_in_single_own_single_out_single_own_transfer(alice, b, user_pk,
|
|
user_sk):
|
|
# CREATE divisible asset
|
|
tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk], 50)],
|
|
asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# TRANSFER
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(), [([alice.public_key], 100)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([user_sk])
|
|
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
assert tx_transfer_signed.validate(b)
|
|
assert len(tx_transfer_signed.outputs) == 1
|
|
assert tx_transfer_signed.outputs[0].amount == 100
|
|
assert len(tx_transfer_signed.inputs) == 2
|
|
|
|
b.store_bulk_transactions([tx_transfer_signed])
|
|
with pytest.raises(DoubleSpend):
|
|
tx_transfer_signed.validate(b)
|
|
|
|
|
|
# TRANSFER divisible asset
|
|
# Multiple inputs
|
|
# Multiple owners_before per input
|
|
# Single output
|
|
# Single owners_after
|
|
def test_multiple_in_multiple_own_single_out_single_own_transfer(alice, b, user_pk,
|
|
user_sk):
|
|
from planetmint.transactions.common.utils import _fulfillment_to_details
|
|
|
|
# CREATE divisible asset
|
|
tx_create = Create.generate([alice.public_key], [([user_pk, alice.public_key], 50),
|
|
([user_pk, alice.public_key], 50)],
|
|
asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# TRANSFER
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(), [([alice.public_key], 100)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([alice.private_key, user_sk])
|
|
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
|
assert len(tx_transfer_signed.outputs) == 1
|
|
assert tx_transfer_signed.outputs[0].amount == 100
|
|
assert len(tx_transfer_signed.inputs) == 2
|
|
|
|
ffill_fid0 = _fulfillment_to_details(tx_transfer_signed.inputs[0].fulfillment)
|
|
ffill_fid1 = _fulfillment_to_details(tx_transfer_signed.inputs[1].fulfillment)
|
|
assert 'subconditions' in ffill_fid0
|
|
assert 'subconditions' in ffill_fid1
|
|
assert len(ffill_fid0['subconditions']) == 2
|
|
assert len(ffill_fid1['subconditions']) == 2
|
|
|
|
b.store_bulk_transactions([tx_transfer_signed])
|
|
with pytest.raises(DoubleSpend):
|
|
tx_transfer_signed.validate(b)
|
|
|
|
|
|
# TRANSFER divisible asset
|
|
# Multiple inputs
|
|
# Mix: one input with a single owners_before, one input with multiple
|
|
# owners_before
|
|
# Single output
|
|
# Single owners_after
|
|
def test_muiltiple_in_mix_own_multiple_out_single_own_transfer(alice, b, user_pk,
|
|
user_sk):
|
|
from planetmint.transactions.common.utils import _fulfillment_to_details
|
|
|
|
# CREATE divisible asset
|
|
tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk, alice.public_key], 50)],
|
|
asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# TRANSFER
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(), [([alice.public_key], 100)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([alice.private_key, user_sk])
|
|
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
|
assert len(tx_transfer_signed.outputs) == 1
|
|
assert tx_transfer_signed.outputs[0].amount == 100
|
|
assert len(tx_transfer_signed.inputs) == 2
|
|
|
|
ffill_fid0 = _fulfillment_to_details(tx_transfer_signed.inputs[0].fulfillment)
|
|
ffill_fid1 = _fulfillment_to_details(tx_transfer_signed.inputs[1].fulfillment)
|
|
assert 'subconditions' not in ffill_fid0
|
|
assert 'subconditions' in ffill_fid1
|
|
assert len(ffill_fid1['subconditions']) == 2
|
|
|
|
b.store_bulk_transactions([tx_transfer_signed])
|
|
with pytest.raises(DoubleSpend):
|
|
tx_transfer_signed.validate(b)
|
|
|
|
|
|
# TRANSFER divisible asset
|
|
# Multiple inputs
|
|
# Mix: one input with a single owners_before, one input with multiple
|
|
# owners_before
|
|
# Multiple outputs
|
|
# Mix: one output with a single owners_after, one output with multiple
|
|
# owners_after
|
|
def test_muiltiple_in_mix_own_multiple_out_mix_own_transfer(alice, b, user_pk,
|
|
user_sk):
|
|
from planetmint.transactions.common.utils import _fulfillment_to_details
|
|
|
|
# CREATE divisible asset
|
|
tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk, alice.public_key], 50)],
|
|
asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
# TRANSFER
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(),
|
|
[([alice.public_key], 50), ([alice.public_key, user_pk], 50)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([alice.private_key, user_sk])
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
|
assert len(tx_transfer_signed.outputs) == 2
|
|
assert tx_transfer_signed.outputs[0].amount == 50
|
|
assert tx_transfer_signed.outputs[1].amount == 50
|
|
assert len(tx_transfer_signed.inputs) == 2
|
|
|
|
cond_cid0 = tx_transfer_signed.outputs[0].to_dict()
|
|
cond_cid1 = tx_transfer_signed.outputs[1].to_dict()
|
|
assert 'subconditions' not in cond_cid0['condition']['details']
|
|
assert 'subconditions' in cond_cid1['condition']['details']
|
|
assert len(cond_cid1['condition']['details']['subconditions']) == 2
|
|
|
|
ffill_fid0 = _fulfillment_to_details(tx_transfer_signed.inputs[0].fulfillment)
|
|
ffill_fid1 = _fulfillment_to_details(tx_transfer_signed.inputs[1].fulfillment)
|
|
assert 'subconditions' not in ffill_fid0
|
|
assert 'subconditions' in ffill_fid1
|
|
assert len(ffill_fid1['subconditions']) == 2
|
|
|
|
b.store_bulk_transactions([tx_transfer_signed])
|
|
with pytest.raises(DoubleSpend):
|
|
tx_transfer_signed.validate(b)
|
|
|
|
|
|
# TRANSFER divisible asset
|
|
# Multiple inputs from different transactions
|
|
# Single owners_before
|
|
# Single output
|
|
# Single owners_after
|
|
def test_multiple_in_different_transactions(alice, b, user_pk, user_sk):
|
|
|
|
# CREATE divisible asset
|
|
# `b` creates a divisible asset and assigns 50 shares to `b` and
|
|
# 50 shares to `user_pk`
|
|
tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([alice.public_key], 50)],
|
|
asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# TRANSFER divisible asset
|
|
# `b` transfers its 50 shares to `user_pk`
|
|
# after this transaction `user_pk` will have a total of 100 shares
|
|
# split across two different transactions
|
|
tx_transfer1 = Transfer.generate(tx_create.to_inputs([1]),
|
|
[([user_pk], 50)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer1_signed = tx_transfer1.sign([alice.private_key])
|
|
|
|
# TRANSFER
|
|
# `user_pk` combines two different transaction with 50 shares each and
|
|
# transfers a total of 100 shares back to `b`
|
|
tx_transfer2 = Transfer.generate(tx_create.to_inputs([0]) +
|
|
tx_transfer1.to_inputs([0]),
|
|
[([alice.private_key], 100)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer2_signed = tx_transfer2.sign([user_sk])
|
|
|
|
b.store_bulk_transactions([tx_create_signed, tx_transfer1_signed])
|
|
|
|
assert tx_transfer2_signed.validate(b) == tx_transfer2_signed
|
|
assert len(tx_transfer2_signed.outputs) == 1
|
|
assert tx_transfer2_signed.outputs[0].amount == 100
|
|
assert len(tx_transfer2_signed.inputs) == 2
|
|
|
|
fid0_input = tx_transfer2_signed.inputs[0].fulfills.txid
|
|
fid1_input = tx_transfer2_signed.inputs[1].fulfills.txid
|
|
assert fid0_input == tx_create.id
|
|
assert fid1_input == tx_transfer1.id
|
|
|
|
|
|
# In a TRANSFER transaction of a divisible asset the amount being spent in the
|
|
# inputs needs to match the amount being sent in the outputs.
|
|
# In other words `amount_in_inputs - amount_in_outputs == 0`
|
|
def test_amount_error_transfer(alice, b, user_pk, user_sk):
|
|
from planetmint.transactions.common.exceptions import AmountError
|
|
|
|
# CREATE divisible asset
|
|
tx_create = Create.generate([alice.public_key], [([user_pk], 100)], asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
# TRANSFER
|
|
# output amount less than input amount
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(), [([alice.public_key], 50)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([user_sk])
|
|
|
|
with pytest.raises(AmountError):
|
|
tx_transfer_signed.validate(b)
|
|
|
|
# TRANSFER
|
|
# output amount greater than input amount
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(), [([alice.public_key], 101)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([user_sk])
|
|
|
|
with pytest.raises(AmountError):
|
|
tx_transfer_signed.validate(b)
|
|
|
|
|
|
def test_threshold_same_public_key(alice, b, user_pk, user_sk):
|
|
# If we try to fulfill a threshold condition where each subcondition has
|
|
# the same key get_subcondition_from_vk will always return the first
|
|
# subcondition. This means that only the 1st subfulfillment will be
|
|
# generated
|
|
# Creating threshold conditions with the same key does not make sense but
|
|
# that does not mean that the code shouldn't work.
|
|
|
|
# CREATE divisible asset
|
|
tx_create = Create.generate([alice.public_key], [([user_pk, user_pk], 100)],
|
|
asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# TRANSFER
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(), [([alice.public_key], 100)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([user_sk, user_sk])
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
|
|
|
b.store_bulk_transactions([tx_transfer_signed])
|
|
with pytest.raises(DoubleSpend):
|
|
tx_transfer_signed.validate(b)
|
|
|
|
|
|
def test_sum_amount(alice, b, user_pk, user_sk):
|
|
|
|
# CREATE divisible asset with 3 outputs with amount 1
|
|
tx_create = Create.generate([alice.public_key], [([user_pk], 1), ([user_pk], 1), ([user_pk], 1)],
|
|
asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# create a transfer transaction with one output and check if the amount
|
|
# is 3
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(), [([alice.public_key], 3)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([user_sk])
|
|
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
|
assert len(tx_transfer_signed.outputs) == 1
|
|
assert tx_transfer_signed.outputs[0].amount == 3
|
|
|
|
b.store_bulk_transactions([tx_transfer_signed])
|
|
with pytest.raises(DoubleSpend):
|
|
tx_transfer_signed.validate(b)
|
|
|
|
|
|
def test_divide(alice, b, user_pk, user_sk):
|
|
|
|
# CREATE divisible asset with 1 output with amount 3
|
|
tx_create = Create.generate([alice.public_key], [([user_pk], 3)], asset={'name': random.random()})
|
|
tx_create_signed = tx_create.sign([alice.private_key])
|
|
|
|
# create a transfer transaction with 3 outputs and check if the amount
|
|
# of each output is 1
|
|
tx_transfer = Transfer.generate(tx_create.to_inputs(),
|
|
[([alice.public_key], 1), ([alice.public_key], 1), ([alice.public_key], 1)],
|
|
asset_id=tx_create.id)
|
|
tx_transfer_signed = tx_transfer.sign([user_sk])
|
|
|
|
b.store_bulk_transactions([tx_create_signed])
|
|
|
|
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
|
assert len(tx_transfer_signed.outputs) == 3
|
|
for output in tx_transfer_signed.outputs:
|
|
assert output.amount == 1
|
|
|
|
b.store_bulk_transactions([tx_transfer_signed])
|
|
with pytest.raises(DoubleSpend):
|
|
tx_transfer_signed.validate(b)
|