started replacing asset with assets

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
This commit is contained in:
Lorenz Herzberger 2022-04-06 00:35:12 +02:00
parent 5fd8bde123
commit 6c34180b39
No known key found for this signature in database
GPG Key ID: FA5EE906EB55316A
23 changed files with 112 additions and 93 deletions

View File

@ -135,8 +135,8 @@ def main():
# tx create # tx create
privkey = 'CfdqtD7sS7FgkMoGPXw55MVGGFwQLAoHYTcBhZDtF99Z' privkey = 'CfdqtD7sS7FgkMoGPXw55MVGGFwQLAoHYTcBhZDtF99Z'
pubkey = '4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD' pubkey = '4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD'
asset = {'msg': 'Hello Planetmint!'} assets = [{'msg': 'Hello Planetmint!'}]
tx = Create.generate([pubkey], [([pubkey], 1)], asset=asset, metadata={'sequence': 0}) tx = Create.generate([pubkey], [([pubkey], 1)], assets=assets, metadata={'sequence': 0})
tx = tx.sign([privkey]) tx = tx.sign([privkey])
ctx['tx'] = pretty_json(tx.to_dict()) ctx['tx'] = pretty_json(tx.to_dict())
ctx['public_keys'] = tx.outputs[0].public_keys[0] ctx['public_keys'] = tx.outputs[0].public_keys[0]

View File

@ -130,9 +130,10 @@ class Planetmint(object):
for t in transactions: for t in transactions:
transaction = t.tx_dict if t.tx_dict else rapidjson.loads(rapidjson.dumps(t.to_dict())) transaction = t.tx_dict if t.tx_dict else rapidjson.loads(rapidjson.dumps(t.to_dict()))
if transaction['operation'] == t.CREATE: if transaction['operation'] == t.CREATE:
asset = transaction.pop('asset') # Change this to use the first element of the assets list or to change to use the assets array itsel and manipulate it
asset['id'] = transaction['id'] tx_assets = transaction.pop('assets')
assets.append(asset) tx_assets[0]['id'] = transaction['id']
assets.extend(tx_assets)
metadata = transaction.pop('metadata') metadata = transaction.pop('metadata')
txn_metadatas.append({'id': transaction['id'], txn_metadatas.append({'id': transaction['id'],

View File

@ -27,7 +27,7 @@ def _load_schema(name, version, path=__file__):
# TODO: make this an env var from a config file # TODO: make this an env var from a config file
TX_SCHEMA_VERSION = 'v2.0' TX_SCHEMA_VERSION = 'v3.0'
TX_SCHEMA_PATH, TX_SCHEMA_COMMON = _load_schema('transaction', TX_SCHEMA_PATH, TX_SCHEMA_COMMON = _load_schema('transaction',
TX_SCHEMA_VERSION) TX_SCHEMA_VERSION)

View File

@ -75,7 +75,7 @@ class Transaction(object):
ALLOWED_OPERATIONS = (CREATE, TRANSFER) ALLOWED_OPERATIONS = (CREATE, TRANSFER)
VERSION = '2.0' VERSION = '2.0'
def __init__(self, operation, asset, inputs=None, outputs=None, def __init__(self, operation, assets, inputs=None, outputs=None,
metadata=None, version=None, hash_id=None, tx_dict=None): metadata=None, version=None, hash_id=None, tx_dict=None):
"""The constructor allows to create a customizable Transaction. """The constructor allows to create a customizable Transaction.
@ -104,12 +104,18 @@ class Transaction(object):
# Asset payloads for 'CREATE' operations must be None or # Asset payloads for 'CREATE' operations must be None or
# dicts holding a `data` property. Asset payloads for 'TRANSFER' # dicts holding a `data` property. Asset payloads for 'TRANSFER'
# operations must be dicts holding an `id` property. # operations must be dicts holding an `id` property.
# Changes: CREATE needs list of 1 asset that holds data in asset or None
if (operation == self.CREATE and if (operation == self.CREATE and
asset is not None and not (isinstance(asset, dict) and 'data' in asset)): assets is not None and not (isinstance(assets, list) and 'data' in assets[0])):
raise TypeError(('`asset` must be None or a dict holding a `data` ' raise TypeError(('`asset` must be None or a list of length 1 with a dict holding a `data` '
" property instance for '{}' Transactions".format(operation))) " property instance for '{}' Transactions".format(operation)))
# if (operation == self.CREATE and
# asset is not None and not (isinstance(asset, dict) and 'data' in asset)):
# raise TypeError(('`asset` must be None or a dict holding a `data` '
# " property instance for '{}' Transactions".format(operation)))
elif (operation == self.TRANSFER and elif (operation == self.TRANSFER and
not (isinstance(asset, dict) and 'id' in asset)): not (isinstance(assets, dict) and 'id' in assets)):
raise TypeError(('`asset` must be a dict holding an `id` property ' raise TypeError(('`asset` must be a dict holding an `id` property '
'for \'TRANSFER\' Transactions')) 'for \'TRANSFER\' Transactions'))
@ -124,7 +130,7 @@ class Transaction(object):
self.version = version if version is not None else self.VERSION self.version = version if version is not None else self.VERSION
self.operation = operation self.operation = operation
self.asset = asset self.assets = assets
self.inputs = inputs or [] self.inputs = inputs or []
self.outputs = outputs or [] self.outputs = outputs or []
self.metadata = metadata self.metadata = metadata
@ -512,7 +518,7 @@ class Transaction(object):
'outputs': [output.to_dict() for output in self.outputs], 'outputs': [output.to_dict() for output in self.outputs],
'operation': str(self.operation), 'operation': str(self.operation),
'metadata': self.metadata, 'metadata': self.metadata,
'asset': self.asset, 'assets': [asset for asset in self.assets],
'version': self.version, 'version': self.version,
'id': self._id, 'id': self._id,
} }
@ -585,14 +591,22 @@ class Transaction(object):
transactions = [transactions] transactions = [transactions]
# create a set of the transactions' asset ids # create a set of the transactions' asset ids
asset_ids = {tx.id if tx.operation == tx.CREATE # NOTE: gather asset ids constraint no longer valid with v3.0
else tx.asset['id'] # asset_ids = {tx.id if tx.operation == tx.CREATE
for tx in transactions} # else tx.asset['id']
# for tx in transactions}
# # check that all the transasctions have the same asset id
# if len(asset_ids) > 1:
# raise AssetIdMismatch(('All inputs of all transactions passed'
# ' need to have the same asset id'))
asset_ids = []
for tx in transactions:
if tx.operation == tx.CREATE:
asset_ids.append(tx.assets[0]['id'])
else:
asset_ids.extend([asset['id'] for asset in tx.assets])
# check that all the transasctions have the same asset id
if len(asset_ids) > 1:
raise AssetIdMismatch(('All inputs of all transactions passed'
' need to have the same asset id'))
return asset_ids.pop() return asset_ids.pop()
@staticmethod @staticmethod

View File

@ -22,8 +22,11 @@ class Create(Transaction):
raise ValueError('`tx_signers` list cannot be empty') raise ValueError('`tx_signers` list cannot be empty')
if len(recipients) == 0: if len(recipients) == 0:
raise ValueError('`recipients` list cannot be empty') raise ValueError('`recipients` list cannot be empty')
if not (asset is None or isinstance(asset, dict)): if not (asset is None or isinstance(asset, list)):
raise TypeError('`asset` must be a dict or None') raise TypeError('`asset` must be a list or None')
if isinstance(asset, dict):
if len(asset) != 1:
raise ValueError('`asset` must be of length 1')
if not (metadata is None or isinstance(metadata, dict)): if not (metadata is None or isinstance(metadata, dict)):
raise TypeError('`metadata` must be a dict or None') raise TypeError('`metadata` must be a dict or None')
@ -45,7 +48,7 @@ class Create(Transaction):
return (inputs, outputs) return (inputs, outputs)
@classmethod @classmethod
def generate(cls, tx_signers, recipients, metadata=None, asset=None): def generate(cls, tx_signers, recipients, metadata=None, assets=None):
"""A simple way to generate a `CREATE` transaction. """A simple way to generate a `CREATE` transaction.
Note: Note:
@ -73,5 +76,6 @@ class Create(Transaction):
:class:`~planetmint.common.transaction.Transaction` :class:`~planetmint.common.transaction.Transaction`
""" """
(inputs, outputs) = cls.validate_create(tx_signers, recipients, asset, metadata) (inputs, outputs) = cls.validate_create(tx_signers, recipients, assets, metadata)
return cls(cls.OPERATION, {'data': asset}, inputs, outputs, metadata) data = assets[0] if assets else None
return cls(cls.OPERATION, [{'data': data}], inputs, outputs, metadata) # if assets is not None len(assets) must be 1

View File

@ -160,7 +160,7 @@ class Election(Transaction):
@classmethod @classmethod
def create(cls, tx_signers, recipients, metadata=None, asset=None): def create(cls, tx_signers, recipients, metadata=None, asset=None):
Create.generate(tx_signers, recipients, metadata=None, asset=None) Create.generate(tx_signers, recipients, metadata=None, assets=None)
@classmethod @classmethod
def transfer(cls, tx_signers, recipients, metadata=None, asset=None): def transfer(cls, tx_signers, recipients, metadata=None, asset=None):

View File

@ -56,7 +56,7 @@ class Vote(Transfer):
@classmethod @classmethod
def create(cls, tx_signers, recipients, metadata=None, asset=None): def create(cls, tx_signers, recipients, metadata=None, asset=None):
return Create.generate(tx_signers, recipients, metadata=None, asset=None) return Create.generate(tx_signers, recipients, metadata=None, assets=None)
@classmethod @classmethod
def transfer(cls, tx_signers, recipients, metadata=None, asset=None): def transfer(cls, tx_signers, recipients, metadata=None, asset=None):

View File

@ -19,7 +19,7 @@ from planetmint.transactions.common.exceptions import DoubleSpend
# Single owners_after # Single owners_after
def test_single_in_single_own_single_out_single_own_create(alice, user_pk, b): 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 = Create.generate([alice.public_key], [([user_pk], 100)], assets=[{'name': random.random()}])
tx_signed = tx.sign([alice.private_key]) tx_signed = tx.sign([alice.private_key])
assert tx_signed.validate(b) == tx_signed assert tx_signed.validate(b) == tx_signed
@ -36,7 +36,7 @@ def test_single_in_single_own_single_out_single_own_create(alice, user_pk, b):
def test_single_in_single_own_multiple_out_single_own_create(alice, user_pk, b): 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)], tx = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk], 50)],
asset={'name': random.random()}) assets=[{'name': random.random()}])
tx_signed = tx.sign([alice.private_key]) tx_signed = tx.sign([alice.private_key])
assert tx_signed.validate(b) == tx_signed assert tx_signed.validate(b) == tx_signed
@ -53,7 +53,7 @@ def test_single_in_single_own_multiple_out_single_own_create(alice, user_pk, b):
# Multiple owners_after # Multiple owners_after
def test_single_in_single_own_single_out_multiple_own_create(alice, user_pk, b): 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 = Create.generate([alice.public_key], [([user_pk, user_pk], 100)], assets=[{'name': random.random()}])
tx_signed = tx.sign([alice.private_key]) tx_signed = tx.sign([alice.private_key])
assert tx_signed.validate(b) == tx_signed assert tx_signed.validate(b) == tx_signed
@ -76,7 +76,7 @@ def test_single_in_single_own_single_out_multiple_own_create(alice, user_pk, b):
def test_single_in_single_own_multiple_out_mix_own_create(alice, user_pk, b): 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)], tx = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk, user_pk], 50)],
asset={'name': random.random()}) assets=[{'name': random.random()}])
tx_signed = tx.sign([alice.private_key]) tx_signed = tx.sign([alice.private_key])
assert tx_signed.validate(b) == tx_signed assert tx_signed.validate(b) == tx_signed
@ -99,7 +99,7 @@ def test_single_in_multiple_own_single_out_single_own_create(alice, b, user_pk,
user_sk): user_sk):
from planetmint.transactions.common.utils import _fulfillment_to_details 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 = Create.generate([alice.public_key, user_pk], [([user_pk], 100)], assets=[{'name': random.random()}])
tx_signed = tx.sign([alice.private_key, user_sk]) tx_signed = tx.sign([alice.private_key, user_sk])
assert tx_signed.validate(b) == tx_signed assert tx_signed.validate(b) == tx_signed
assert len(tx_signed.outputs) == 1 assert len(tx_signed.outputs) == 1
@ -120,7 +120,7 @@ def test_single_in_single_own_single_out_single_own_transfer(alice, b, user_pk,
user_sk): user_sk):
# CREATE divisible asset # CREATE divisible asset
tx_create = Create.generate([alice.public_key], [([user_pk], 100)], asset={'name': random.random()}) tx_create = Create.generate([alice.public_key], [([user_pk], 100)], assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# TRANSFER # TRANSFER
@ -145,7 +145,7 @@ def test_single_in_single_own_multiple_out_single_own_transfer(alice, b, user_pk
user_sk): user_sk):
# CREATE divisible asset # CREATE divisible asset
tx_create = Create.generate([alice.public_key], [([user_pk], 100)], asset={'name': random.random()}) tx_create = Create.generate([alice.public_key], [([user_pk], 100)], assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# TRANSFER # TRANSFER
@ -172,7 +172,7 @@ def test_single_in_single_own_single_out_multiple_own_transfer(alice, b, user_pk
user_sk): user_sk):
# CREATE divisible asset # CREATE divisible asset
tx_create = Create.generate([alice.public_key], [([user_pk], 100)], asset={'name': random.random()}) tx_create = Create.generate([alice.public_key], [([user_pk], 100)], assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# TRANSFER # TRANSFER
@ -208,7 +208,7 @@ def test_single_in_single_own_multiple_out_mix_own_transfer(alice, b, user_pk,
user_sk): user_sk):
# CREATE divisible asset # CREATE divisible asset
tx_create = Create.generate([alice.public_key], [([user_pk], 100)], asset={'name': random.random()}) tx_create = Create.generate([alice.public_key], [([user_pk], 100)], assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# TRANSFER # TRANSFER
@ -246,7 +246,7 @@ def test_single_in_multiple_own_single_out_single_own_transfer(alice, b, user_pk
# CREATE divisible asset # CREATE divisible asset
tx_create = Create.generate([alice.public_key], [([alice.public_key, user_pk], 100)], tx_create = Create.generate([alice.public_key], [([alice.public_key, user_pk], 100)],
asset={'name': random.random()}) assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# TRANSFER # TRANSFER
@ -279,7 +279,7 @@ def test_multiple_in_single_own_single_out_single_own_transfer(alice, b, user_pk
user_sk): user_sk):
# CREATE divisible asset # CREATE divisible asset
tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk], 50)], tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk], 50)],
asset={'name': random.random()}) assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# TRANSFER # TRANSFER
@ -311,7 +311,7 @@ def test_multiple_in_multiple_own_single_out_single_own_transfer(alice, b, user_
# CREATE divisible asset # CREATE divisible asset
tx_create = Create.generate([alice.public_key], [([user_pk, alice.public_key], 50), tx_create = Create.generate([alice.public_key], [([user_pk, alice.public_key], 50),
([user_pk, alice.public_key], 50)], ([user_pk, alice.public_key], 50)],
asset={'name': random.random()}) assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# TRANSFER # TRANSFER
@ -350,7 +350,7 @@ def test_muiltiple_in_mix_own_multiple_out_single_own_transfer(alice, b, user_pk
# CREATE divisible asset # CREATE divisible asset
tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk, alice.public_key], 50)], tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk, alice.public_key], 50)],
asset={'name': random.random()}) assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# TRANSFER # TRANSFER
@ -389,7 +389,7 @@ def test_muiltiple_in_mix_own_multiple_out_mix_own_transfer(alice, b, user_pk,
# CREATE divisible asset # CREATE divisible asset
tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk, alice.public_key], 50)], tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([user_pk, alice.public_key], 50)],
asset={'name': random.random()}) assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# TRANSFER # TRANSFER
@ -434,7 +434,7 @@ def test_multiple_in_different_transactions(alice, b, user_pk, user_sk):
# `b` creates a divisible asset and assigns 50 shares to `b` and # `b` creates a divisible asset and assigns 50 shares to `b` and
# 50 shares to `user_pk` # 50 shares to `user_pk`
tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([alice.public_key], 50)], tx_create = Create.generate([alice.public_key], [([user_pk], 50), ([alice.public_key], 50)],
asset={'name': random.random()}) assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# TRANSFER divisible asset # TRANSFER divisible asset
@ -475,7 +475,7 @@ def test_amount_error_transfer(alice, b, user_pk, user_sk):
from planetmint.transactions.common.exceptions import AmountError from planetmint.transactions.common.exceptions import AmountError
# CREATE divisible asset # CREATE divisible asset
tx_create = Create.generate([alice.public_key], [([user_pk], 100)], asset={'name': random.random()}) tx_create = Create.generate([alice.public_key], [([user_pk], 100)], assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
b.store_bulk_transactions([tx_create_signed]) b.store_bulk_transactions([tx_create_signed])
@ -509,7 +509,7 @@ def test_threshold_same_public_key(alice, b, user_pk, user_sk):
# CREATE divisible asset # CREATE divisible asset
tx_create = Create.generate([alice.public_key], [([user_pk, user_pk], 100)], tx_create = Create.generate([alice.public_key], [([user_pk, user_pk], 100)],
asset={'name': random.random()}) assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# TRANSFER # TRANSFER
@ -530,7 +530,7 @@ def test_sum_amount(alice, b, user_pk, user_sk):
# CREATE divisible asset with 3 outputs with amount 1 # 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)], tx_create = Create.generate([alice.public_key], [([user_pk], 1), ([user_pk], 1), ([user_pk], 1)],
asset={'name': random.random()}) assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# create a transfer transaction with one output and check if the amount # create a transfer transaction with one output and check if the amount
@ -553,7 +553,7 @@ def test_sum_amount(alice, b, user_pk, user_sk):
def test_divide(alice, b, user_pk, user_sk): def test_divide(alice, b, user_pk, user_sk):
# CREATE divisible asset with 1 output with amount 3 # 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 = Create.generate([alice.public_key], [([user_pk], 3)], assets=[{'name': random.random()}])
tx_create_signed = tx_create.sign([alice.private_key]) tx_create_signed = tx_create.sign([alice.private_key])
# create a transfer transaction with 3 outputs and check if the amount # create a transfer transaction with 3 outputs and check if the amount

View File

@ -265,12 +265,12 @@ def test_run_recover(b, alice, bob):
tx1 = Create.generate([alice.public_key], tx1 = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset={'cycle': 'hero'}, assets={'cycle': 'hero'},
metadata={'name': 'hohenheim'}) \ metadata={'name': 'hohenheim'}) \
.sign([alice.private_key]) .sign([alice.private_key])
tx2 = Create.generate([bob.public_key], tx2 = Create.generate([bob.public_key],
[([bob.public_key], 1)], [([bob.public_key], 1)],
asset={'cycle': 'hero'}, assets={'cycle': 'hero'},
metadata={'name': 'hohenheim'}) \ metadata={'name': 'hohenheim'}) \
.sign([bob.private_key]) .sign([bob.private_key])

View File

@ -26,7 +26,7 @@ def test_memoize_to_dict(b):
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=asset,)\ assets=asset,)\
.sign([alice.private_key]) .sign([alice.private_key])
tx.to_dict() tx.to_dict()
@ -52,7 +52,7 @@ def test_memoize_from_dict(b):
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=asset,)\ assets=asset,)\
.sign([alice.private_key]) .sign([alice.private_key])
tx_dict = deepcopy(tx.to_dict()) tx_dict = deepcopy(tx.to_dict())
@ -79,7 +79,7 @@ def test_memoize_input_valid(b):
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=asset,)\ assets=asset,)\
.sign([alice.private_key]) .sign([alice.private_key])
tx.inputs_valid() tx.inputs_valid()

View File

@ -278,28 +278,28 @@ def test_invalid_transaction_initialization(asset_definition):
from planetmint.transactions.common.transaction import Transaction from planetmint.transactions.common.transaction import Transaction
with raises(ValueError): with raises(ValueError):
Transaction(operation='invalid operation', asset=asset_definition) Transaction(operation='invalid operation', assets=asset_definition)
with raises(TypeError): with raises(TypeError):
Transaction(operation='CREATE', asset='invalid asset') Transaction(operation='CREATE', assets='invalid asset')
with raises(TypeError): with raises(TypeError):
Transaction(operation='TRANSFER', asset={}) Transaction(operation='TRANSFER', assets={})
with raises(TypeError): with raises(TypeError):
Transaction( Transaction(
operation='CREATE', operation='CREATE',
asset=asset_definition, assets=asset_definition,
outputs='invalid outputs' outputs='invalid outputs'
) )
with raises(TypeError): with raises(TypeError):
Transaction( Transaction(
operation='CREATE', operation='CREATE',
asset=asset_definition, assets=asset_definition,
outputs=[], outputs=[],
inputs='invalid inputs' inputs='invalid inputs'
) )
with raises(TypeError): with raises(TypeError):
Transaction( Transaction(
operation='CREATE', operation='CREATE',
asset=asset_definition, assets=asset_definition,
outputs=[], outputs=[],
inputs=[], inputs=[],
metadata='invalid metadata' metadata='invalid metadata'
@ -310,7 +310,7 @@ def test_create_default_asset_on_tx_initialization(asset_definition):
from planetmint.transactions.common.transaction import Transaction from planetmint.transactions.common.transaction import Transaction
expected = {'data': None} expected = {'data': None}
tx = Transaction(Transaction.CREATE, asset=expected) tx = Transaction(Transaction.CREATE, assets=expected)
asset = tx.asset asset = tx.asset
assert asset == expected assert asset == expected
@ -693,7 +693,7 @@ def test_create_create_transaction_single_io(user_output, user_pub, data):
} }
tx = Create.generate([user_pub], [([user_pub], 1)], metadata=data, tx = Create.generate([user_pub], [([user_pub], 1)], metadata=data,
asset=data) assets=data)
tx_dict = tx.to_dict() tx_dict = tx.to_dict()
tx_dict['inputs'][0]['fulfillment'] = None tx_dict['inputs'][0]['fulfillment'] = None
tx_dict.pop('id') tx_dict.pop('id')
@ -775,7 +775,7 @@ def test_create_create_transaction_threshold(user_pub, user2_pub, user3_pub,
'version': Transaction.VERSION 'version': Transaction.VERSION
} }
tx = Create.generate([user_pub], [([user_pub, user2_pub], 1)], tx = Create.generate([user_pub], [([user_pub, user2_pub], 1)],
metadata=data, asset=data) metadata=data, assets=data)
tx_dict = tx.to_dict() tx_dict = tx.to_dict()
tx_dict.pop('id') tx_dict.pop('id')
tx_dict['inputs'][0]['fulfillment'] = None tx_dict['inputs'][0]['fulfillment'] = None
@ -814,7 +814,7 @@ def test_create_create_transaction_with_invalid_parameters(user_pub):
with raises(TypeError): with raises(TypeError):
Create.generate([user_pub], Create.generate([user_pub],
[([user_pub], 1)], [([user_pub], 1)],
asset='not a dict or none') assets='not a dict or none')
def test_outputs_to_inputs(tx): def test_outputs_to_inputs(tx):
@ -1019,7 +1019,7 @@ def test_unspent_outputs_property(merlin, alice, bob, carol):
[([alice.public_key], 1), [([alice.public_key], 1),
([bob.public_key], 2), ([bob.public_key], 2),
([carol.public_key], 3)], ([carol.public_key], 3)],
asset={'hash': '06e47bcf9084f7ecfd2a2a2ad275444a'}, assets={'hash': '06e47bcf9084f7ecfd2a2a2ad275444a'},
).sign([merlin.private_key]) ).sign([merlin.private_key])
unspent_outputs = list(tx.unspent_outputs) unspent_outputs = list(tx.unspent_outputs)
assert len(unspent_outputs) == 3 assert len(unspent_outputs) == 3

View File

@ -287,7 +287,7 @@ def mock_get_validators(network_validators):
def create_tx(alice, user_pk): def create_tx(alice, user_pk):
from planetmint.transactions.types.assets.create import Create from planetmint.transactions.types.assets.create import Create
name = f'I am created by the create_tx fixture. My random identifier is {random.random()}.' name = f'I am created by the create_tx fixture. My random identifier is {random.random()}.'
return Create.generate([alice.public_key], [([user_pk], 1)], asset={'name': name}) return Create.generate([alice.public_key], [([user_pk], 1)], assets=[{'name': name}])
@pytest.fixture @pytest.fixture

View File

@ -64,11 +64,11 @@ class TestBigchainApi(object):
# create the transactions # create the transactions
tx1 = Create.generate([alice.public_key], [([alice.public_key], 1)], tx1 = Create.generate([alice.public_key], [([alice.public_key], 1)],
asset=asset1).sign([alice.private_key]) assets=asset1).sign([alice.private_key])
tx2 = Create.generate([alice.public_key], [([alice.public_key], 1)], tx2 = Create.generate([alice.public_key], [([alice.public_key], 1)],
asset=asset2).sign([alice.private_key]) assets=asset2).sign([alice.private_key])
tx3 = Create.generate([alice.public_key], [([alice.public_key], 1)], tx3 = Create.generate([alice.public_key], [([alice.public_key], 1)],
asset=asset3).sign([alice.private_key]) assets=asset3).sign([alice.private_key])
# write the transactions to the DB # write the transactions to the DB
b.store_bulk_transactions([tx1, tx2, tx3]) b.store_bulk_transactions([tx1, tx2, tx3])
@ -97,7 +97,7 @@ class TestBigchainApi(object):
asset1 = {'msg': 'Planetmint 1'} asset1 = {'msg': 'Planetmint 1'}
tx = Create.generate([alice.public_key], [([alice.public_key], 1)], tx = Create.generate([alice.public_key], [([alice.public_key], 1)],
asset=asset1).sign([alice.private_key]) assets=asset1).sign([alice.private_key])
b.store_bulk_transactions([tx]) b.store_bulk_transactions([tx])
tx_from_db = b.get_transaction(tx.id) tx_from_db = b.get_transaction(tx.id)

View File

@ -318,7 +318,7 @@ def test_deliver_transfer_tx__double_spend_fails(b, init_chain_request):
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=asset)\ assets=asset)\
.sign([alice.private_key]) .sign([alice.private_key])
result = app.deliver_tx(encode_tx_to_bytes(tx)) result = app.deliver_tx(encode_tx_to_bytes(tx))
@ -382,7 +382,7 @@ def test_store_pre_commit_state_in_end_block(b, alice, init_chain_request):
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset={'msg': 'live long and prosper'})\ assets={'msg': 'live long and prosper'})\
.sign([alice.private_key]) .sign([alice.private_key])
app = App(b) app = App(b)

View File

@ -120,7 +120,7 @@ def test_post_transaction_responses(tendermint_ws_url, b):
bob = generate_key_pair() bob = generate_key_pair()
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=None)\ assets=None)\
.sign([alice.private_key]) .sign([alice.private_key])
code, message = b.write_transaction(tx, BROADCAST_TX_COMMIT) code, message = b.write_transaction(tx, BROADCAST_TX_COMMIT)

View File

@ -44,7 +44,7 @@ def test_asset_is_separated_from_transaciton(b):
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([bob.public_key], 1)], [([bob.public_key], 1)],
metadata=None, metadata=None,
asset=asset)\ assets=asset)\
.sign([alice.private_key]) .sign([alice.private_key])
# with store_bulk_transactions we use `insert_many` where PyMongo # with store_bulk_transactions we use `insert_many` where PyMongo
@ -87,7 +87,7 @@ def test_validation_error(b):
alice = generate_key_pair() alice = generate_key_pair()
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=None)\ assets=None)\
.sign([alice.private_key]).to_dict() .sign([alice.private_key]).to_dict()
tx['metadata'] = '' tx['metadata'] = ''
@ -102,7 +102,7 @@ def test_write_and_post_transaction(mock_post, b):
alice = generate_key_pair() alice = generate_key_pair()
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=None)\ assets=None)\
.sign([alice.private_key]).to_dict() .sign([alice.private_key]).to_dict()
tx = b.validate_transaction(tx) tx = b.validate_transaction(tx)
@ -126,7 +126,7 @@ def test_post_transaction_valid_modes(mock_post, b, mode):
alice = generate_key_pair() alice = generate_key_pair()
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=None) \ assets=None) \
.sign([alice.private_key]).to_dict() .sign([alice.private_key]).to_dict()
tx = b.validate_transaction(tx) tx = b.validate_transaction(tx)
b.write_transaction(tx, mode) b.write_transaction(tx, mode)
@ -141,7 +141,7 @@ def test_post_transaction_invalid_mode(b):
alice = generate_key_pair() alice = generate_key_pair()
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=None) \ assets=None) \
.sign([alice.private_key]).to_dict() .sign([alice.private_key]).to_dict()
tx = b.validate_transaction(tx) tx = b.validate_transaction(tx)
with pytest.raises(ValidationError): with pytest.raises(ValidationError):
@ -358,7 +358,7 @@ def test_get_spent_transaction_critical_double_spend(b, alice, bob, carol):
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=asset)\ assets=asset)\
.sign([alice.private_key]) .sign([alice.private_key])
tx_transfer = Transfer.generate(tx.to_inputs(), tx_transfer = Transfer.generate(tx.to_inputs(),
@ -462,7 +462,7 @@ def test_get_spent_key_order(b, user_pk, user_sk, user2_pk, user2_sk):
tx1 = Create.generate([user_pk], tx1 = Create.generate([user_pk],
[([alice.public_key], 3), ([user_pk], 2)], [([alice.public_key], 3), ([user_pk], 2)],
asset=None)\ assets=None)\
.sign([user_sk]) .sign([user_sk])
b.store_bulk_transactions([tx1]) b.store_bulk_transactions([tx1])

View File

@ -318,7 +318,7 @@ def test_deliver_transfer_tx__double_spend_fails(b, init_chain_request):
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=asset)\ assets=asset)\
.sign([alice.private_key]) .sign([alice.private_key])
result = app.deliver_tx(encode_tx_to_bytes(tx)) result = app.deliver_tx(encode_tx_to_bytes(tx))
@ -382,7 +382,7 @@ def test_store_pre_commit_state_in_end_block(b, alice, init_chain_request):
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset={'msg': 'live long and prosper'})\ assets={'msg': 'live long and prosper'})\
.sign([alice.private_key]) .sign([alice.private_key])
app = App(b) app = App(b)

View File

@ -35,7 +35,7 @@ def generate_block(planet):
alice = generate_key_pair() alice = generate_key_pair()
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=None)\ assets=None)\
.sign([alice.private_key]) .sign([alice.private_key])
code, message = planet.write_transaction(tx, BROADCAST_TX_COMMIT) code, message = planet.write_transaction(tx, BROADCAST_TX_COMMIT)

View File

@ -32,7 +32,7 @@ def test_get_assets_tendermint(client, b, alice):
# create asset # create asset
asset = {'msg': 'abc'} asset = {'msg': 'abc'}
tx = Create.generate([alice.public_key], [([alice.public_key], 1)], tx = Create.generate([alice.public_key], [([alice.public_key], 1)],
asset=asset).sign([alice.private_key]) assets=asset).sign([alice.private_key])
b.store_bulk_transactions([tx]) b.store_bulk_transactions([tx])
@ -53,9 +53,9 @@ def test_get_assets_limit_tendermint(client, b, alice):
asset1 = {'msg': 'abc 1'} asset1 = {'msg': 'abc 1'}
asset2 = {'msg': 'abc 2'} asset2 = {'msg': 'abc 2'}
tx1 = Create.generate([alice.public_key], [([alice.public_key], 1)], tx1 = Create.generate([alice.public_key], [([alice.public_key], 1)],
asset=asset1).sign([alice.private_key]) assets=asset1).sign([alice.private_key])
tx2 = Create.generate([alice.public_key], [([alice.public_key], 1)], tx2 = Create.generate([alice.public_key], [([alice.public_key], 1)],
asset=asset2).sign([alice.private_key]) assets=asset2).sign([alice.private_key])
b.store_bulk_transactions([tx1]) b.store_bulk_transactions([tx1])
b.store_bulk_transactions([tx2]) b.store_bulk_transactions([tx2])

View File

@ -15,7 +15,7 @@ BLOCKS_ENDPOINT = '/api/v1/blocks/'
@pytest.mark.usefixtures('inputs') @pytest.mark.usefixtures('inputs')
def test_get_block_endpoint(b, client, alice): def test_get_block_endpoint(b, client, alice):
import copy import copy
tx = Create.generate([alice.public_key], [([alice.public_key], 1)], asset={'cycle': 'hero'}) tx = Create.generate([alice.public_key], [([alice.public_key], 1)], assets={'cycle': 'hero'})
tx = tx.sign([alice.private_key]) tx = tx.sign([alice.private_key])
# with store_bulk_transactions we use `insert_many` where PyMongo # with store_bulk_transactions we use `insert_many` where PyMongo
@ -48,7 +48,7 @@ def test_get_block_returns_404_if_not_found(client):
@pytest.mark.bdb @pytest.mark.bdb
def test_get_block_containing_transaction(b, client, alice): def test_get_block_containing_transaction(b, client, alice):
tx = Create.generate([alice.public_key], [([alice.public_key], 1)], asset={'cycle': 'hero'}) tx = Create.generate([alice.public_key], [([alice.public_key], 1)], assets={'cycle': 'hero'})
tx = tx.sign([alice.private_key]) tx = tx.sign([alice.private_key])
b.store_bulk_transactions([tx]) b.store_bulk_transactions([tx])

View File

@ -33,7 +33,7 @@ def test_get_metadata_tendermint(client, b, alice):
asset = {'msg': 'abc'} asset = {'msg': 'abc'}
metadata = {'key': 'my_meta'} metadata = {'key': 'my_meta'}
tx = Create.generate([alice.public_key], [([alice.public_key], 1)], metadata=metadata, tx = Create.generate([alice.public_key], [([alice.public_key], 1)], metadata=metadata,
asset=asset).sign([alice.private_key]) assets=asset).sign([alice.private_key])
b.store_bulk_transactions([tx]) b.store_bulk_transactions([tx])
@ -54,13 +54,13 @@ def test_get_metadata_limit_tendermint(client, b, alice):
asset1 = {'msg': 'abc 1'} asset1 = {'msg': 'abc 1'}
meta1 = {'key': 'meta 1'} meta1 = {'key': 'meta 1'}
tx1 = Create.generate([alice.public_key], [([alice.public_key], 1)], metadata=meta1, tx1 = Create.generate([alice.public_key], [([alice.public_key], 1)], metadata=meta1,
asset=asset1).sign([alice.private_key]) assets=asset1).sign([alice.private_key])
b.store_bulk_transactions([tx1]) b.store_bulk_transactions([tx1])
asset2 = {'msg': 'abc 2'} asset2 = {'msg': 'abc 2'}
meta2 = {'key': 'meta 2'} meta2 = {'key': 'meta 2'}
tx2 = Create.generate([alice.public_key], [([alice.public_key], 1)], metadata=meta2, tx2 = Create.generate([alice.public_key], [([alice.public_key], 1)], metadata=meta2,
asset=asset2).sign([alice.private_key]) assets=asset2).sign([alice.private_key])
b.store_bulk_transactions([tx2]) b.store_bulk_transactions([tx2])
# test that both assets are returned without limit # test that both assets are returned without limit

View File

@ -80,7 +80,7 @@ def test_post_create_transaction_with_language(b, client, nested, language,
asset = lang_obj asset = lang_obj
tx = Create.generate([user_pub], [([user_pub], 1)], tx = Create.generate([user_pub], [([user_pub], 1)],
asset=asset) assets=asset)
tx = tx.sign([user_priv]) tx = tx.sign([user_priv])
res = client.post(TX_ENDPOINT, data=json.dumps(tx.to_dict())) res = client.post(TX_ENDPOINT, data=json.dumps(tx.to_dict()))
assert res.status_code == expected_status_code assert res.status_code == expected_status_code
@ -111,7 +111,7 @@ def test_post_create_transaction_with_invalid_key(b, client, field, value,
if isinstance(b.connection, LocalMongoDBConnection): if isinstance(b.connection, LocalMongoDBConnection):
if field == 'asset': if field == 'asset':
tx = Create.generate([user_pub], [([user_pub], 1)], tx = Create.generate([user_pub], [([user_pub], 1)],
asset=value) assets=value)
elif field == 'metadata': elif field == 'metadata':
tx = Create.generate([user_pub], [([user_pub], 1)], tx = Create.generate([user_pub], [([user_pub], 1)],
metadata=value) metadata=value)
@ -342,7 +342,7 @@ def test_post_wrong_asset_division_transfer_returns_400(b, client, user_pk):
create_tx = Create.generate([pub_key], create_tx = Create.generate([pub_key],
[([pub_key], 10)], [([pub_key], 10)],
asset={'test': 'asset'}).sign([priv_key]) assets={'test': 'asset'}).sign([priv_key])
res = client.post(TX_ENDPOINT + '?mode=commit', data=json.dumps(create_tx.to_dict())) res = client.post(TX_ENDPOINT + '?mode=commit', data=json.dumps(create_tx.to_dict()))
assert res.status_code == 202 assert res.status_code == 202
@ -426,7 +426,7 @@ def test_post_transaction_valid_modes(mock_post, client, mode):
alice = generate_key_pair() alice = generate_key_pair()
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=None) \ assets=None) \
.sign([alice.private_key]) .sign([alice.private_key])
mode_endpoint = TX_ENDPOINT + mode[0] mode_endpoint = TX_ENDPOINT + mode[0]
client.post(mode_endpoint, data=json.dumps(tx.to_dict())) client.post(mode_endpoint, data=json.dumps(tx.to_dict()))
@ -440,7 +440,7 @@ def test_post_transaction_invalid_mode(client):
alice = generate_key_pair() alice = generate_key_pair()
tx = Create.generate([alice.public_key], tx = Create.generate([alice.public_key],
[([alice.public_key], 1)], [([alice.public_key], 1)],
asset=None) \ assets=None) \
.sign([alice.private_key]) .sign([alice.private_key])
mode_endpoint = TX_ENDPOINT + '?mode=nope' mode_endpoint = TX_ENDPOINT + '?mode=nope'
response = client.post(mode_endpoint, data=json.dumps(tx.to_dict())) response = client.post(mode_endpoint, data=json.dumps(tx.to_dict()))

View File

@ -202,7 +202,7 @@ def test_integration_from_webapi_to_websocket(monkeypatch, client, loop):
# Create a keypair and generate a new asset # Create a keypair and generate a new asset
user_priv, user_pub = crypto.generate_key_pair() user_priv, user_pub = crypto.generate_key_pair()
asset = {'random': random.random()} asset = {'random': random.random()}
tx = Create.generate([user_pub], [([user_pub], 1)], asset=asset) tx = Create.generate([user_pub], [([user_pub], 1)], assets=asset)
tx = tx.sign([user_priv]) tx = tx.sign([user_priv])
# Post the transaction to the Planetmint Web API # Post the transaction to the Planetmint Web API
client.post('/api/v1/transactions/', data=json.dumps(tx.to_dict())) client.post('/api/v1/transactions/', data=json.dumps(tx.to_dict()))