mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-06-28 00:27:45 +02:00
Added support for divisible assets in TRANSFER transactions
Created tests
This commit is contained in:
parent
5b5c701e0a
commit
ee3b967184
|
@ -779,7 +779,7 @@ class Transaction(object):
|
|||
ffills = [Fulfillment(Ed25519Fulfillment(public_key=owner_before),
|
||||
[owner_before])
|
||||
for owner_before in owners_before]
|
||||
conds = [Condition.generate([owners], amount)
|
||||
conds = [Condition.generate([owners], amount)
|
||||
for owners in owners_after]
|
||||
return cls(cls.CREATE, asset, ffills, conds, metadata)
|
||||
|
||||
|
@ -857,20 +857,27 @@ class Transaction(object):
|
|||
if not isinstance(owners_after, list):
|
||||
raise TypeError('`owners_after` must be a list instance')
|
||||
|
||||
# NOTE: See doc strings `Note` for description.
|
||||
if len(inputs) == len(owners_after):
|
||||
if len(owners_after) == 1:
|
||||
conditions = [Condition.generate(owners_after)]
|
||||
elif len(owners_after) > 1:
|
||||
conditions = [Condition.generate(owners) for owners
|
||||
in owners_after]
|
||||
else:
|
||||
raise ValueError("`inputs` and `owners_after`'s count must be the "
|
||||
"same")
|
||||
# # NOTE: See doc strings `Note` for description.
|
||||
# if len(inputs) == len(owners_after):
|
||||
# if len(owners_after) == 1:
|
||||
# conditions = [Condition.generate(owners_after)]
|
||||
# elif len(owners_after) > 1:
|
||||
# conditions = [Condition.generate(owners) for owners
|
||||
# in owners_after]
|
||||
# else:
|
||||
# # TODO: Why??
|
||||
# raise ValueError("`inputs` and `owners_after`'s count must be the "
|
||||
# "same")
|
||||
|
||||
conds = []
|
||||
for owner_after in owners_after:
|
||||
pub_keys, amount = owner_after
|
||||
conds.append(Condition.generate(pub_keys, amount))
|
||||
|
||||
|
||||
metadata = Metadata(metadata)
|
||||
inputs = deepcopy(inputs)
|
||||
return cls(cls.TRANSFER, asset, inputs, conditions, metadata)
|
||||
return cls(cls.TRANSFER, asset, inputs, conds, metadata)
|
||||
|
||||
def __eq__(self, other):
|
||||
try:
|
||||
|
|
|
@ -551,7 +551,7 @@ class Bigchain(object):
|
|||
"""Prepare a genesis block."""
|
||||
|
||||
metadata = {'message': 'Hello World from the BigchainDB'}
|
||||
transaction = Transaction.create([self.me], [self.me],
|
||||
transaction = Transaction.create([self.me], [([self.me], 1)],
|
||||
metadata=metadata)
|
||||
|
||||
# NOTE: The transaction model doesn't expose an API to generate a
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import pytest
|
||||
|
||||
from ..db.conftest import inputs # noqa
|
||||
|
||||
|
||||
# CREATE divisible asset
|
||||
# Single input
|
||||
# Single owners_before
|
||||
# Single output
|
||||
# single owners_after
|
||||
# Single owners_after
|
||||
def test_single_in_single_own_single_out_single_own_create(b, user_vk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
@ -107,3 +109,163 @@ def test_single_in_multiple_own_single_out_single_own_create(b, user_vk):
|
|||
tx = Transaction.create([b.me, b.me], [([user_vk], 100)], asset=asset)
|
||||
tx_signed = tx.sign([b.me, b.me])
|
||||
assert tx_signed.validate(b) == tx_signed
|
||||
|
||||
|
||||
# TRANSFER divisible asset
|
||||
# Single input
|
||||
# Single owners_before
|
||||
# Single output
|
||||
# Single owners_after
|
||||
# TODO: I don't really need inputs. But I need the database to be setup or
|
||||
# else there will be no genesis block and b.get_last_voted_block will
|
||||
# fail.
|
||||
# Is there a better way of doing this?
|
||||
@pytest.mark.usefixtures('inputs')
|
||||
def test_single_in_single_own_single_out_single_own_transfer(b, user_vk,
|
||||
user_sk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset(divisible=True)
|
||||
tx_create = Transaction.create([b.me], [([user_vk], 100)], asset=asset)
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
assert block.validate(b) == block
|
||||
b.write_block(block, durability='hard')
|
||||
# vote
|
||||
vote = b.vote(block.id, b.get_last_voted_block().id, True)
|
||||
b.write_vote(vote)
|
||||
|
||||
# TRANSFER
|
||||
tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 100)],
|
||||
asset=tx_create.asset)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b)
|
||||
assert len(tx_transfer_signed.conditions) == 1
|
||||
assert tx_transfer_signed.conditions[0].amount == 100
|
||||
assert len(tx_transfer_signed.fulfillments) == 1
|
||||
|
||||
|
||||
# TRANSFER divisible asset
|
||||
# Single input
|
||||
# Single owners_before
|
||||
# Multiple output
|
||||
# Single owners_after
|
||||
@pytest.mark.usefixtures('inputs')
|
||||
def test_single_in_single_own_multiple_out_single_own_transfer(b, user_vk,
|
||||
user_sk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset(divisible=True)
|
||||
tx_create = Transaction.create([b.me], [([user_vk], 100)], asset=asset)
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
assert block.validate(b) == block
|
||||
b.write_block(block, durability='hard')
|
||||
# vote
|
||||
vote = b.vote(block.id, b.get_last_voted_block().id, True)
|
||||
b.write_vote(vote)
|
||||
|
||||
# TRANSFER
|
||||
tx_transfer = Transaction.transfer(tx_create.to_inputs(),
|
||||
[([b.me], 50), ([b.me], 50)],
|
||||
asset=tx_create.asset)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
assert len(tx_transfer_signed.conditions) == 2
|
||||
assert tx_transfer_signed.conditions[0].amount == 50
|
||||
assert tx_transfer_signed.conditions[1].amount == 50
|
||||
assert len(tx_transfer_signed.fulfillments) == 1
|
||||
|
||||
|
||||
# TRANSFER divisible asset
|
||||
# Single input
|
||||
# Single owners_before
|
||||
# Single output
|
||||
# Multiple owners_after
|
||||
@pytest.mark.usefixtures('inputs')
|
||||
def test_single_in_single_own_single_out_multiple_own_transfer(b, user_vk,
|
||||
user_sk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset(divisible=True)
|
||||
tx_create = Transaction.create([b.me], [([user_vk], 100)], asset=asset)
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
assert block.validate(b) == block
|
||||
b.write_block(block, durability='hard')
|
||||
# vote
|
||||
vote = b.vote(block.id, b.get_last_voted_block().id, True)
|
||||
b.write_vote(vote)
|
||||
|
||||
# TRANSFER
|
||||
tx_transfer = Transaction.transfer(tx_create.to_inputs(),
|
||||
[([b.me, b.me], 100)],
|
||||
asset=tx_create.asset)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
assert len(tx_transfer_signed.conditions) == 1
|
||||
assert tx_transfer_signed.conditions[0].amount == 100
|
||||
|
||||
condition = tx_transfer_signed.conditions[0].to_dict()
|
||||
assert 'subfulfillments' in condition['condition']['details']
|
||||
assert len(condition['condition']['details']['subfulfillments']) == 2
|
||||
|
||||
assert len(tx_transfer_signed.fulfillments) == 1
|
||||
|
||||
|
||||
# TRANSFER divisible asset
|
||||
# Single input
|
||||
# Single owners_before
|
||||
# Multiple outputs
|
||||
# Mix: one output with a single owners_after, one output with multiple
|
||||
# owners_after
|
||||
@pytest.mark.usefixtures('inputs')
|
||||
def test_single_in_single_own_multiple_out_mix_own_transfer(b, user_vk,
|
||||
user_sk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset(divisible=True)
|
||||
tx_create = Transaction.create([b.me], [([user_vk], 100)], asset=asset)
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
assert block.validate(b) == block
|
||||
b.write_block(block, durability='hard')
|
||||
# vote
|
||||
vote = b.vote(block.id, b.get_last_voted_block().id, True)
|
||||
b.write_vote(vote)
|
||||
|
||||
# TRANSFER
|
||||
tx_transfer = Transaction.transfer(tx_create.to_inputs(),
|
||||
[([b.me], 50), ([b.me, b.me], 50)],
|
||||
asset=tx_create.asset)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
assert len(tx_transfer_signed.conditions) == 2
|
||||
assert tx_transfer_signed.conditions[0].amount == 50
|
||||
assert tx_transfer_signed.conditions[1].amount == 50
|
||||
|
||||
condition_cid1 = tx_transfer_signed.conditions[1].to_dict()
|
||||
assert 'subfulfillments' in condition_cid1['condition']['details']
|
||||
assert len(condition_cid1['condition']['details']['subfulfillments']) == 2
|
||||
|
||||
assert len(tx_transfer_signed.fulfillments) == 1
|
||||
|
||||
|
||||
#def test_single_in_multiple_own_single_out_single_own_create(b, user_vk):
|
||||
#test input output amount mismatch. Both when output is less and greater then input
|
||||
|
|
|
@ -119,7 +119,7 @@ def inputs(user_vk):
|
|||
prev_block_id = g.id
|
||||
for block in range(4):
|
||||
transactions = [
|
||||
Transaction.create([b.me], [user_vk]).sign([b.me_private])
|
||||
Transaction.create([b.me], [([user_vk], 1)]).sign([b.me_private])
|
||||
for i in range(10)
|
||||
]
|
||||
block = b.create_block(transactions)
|
||||
|
|
Loading…
Reference in New Issue
Block a user