Problem: Monolithic code files (#60)

* Integrate zenroom acceptance test

* fixed zenroom reference

* added additional dependences to the docker fils so that zenroom can be executed.
added zenroom from git repo, because pypi servs an older buggy version

* using the custom planetmintdriver branch to avoid pypi zendesk downloads

* Added zenroom test

* Added zenroom test

Signed-off-by: Sangat Das <sangatdas5@gmail.com>

* Change reference to planetmint-driver to planetmint-driver-python

Signed-off-by: Sangat Das <sangatdas5@gmail.com>

* Basic structuring

* Added new classes in transactions/common

* Added Create and Transfer as separate transactions

* Resolved errors related to transactions.common

* Fixing imports

* Resolved issues of election transaction

* Resolve flake8 issues

Signed-off-by: Sangat Das <sangatdas5@gmail.com>

* Resolve remaining flake8 issues

Signed-off-by: Sangat Das <sangatdas5@gmail.com>

* Resolve remaining flake8 issues

Signed-off-by: Sangat Das <sangatdas5@gmail.com>

Co-authored-by: Jürgen Eckel <juergen@riddleandcode.com>
Co-authored-by: ArpitShukla007 <arpitnshukla@gmail.com>
This commit is contained in:
RoninX 2022-03-15 07:21:16 +01:00 committed by GitHub
parent bf5b88fcb2
commit 4d3eb6bfdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
76 changed files with 917 additions and 747 deletions

View File

@ -9,7 +9,7 @@ import json
import os
import os.path
from planetmint.common.transaction import Transaction, Input, TransactionLink
from planetmint.transactions.common.transaction import Transaction, Input, TransactionLink
from planetmint import lib
from planetmint.web import server

View File

@ -94,10 +94,10 @@ config = {
# the user wants to reconfigure the node. Check ``planetmint.config_utils``
# for more info.
_config = copy.deepcopy(config)
from planetmint.common.transaction import Transaction # noqa
from planetmint.transactions.common.transaction import Transaction # noqa
from planetmint import models # noqa
from planetmint.upsert_validator import ValidatorElection # noqa
from planetmint.elections.vote import Vote # noqa
from planetmint.transactions.types.elections.vote import Vote # noqa
Transaction.register_type(Transaction.CREATE, models.Transaction)
Transaction.register_type(Transaction.TRANSFER, models.Transaction)

View File

@ -10,7 +10,7 @@ from itertools import repeat
import planetmint
from planetmint.backend.exceptions import ConnectionError
from planetmint.backend.utils import get_planetmint_config_value, get_planetmint_config_value_or_key_error
from planetmint.common.exceptions import ConfigurationError
from planetmint.transactions.common.exceptions import ConfigurationError
BACKENDS = {
'localmongodb': 'planetmint.backend.localmongodb.connection.LocalMongoDBConnection',

View File

@ -13,7 +13,7 @@ from planetmint.backend.exceptions import (DuplicateKeyError,
OperationError,
ConnectionError)
from planetmint.backend.utils import get_planetmint_config_value
from planetmint.common.exceptions import ConfigurationError
from planetmint.transactions.common.exceptions import ConfigurationError
from planetmint.utils import Lazy
logger = logging.getLogger(__name__)

View File

@ -11,7 +11,7 @@ from planetmint import backend
from planetmint.backend.exceptions import DuplicateKeyError
from planetmint.backend.utils import module_dispatch_registrar
from planetmint.backend.localmongodb.connection import LocalMongoDBConnection
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
register_query = module_dispatch_registrar(backend.query)

View File

@ -10,8 +10,9 @@ import logging
import planetmint
from planetmint.backend.connection import connect
from planetmint.common.exceptions import ValidationError
from planetmint.common.utils import validate_all_values_for_key_in_obj, validate_all_values_for_key_in_list
from planetmint.transactions.common.exceptions import ValidationError
from planetmint.transactions.common.utils import (
validate_all_values_for_key_in_obj, validate_all_values_for_key_in_list)
logger = logging.getLogger(__name__)

View File

@ -17,10 +17,10 @@ import sys
from planetmint.core import rollback
from planetmint.migrations.chain_migration_election import ChainMigrationElection
from planetmint.utils import load_node_key
from planetmint.common.transaction_mode_types import BROADCAST_TX_COMMIT
from planetmint.common.exceptions import (DatabaseDoesNotExist,
ValidationError)
from planetmint.elections.vote import Vote
from planetmint.transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT
from planetmint.transactions.common.exceptions import (
DatabaseDoesNotExist, ValidationError)
from planetmint.transactions.types.elections.vote import Vote
import planetmint
from planetmint import (backend, ValidatorElection,
Planetmint)

View File

@ -25,7 +25,7 @@ from functools import lru_cache
from pkg_resources import iter_entry_points, ResolutionError
from planetmint.common import exceptions
from planetmint.transactions.common import exceptions
import planetmint

View File

@ -21,7 +21,7 @@ from tendermint.abci.types_pb2 import (
ResponseCommit
)
from planetmint import Planetmint
from planetmint.elections.election import Election
from planetmint.transactions.types.elections.election import Election
from planetmint.tendermint_utils import (decode_transaction,
calculate_hash)
from planetmint.lib import Block

View File

@ -5,7 +5,7 @@
from planetmint.utils import condition_details_has_owner
from planetmint.backend import query
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
class FastQuery():

View File

@ -24,31 +24,27 @@ import requests
import planetmint
from planetmint import backend, config_utils, fastquery
from planetmint.models import Transaction
from planetmint.common.exceptions import (SchemaValidationError,
ValidationError,
DoubleSpend)
from planetmint.common.transaction_mode_types import (BROADCAST_TX_COMMIT,
BROADCAST_TX_ASYNC,
BROADCAST_TX_SYNC)
from planetmint.transactions.common.exceptions import (
SchemaValidationError, ValidationError, DoubleSpend)
from planetmint.transactions.common.transaction_mode_types import (
BROADCAST_TX_COMMIT, BROADCAST_TX_ASYNC, BROADCAST_TX_SYNC)
from planetmint.tendermint_utils import encode_transaction, merkleroot
from planetmint import exceptions as core_exceptions
from planetmint.validation import BaseValidationRules
logger = logging.getLogger(__name__)
class Planetmint(object):
"""Bigchain API
"""Planetmint API
Create, read, sign, write transactions to the database
"""
def __init__(self, connection=None):
"""Initialize the Bigchain instance
"""Initialize the Planetmint instance
A Bigchain instance has several configuration parameters (e.g. host).
If a parameter value is passed as an argument to the Bigchain
A Planetmint instance has several configuration parameters (e.g. host).
If a parameter value is passed as an argument to the Planetmint
__init__ method, then that is the value it will have.
Otherwise, the parameter value will come from an environment variable.
If that environment variable isn't set, then the value

View File

@ -6,7 +6,7 @@
import planetmint
import logging
from planetmint.common.exceptions import ConfigurationError
from planetmint.transactions.common.exceptions import ConfigurationError
from logging.config import dictConfig as set_logging_config
import os

View File

@ -1,7 +1,7 @@
import json
from planetmint.common.schema import TX_SCHEMA_CHAIN_MIGRATION_ELECTION
from planetmint.elections.election import Election
from planetmint.transactions.common.schema import TX_SCHEMA_CHAIN_MIGRATION_ELECTION
from planetmint.transactions.types.elections.election import Election
class ChainMigrationElection(Election):

View File

@ -4,11 +4,10 @@
# Code is Apache-2.0 and docs are CC-BY-4.0
from planetmint.backend.schema import validate_language_key
from planetmint.common.exceptions import (InvalidSignature,
DuplicateTransaction)
from planetmint.common.schema import validate_transaction_schema
from planetmint.common.transaction import Transaction
from planetmint.common.utils import (validate_txn_obj, validate_key)
from planetmint.transactions.common.exceptions import (InvalidSignature, DuplicateTransaction)
from planetmint.transactions.common.schema import validate_transaction_schema
from planetmint.transactions.common.transaction import Transaction
from planetmint.transactions.common.utils import (validate_txn_obj, validate_key)
class Transaction(Transaction):

View File

@ -26,10 +26,10 @@ def generate_key_pair():
"""Generates a cryptographic key pair.
Returns:
:class:`~planetmint.common.crypto.CryptoKeypair`: A
:class:`~planetmint.transactions.common.crypto.CryptoKeypair`: A
:obj:`collections.namedtuple` with named fields
:attr:`~planetmint.common.crypto.CryptoKeypair.private_key` and
:attr:`~planetmint.common.crypto.CryptoKeypair.public_key`.
:attr:`~planetmint.transactions.common.crypto.CryptoKeypair.private_key` and
:attr:`~planetmint.transactions.common.crypto.CryptoKeypair.public_key`.
"""
# TODO FOR CC: Adjust interface so that this function becomes unnecessary

View File

@ -0,0 +1,125 @@
# 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
from cryptoconditions import Fulfillment
from cryptoconditions.exceptions import ASN1DecodeError, ASN1EncodeError
from planetmint.transactions.common.exceptions import InvalidSignature
from .utils import _fulfillment_to_details, _fulfillment_from_details
from .output import Output
from .transaction_link import TransactionLink
class Input(object):
"""A Input is used to spend assets locked by an Output.
Wraps around a Crypto-condition Fulfillment.
Attributes:
fulfillment (:class:`cryptoconditions.Fulfillment`): A Fulfillment
to be signed with a private key.
owners_before (:obj:`list` of :obj:`str`): A list of owners after a
Transaction was confirmed.
fulfills (:class:`~planetmint.transactions.common.transaction. TransactionLink`,
optional): A link representing the input of a `TRANSFER`
Transaction.
"""
def __init__(self, fulfillment, owners_before, fulfills=None):
"""Create an instance of an :class:`~.Input`.
Args:
fulfillment (:class:`cryptoconditions.Fulfillment`): A
Fulfillment to be signed with a private key.
owners_before (:obj:`list` of :obj:`str`): A list of owners
after a Transaction was confirmed.
fulfills (:class:`~planetmint.transactions.common.transaction.
TransactionLink`, optional): A link representing the input
of a `TRANSFER` Transaction.
"""
if fulfills is not None and not isinstance(fulfills, TransactionLink):
raise TypeError('`fulfills` must be a TransactionLink instance')
if not isinstance(owners_before, list):
raise TypeError('`owners_before` must be a list instance')
self.fulfillment = fulfillment
self.fulfills = fulfills
self.owners_before = owners_before
def __eq__(self, other):
# TODO: If `other !== Fulfillment` return `False`
return self.to_dict() == other.to_dict()
# NOTE: This function is used to provide a unique key for a given
# Input to suppliment memoization
def __hash__(self):
return hash((self.fulfillment, self.fulfills))
def to_dict(self):
"""Transforms the object to a Python dictionary.
Note:
If an Input hasn't been signed yet, this method returns a
dictionary representation.
Returns:
dict: The Input as an alternative serialization format.
"""
try:
fulfillment = self.fulfillment.serialize_uri()
except (TypeError, AttributeError, ASN1EncodeError, ASN1DecodeError):
fulfillment = _fulfillment_to_details(self.fulfillment)
try:
# NOTE: `self.fulfills` can be `None` and that's fine
fulfills = self.fulfills.to_dict()
except AttributeError:
fulfills = None
input_ = {
'owners_before': self.owners_before,
'fulfills': fulfills,
'fulfillment': fulfillment,
}
return input_
@classmethod
def generate(cls, public_keys):
# TODO: write docstring
# The amount here does not really matter. It is only use on the
# output data model but here we only care about the fulfillment
output = Output.generate(public_keys, 1)
return cls(output.fulfillment, public_keys)
@classmethod
def from_dict(cls, data):
"""Transforms a Python dictionary to an Input object.
Note:
Optionally, this method can also serialize a Cryptoconditions-
Fulfillment that is not yet signed.
Args:
data (dict): The Input to be transformed.
Returns:
:class:`~planetmint.transactions.common.transaction.Input`
Raises:
InvalidSignature: If an Input's URI couldn't be parsed.
"""
fulfillment = data['fulfillment']
if not isinstance(fulfillment, (Fulfillment, type(None))):
try:
fulfillment = Fulfillment.from_uri(data['fulfillment'])
except ASN1DecodeError:
# TODO Remove as it is legacy code, and simply fall back on
# ASN1DecodeError
raise InvalidSignature("Fulfillment URI couldn't been parsed")
except TypeError:
# NOTE: See comment about this special case in
# `Input.to_dict`
fulfillment = _fulfillment_from_details(data['fulfillment'])
fulfills = TransactionLink.from_dict(data['fulfills'])
return cls(fulfillment, data['owners_before'], fulfills)

View File

@ -0,0 +1,208 @@
# 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
from functools import reduce
import base58
from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256
from planetmint.transactions.common.exceptions import AmountError
from .utils import _fulfillment_to_details, _fulfillment_from_details
class Output(object):
"""An Output is used to lock an asset.
Wraps around a Crypto-condition Condition.
Attributes:
fulfillment (:class:`cryptoconditions.Fulfillment`): A Fulfillment
to extract a Condition from.
public_keys (:obj:`list` of :obj:`str`, optional): A list of
owners before a Transaction was confirmed.
"""
MAX_AMOUNT = 9 * 10 ** 18
def __init__(self, fulfillment, public_keys=None, amount=1):
"""Create an instance of a :class:`~.Output`.
Args:
fulfillment (:class:`cryptoconditions.Fulfillment`): A
Fulfillment to extract a Condition from.
public_keys (:obj:`list` of :obj:`str`, optional): A list of
owners before a Transaction was confirmed.
amount (int): The amount of Assets to be locked with this
Output.
Raises:
TypeError: if `public_keys` is not instance of `list`.
"""
if not isinstance(public_keys, list) and public_keys is not None:
raise TypeError('`public_keys` must be a list instance or None')
if not isinstance(amount, int):
raise TypeError('`amount` must be an int')
if amount < 1:
raise AmountError('`amount` must be greater than 0')
if amount > self.MAX_AMOUNT:
raise AmountError('`amount` must be <= %s' % self.MAX_AMOUNT)
self.fulfillment = fulfillment
self.amount = amount
self.public_keys = public_keys
def __eq__(self, other):
# TODO: If `other !== Condition` return `False`
return self.to_dict() == other.to_dict()
def to_dict(self):
"""Transforms the object to a Python dictionary.
Note:
A dictionary serialization of the Input the Output was
derived from is always provided.
Returns:
dict: The Output as an alternative serialization format.
"""
# TODO FOR CC: It must be able to recognize a hashlock condition
# and fulfillment!
condition = {}
try:
condition['details'] = _fulfillment_to_details(self.fulfillment)
except AttributeError:
pass
try:
condition['uri'] = self.fulfillment.condition_uri
except AttributeError:
condition['uri'] = self.fulfillment
output = {
'public_keys': self.public_keys,
'condition': condition,
'amount': str(self.amount),
}
return output
@classmethod
def generate(cls, public_keys, amount):
"""Generates a Output from a specifically formed tuple or list.
Note:
If a ThresholdCondition has to be generated where the threshold
is always the number of subconditions it is split between, a
list of the following structure is sufficient:
[(address|condition)*, [(address|condition)*, ...], ...]
Args:
public_keys (:obj:`list` of :obj:`str`): The public key of
the users that should be able to fulfill the Condition
that is being created.
amount (:obj:`int`): The amount locked by the Output.
Returns:
An Output that can be used in a Transaction.
Raises:
TypeError: If `public_keys` is not an instance of `list`.
ValueError: If `public_keys` is an empty list.
"""
threshold = len(public_keys)
if not isinstance(amount, int):
raise TypeError('`amount` must be a int')
if amount < 1:
raise AmountError('`amount` needs to be greater than zero')
if not isinstance(public_keys, list):
raise TypeError('`public_keys` must be an instance of list')
if len(public_keys) == 0:
raise ValueError('`public_keys` needs to contain at least one'
'owner')
elif len(public_keys) == 1 and not isinstance(public_keys[0], list):
if isinstance(public_keys[0], Fulfillment):
ffill = public_keys[0]
else:
ffill = Ed25519Sha256(
public_key=base58.b58decode(public_keys[0]))
return cls(ffill, public_keys, amount=amount)
else:
initial_cond = ThresholdSha256(threshold=threshold)
threshold_cond = reduce(cls._gen_condition, public_keys,
initial_cond)
return cls(threshold_cond, public_keys, amount=amount)
@classmethod
def _gen_condition(cls, initial, new_public_keys):
"""Generates ThresholdSha256 conditions from a list of new owners.
Note:
This method is intended only to be used with a reduce function.
For a description on how to use this method, see
:meth:`~.Output.generate`.
Args:
initial (:class:`cryptoconditions.ThresholdSha256`):
A Condition representing the overall root.
new_public_keys (:obj:`list` of :obj:`str`|str): A list of new
owners or a single new owner.
Returns:
:class:`cryptoconditions.ThresholdSha256`:
"""
try:
threshold = len(new_public_keys)
except TypeError:
threshold = None
if isinstance(new_public_keys, list) and len(new_public_keys) > 1:
ffill = ThresholdSha256(threshold=threshold)
reduce(cls._gen_condition, new_public_keys, ffill)
elif isinstance(new_public_keys, list) and len(new_public_keys) <= 1:
raise ValueError('Sublist cannot contain single owner')
else:
try:
new_public_keys = new_public_keys.pop()
except AttributeError:
pass
# NOTE: Instead of submitting base58 encoded addresses, a user
# of this class can also submit fully instantiated
# Cryptoconditions. In the case of casting
# `new_public_keys` to a Ed25519Fulfillment with the
# result of a `TypeError`, we're assuming that
# `new_public_keys` is a Cryptocondition then.
if isinstance(new_public_keys, Fulfillment):
ffill = new_public_keys
else:
ffill = Ed25519Sha256(
public_key=base58.b58decode(new_public_keys))
initial.add_subfulfillment(ffill)
return initial
@classmethod
def from_dict(cls, data):
"""Transforms a Python dictionary to an Output object.
Note:
To pass a serialization cycle multiple times, a
Cryptoconditions Fulfillment needs to be present in the
passed-in dictionary, as Condition URIs are not serializable
anymore.
Args:
data (dict): The dict to be transformed.
Returns:
:class:`~planetmint.transactions.common.transaction.Output`
"""
try:
fulfillment = _fulfillment_from_details(data['condition']['details'])
except KeyError:
# NOTE: Hashlock condition case
fulfillment = data['condition']['uri']
try:
amount = int(data['amount'])
except ValueError:
raise AmountError('Invalid amount: %s' % data['amount'])
return cls(fulfillment, data['public_keys'], amount)

View File

@ -11,7 +11,7 @@ import jsonschema
import yaml
import rapidjson
from planetmint.common.exceptions import SchemaValidationError
from planetmint.transactions.common.exceptions import SchemaValidationError
logger = logging.getLogger(__name__)

View File

@ -13,27 +13,27 @@ Attributes:
"""
from collections import namedtuple
from copy import deepcopy
from functools import reduce, lru_cache
from functools import lru_cache
import rapidjson
import base58
from cryptoconditions import Fulfillment, ThresholdSha256, Ed25519Sha256
from cryptoconditions.exceptions import (
ParsingError, ASN1DecodeError, ASN1EncodeError, UnsupportedTypeError)
ParsingError, ASN1DecodeError, ASN1EncodeError)
try:
from hashlib import sha3_256
except ImportError:
from sha3 import sha3_256
from planetmint.common.crypto import PrivateKey, hash_data
from planetmint.common.exceptions import (KeypairMismatchException,
InputDoesNotExist, DoubleSpend,
InvalidHash, InvalidSignature,
AmountError, AssetIdMismatch,
ThresholdTooDeep)
from planetmint.common.utils import serialize
from planetmint.transactions.common.crypto import PrivateKey, hash_data
from planetmint.transactions.common.exceptions import (
KeypairMismatchException, InputDoesNotExist, DoubleSpend,
InvalidHash, InvalidSignature, AmountError, AssetIdMismatch)
from planetmint.transactions.common.utils import serialize
from .memoize import memoize_from_dict, memoize_to_dict
from .input import Input
from .output import Output
from .transaction_link import TransactionLink
UnspentOutput = namedtuple(
'UnspentOutput', (
@ -47,441 +47,6 @@ UnspentOutput = namedtuple(
)
)
class Input(object):
"""A Input is used to spend assets locked by an Output.
Wraps around a Crypto-condition Fulfillment.
Attributes:
fulfillment (:class:`cryptoconditions.Fulfillment`): A Fulfillment
to be signed with a private key.
owners_before (:obj:`list` of :obj:`str`): A list of owners after a
Transaction was confirmed.
fulfills (:class:`~planetmint.common.transaction. TransactionLink`,
optional): A link representing the input of a `TRANSFER`
Transaction.
"""
def __init__(self, fulfillment, owners_before, fulfills=None):
"""Create an instance of an :class:`~.Input`.
Args:
fulfillment (:class:`cryptoconditions.Fulfillment`): A
Fulfillment to be signed with a private key.
owners_before (:obj:`list` of :obj:`str`): A list of owners
after a Transaction was confirmed.
fulfills (:class:`~planetmint.common.transaction.
TransactionLink`, optional): A link representing the input
of a `TRANSFER` Transaction.
"""
if fulfills is not None and not isinstance(fulfills, TransactionLink):
raise TypeError('`fulfills` must be a TransactionLink instance')
if not isinstance(owners_before, list):
raise TypeError('`owners_before` must be a list instance')
self.fulfillment = fulfillment
self.fulfills = fulfills
self.owners_before = owners_before
def __eq__(self, other):
# TODO: If `other !== Fulfillment` return `False`
return self.to_dict() == other.to_dict()
# NOTE: This function is used to provide a unique key for a given
# Input to suppliment memoization
def __hash__(self):
return hash((self.fulfillment, self.fulfills))
def to_dict(self):
"""Transforms the object to a Python dictionary.
Note:
If an Input hasn't been signed yet, this method returns a
dictionary representation.
Returns:
dict: The Input as an alternative serialization format.
"""
try:
fulfillment = self.fulfillment.serialize_uri()
except (TypeError, AttributeError, ASN1EncodeError, ASN1DecodeError):
fulfillment = _fulfillment_to_details(self.fulfillment)
try:
# NOTE: `self.fulfills` can be `None` and that's fine
fulfills = self.fulfills.to_dict()
except AttributeError:
fulfills = None
input_ = {
'owners_before': self.owners_before,
'fulfills': fulfills,
'fulfillment': fulfillment,
}
return input_
@classmethod
def generate(cls, public_keys):
# TODO: write docstring
# The amount here does not really matter. It is only use on the
# output data model but here we only care about the fulfillment
output = Output.generate(public_keys, 1)
return cls(output.fulfillment, public_keys)
@classmethod
def from_dict(cls, data):
"""Transforms a Python dictionary to an Input object.
Note:
Optionally, this method can also serialize a Cryptoconditions-
Fulfillment that is not yet signed.
Args:
data (dict): The Input to be transformed.
Returns:
:class:`~planetmint.common.transaction.Input`
Raises:
InvalidSignature: If an Input's URI couldn't be parsed.
"""
fulfillment = data['fulfillment']
if not isinstance(fulfillment, (Fulfillment, type(None))):
try:
fulfillment = Fulfillment.from_uri(data['fulfillment'])
except ASN1DecodeError:
# TODO Remove as it is legacy code, and simply fall back on
# ASN1DecodeError
raise InvalidSignature("Fulfillment URI couldn't been parsed")
except TypeError:
# NOTE: See comment about this special case in
# `Input.to_dict`
fulfillment = _fulfillment_from_details(data['fulfillment'])
fulfills = TransactionLink.from_dict(data['fulfills'])
return cls(fulfillment, data['owners_before'], fulfills)
def _fulfillment_to_details(fulfillment):
"""Encode a fulfillment as a details dictionary
Args:
fulfillment: Crypto-conditions Fulfillment object
"""
if fulfillment.type_name == 'ed25519-sha-256':
return {
'type': 'ed25519-sha-256',
'public_key': base58.b58encode(fulfillment.public_key).decode(),
}
if fulfillment.type_name == 'threshold-sha-256':
subconditions = [
_fulfillment_to_details(cond['body'])
for cond in fulfillment.subconditions
]
return {
'type': 'threshold-sha-256',
'threshold': fulfillment.threshold,
'subconditions': subconditions,
}
raise UnsupportedTypeError(fulfillment.type_name)
def _fulfillment_from_details(data, _depth=0):
"""Load a fulfillment for a signing spec dictionary
Args:
data: tx.output[].condition.details dictionary
"""
if _depth == 100:
raise ThresholdTooDeep()
if data['type'] == 'ed25519-sha-256':
public_key = base58.b58decode(data['public_key'])
return Ed25519Sha256(public_key=public_key)
if data['type'] == 'threshold-sha-256':
threshold = ThresholdSha256(data['threshold'])
for cond in data['subconditions']:
cond = _fulfillment_from_details(cond, _depth + 1)
threshold.add_subfulfillment(cond)
return threshold
raise UnsupportedTypeError(data.get('type'))
class TransactionLink(object):
"""An object for unidirectional linking to a Transaction's Output.
Attributes:
txid (str, optional): A Transaction to link to.
output (int, optional): An output's index in a Transaction with id
`txid`.
"""
def __init__(self, txid=None, output=None):
"""Create an instance of a :class:`~.TransactionLink`.
Note:
In an IPLD implementation, this class is not necessary anymore,
as an IPLD link can simply point to an object, as well as an
objects properties. So instead of having a (de)serializable
class, we can have a simple IPLD link of the form:
`/<tx_id>/transaction/outputs/<output>/`.
Args:
txid (str, optional): A Transaction to link to.
output (int, optional): An Outputs's index in a Transaction with
id `txid`.
"""
self.txid = txid
self.output = output
def __bool__(self):
return self.txid is not None and self.output is not None
def __eq__(self, other):
# TODO: If `other !== TransactionLink` return `False`
return self.to_dict() == other.to_dict()
def __hash__(self):
return hash((self.txid, self.output))
@classmethod
def from_dict(cls, link):
"""Transforms a Python dictionary to a TransactionLink object.
Args:
link (dict): The link to be transformed.
Returns:
:class:`~planetmint.common.transaction.TransactionLink`
"""
try:
return cls(link['transaction_id'], link['output_index'])
except TypeError:
return cls()
def to_dict(self):
"""Transforms the object to a Python dictionary.
Returns:
(dict|None): The link as an alternative serialization format.
"""
if self.txid is None and self.output is None:
return None
else:
return {
'transaction_id': self.txid,
'output_index': self.output,
}
def to_uri(self, path=''):
if self.txid is None and self.output is None:
return None
return '{}/transactions/{}/outputs/{}'.format(path, self.txid,
self.output)
class Output(object):
"""An Output is used to lock an asset.
Wraps around a Crypto-condition Condition.
Attributes:
fulfillment (:class:`cryptoconditions.Fulfillment`): A Fulfillment
to extract a Condition from.
public_keys (:obj:`list` of :obj:`str`, optional): A list of
owners before a Transaction was confirmed.
"""
MAX_AMOUNT = 9 * 10 ** 18
def __init__(self, fulfillment, public_keys=None, amount=1):
"""Create an instance of a :class:`~.Output`.
Args:
fulfillment (:class:`cryptoconditions.Fulfillment`): A
Fulfillment to extract a Condition from.
public_keys (:obj:`list` of :obj:`str`, optional): A list of
owners before a Transaction was confirmed.
amount (int): The amount of Assets to be locked with this
Output.
Raises:
TypeError: if `public_keys` is not instance of `list`.
"""
if not isinstance(public_keys, list) and public_keys is not None:
raise TypeError('`public_keys` must be a list instance or None')
if not isinstance(amount, int):
raise TypeError('`amount` must be an int')
if amount < 1:
raise AmountError('`amount` must be greater than 0')
if amount > self.MAX_AMOUNT:
raise AmountError('`amount` must be <= %s' % self.MAX_AMOUNT)
self.fulfillment = fulfillment
self.amount = amount
self.public_keys = public_keys
def __eq__(self, other):
# TODO: If `other !== Condition` return `False`
return self.to_dict() == other.to_dict()
def to_dict(self):
"""Transforms the object to a Python dictionary.
Note:
A dictionary serialization of the Input the Output was
derived from is always provided.
Returns:
dict: The Output as an alternative serialization format.
"""
# TODO FOR CC: It must be able to recognize a hashlock condition
# and fulfillment!
condition = {}
try:
condition['details'] = _fulfillment_to_details(self.fulfillment)
except AttributeError:
pass
try:
condition['uri'] = self.fulfillment.condition_uri
except AttributeError:
condition['uri'] = self.fulfillment
output = {
'public_keys': self.public_keys,
'condition': condition,
'amount': str(self.amount),
}
return output
@classmethod
def generate(cls, public_keys, amount):
"""Generates a Output from a specifically formed tuple or list.
Note:
If a ThresholdCondition has to be generated where the threshold
is always the number of subconditions it is split between, a
list of the following structure is sufficient:
[(address|condition)*, [(address|condition)*, ...], ...]
Args:
public_keys (:obj:`list` of :obj:`str`): The public key of
the users that should be able to fulfill the Condition
that is being created.
amount (:obj:`int`): The amount locked by the Output.
Returns:
An Output that can be used in a Transaction.
Raises:
TypeError: If `public_keys` is not an instance of `list`.
ValueError: If `public_keys` is an empty list.
"""
threshold = len(public_keys)
if not isinstance(amount, int):
raise TypeError('`amount` must be a int')
if amount < 1:
raise AmountError('`amount` needs to be greater than zero')
if not isinstance(public_keys, list):
raise TypeError('`public_keys` must be an instance of list')
if len(public_keys) == 0:
raise ValueError('`public_keys` needs to contain at least one'
'owner')
elif len(public_keys) == 1 and not isinstance(public_keys[0], list):
if isinstance(public_keys[0], Fulfillment):
ffill = public_keys[0]
else:
ffill = Ed25519Sha256(
public_key=base58.b58decode(public_keys[0]))
return cls(ffill, public_keys, amount=amount)
else:
initial_cond = ThresholdSha256(threshold=threshold)
threshold_cond = reduce(cls._gen_condition, public_keys,
initial_cond)
return cls(threshold_cond, public_keys, amount=amount)
@classmethod
def _gen_condition(cls, initial, new_public_keys):
"""Generates ThresholdSha256 conditions from a list of new owners.
Note:
This method is intended only to be used with a reduce function.
For a description on how to use this method, see
:meth:`~.Output.generate`.
Args:
initial (:class:`cryptoconditions.ThresholdSha256`):
A Condition representing the overall root.
new_public_keys (:obj:`list` of :obj:`str`|str): A list of new
owners or a single new owner.
Returns:
:class:`cryptoconditions.ThresholdSha256`:
"""
try:
threshold = len(new_public_keys)
except TypeError:
threshold = None
if isinstance(new_public_keys, list) and len(new_public_keys) > 1:
ffill = ThresholdSha256(threshold=threshold)
reduce(cls._gen_condition, new_public_keys, ffill)
elif isinstance(new_public_keys, list) and len(new_public_keys) <= 1:
raise ValueError('Sublist cannot contain single owner')
else:
try:
new_public_keys = new_public_keys.pop()
except AttributeError:
pass
# NOTE: Instead of submitting base58 encoded addresses, a user
# of this class can also submit fully instantiated
# Cryptoconditions. In the case of casting
# `new_public_keys` to a Ed25519Fulfillment with the
# result of a `TypeError`, we're assuming that
# `new_public_keys` is a Cryptocondition then.
if isinstance(new_public_keys, Fulfillment):
ffill = new_public_keys
else:
ffill = Ed25519Sha256(
public_key=base58.b58decode(new_public_keys))
initial.add_subfulfillment(ffill)
return initial
@classmethod
def from_dict(cls, data):
"""Transforms a Python dictionary to an Output object.
Note:
To pass a serialization cycle multiple times, a
Cryptoconditions Fulfillment needs to be present in the
passed-in dictionary, as Condition URIs are not serializable
anymore.
Args:
data (dict): The dict to be transformed.
Returns:
:class:`~planetmint.common.transaction.Output`
"""
try:
fulfillment = _fulfillment_from_details(data['condition']['details'])
except KeyError:
# NOTE: Hashlock condition case
fulfillment = data['condition']['uri']
try:
amount = int(data['amount'])
except ValueError:
raise AmountError('Invalid amount: %s' % data['amount'])
return cls(fulfillment, data['public_keys'], amount)
class Transaction(object):
"""A Transaction is used to create and transfer assets.
@ -491,10 +56,10 @@ class Transaction(object):
Attributes:
operation (str): Defines the operation of the Transaction.
inputs (:obj:`list` of :class:`~planetmint.common.
inputs (:obj:`list` of :class:`~planetmint.transactions.common.
transaction.Input`, optional): Define the assets to
spend.
outputs (:obj:`list` of :class:`~planetmint.common.
outputs (:obj:`list` of :class:`~planetmint.transactions.common.
transaction.Output`, optional): Define the assets to lock.
asset (dict): Asset payload for this Transaction. ``CREATE``
Transactions require a dict with a ``data``
@ -521,9 +86,9 @@ class Transaction(object):
Args:
operation (str): Defines the operation of the Transaction.
asset (dict): Asset payload for this Transaction.
inputs (:obj:`list` of :class:`~planetmint.common.
inputs (:obj:`list` of :class:`~planetmint.transactions.common.
transaction.Input`, optional): Define the assets to
outputs (:obj:`list` of :class:`~planetmint.common.
outputs (:obj:`list` of :class:`~planetmint.transactions.common.
transaction.Output`, optional): Define the assets to
lock.
metadata (dict): Metadata to be stored along with the
@ -660,7 +225,7 @@ class Transaction(object):
be created in this Transaction.
Returns:
:class:`~planetmint.common.transaction.Transaction`
:class:`~planetmint.transactions.common.transaction.Transaction`
"""
(inputs, outputs) = cls.validate_create(tx_signers, recipients, asset, metadata)
@ -716,7 +281,7 @@ class Transaction(object):
weight respectively. `inp2` is owned completely by `d`.
Args:
inputs (:obj:`list` of :class:`~planetmint.common.transaction.
inputs (:obj:`list` of :class:`~planetmint.transactions.common.transaction.
Input`): Converted `Output`s, intended to
be used as inputs in the transfer to generate.
recipients (:obj:`list` of :obj:`tuple`): A list of
@ -728,7 +293,7 @@ class Transaction(object):
Transaction.
Returns:
:class:`~planetmint.common.transaction.Transaction`
:class:`~planetmint.transactions.common.transaction.Transaction`
"""
(inputs, outputs) = cls.validate_transfer(inputs, recipients, asset_id, metadata)
return cls(cls.TRANSFER, {'id': asset_id}, inputs, outputs, metadata)
@ -757,7 +322,7 @@ class Transaction(object):
outputs should be returned as inputs.
Returns:
:obj:`list` of :class:`~planetmint.common.transaction.
:obj:`list` of :class:`~planetmint.transactions.common.transaction.
Input`
"""
# NOTE: If no indices are passed, we just assume to take all outputs
@ -774,7 +339,7 @@ class Transaction(object):
"""Adds an input to a Transaction's list of inputs.
Args:
input_ (:class:`~planetmint.common.transaction.
input_ (:class:`~planetmint.transactions.common.transaction.
Input`): An Input to be added to the Transaction.
"""
if not isinstance(input_, Input):
@ -785,7 +350,7 @@ class Transaction(object):
"""Adds an output to a Transaction's list of outputs.
Args:
output (:class:`~planetmint.common.transaction.
output (:class:`~planetmint.transactions.common.transaction.
Output`): An Output to be added to the
Transaction.
"""
@ -811,7 +376,7 @@ class Transaction(object):
Transaction.
Returns:
:class:`~planetmint.common.transaction.Transaction`
:class:`~planetmint.transactions.common.transaction.Transaction`
"""
# TODO: Singing should be possible with at least one of all private
# keys supplied to this method.
@ -857,7 +422,7 @@ class Transaction(object):
- ThresholdSha256.
Args:
input_ (:class:`~planetmint.common.transaction.
input_ (:class:`~planetmint.transactions.common.transaction.
Input`) The Input to be signed.
message (str): The message to be signed
key_pairs (dict): The keys to sign the Transaction with.
@ -878,7 +443,7 @@ class Transaction(object):
"""Signs a Ed25519Fulfillment.
Args:
input_ (:class:`~planetmint.common.transaction.
input_ (:class:`~planetmint.transactions.common.transaction.
Input`) The input to be signed.
message (str): The message to be signed
key_pairs (dict): The keys to sign the Transaction with.
@ -910,7 +475,7 @@ class Transaction(object):
"""Signs a ThresholdSha256.
Args:
input_ (:class:`~planetmint.common.transaction.
input_ (:class:`~planetmint.transactions.common.transaction.
Input`) The Input to be signed.
message (str): The message to be signed
key_pairs (dict): The keys to sign the Transaction with.
@ -962,7 +527,7 @@ class Transaction(object):
evaluate parts of the validation-checks to `True`.
Args:
outputs (:obj:`list` of :class:`~planetmint.common.
outputs (:obj:`list` of :class:`~planetmint.transactions.common.
transaction.Output`): A list of Outputs to check the
Inputs against.
@ -1025,7 +590,7 @@ class Transaction(object):
does not validate against `output_condition_uri`.
Args:
input_ (:class:`~planetmint.common.transaction.
input_ (:class:`~planetmint.transactions.common.transaction.
Input`) The Input to be signed.
operation (str): The type of Transaction.
message (str): The fulfillment message.
@ -1134,7 +699,7 @@ class Transaction(object):
transaction are related to the same asset id.
Args:
transactions (:obj:`list` of :class:`~planetmint.common.
transactions (:obj:`list` of :class:`~planetmint.transactions.common.
transaction.Transaction`): A list of Transactions.
Usually input Transactions that should have a matching
asset ID.
@ -1196,7 +761,7 @@ class Transaction(object):
tx_body (dict): The Transaction to be transformed.
Returns:
:class:`~planetmint.common.transaction.Transaction`
:class:`~planetmint.transactions.common.transaction.Transaction`
"""
operation = tx.get('operation', Transaction.CREATE) if isinstance(tx, dict) else Transaction.CREATE
cls = Transaction.resolve_class(operation)

View File

@ -0,0 +1,76 @@
# 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
class TransactionLink(object):
"""An object for unidirectional linking to a Transaction's Output.
Attributes:
txid (str, optional): A Transaction to link to.
output (int, optional): An output's index in a Transaction with id
`txid`.
"""
def __init__(self, txid=None, output=None):
"""Create an instance of a :class:`~.TransactionLink`.
Note:
In an IPLD implementation, this class is not necessary anymore,
as an IPLD link can simply point to an object, as well as an
objects properties. So instead of having a (de)serializable
class, we can have a simple IPLD link of the form:
`/<tx_id>/transaction/outputs/<output>/`.
Args:
txid (str, optional): A Transaction to link to.
output (int, optional): An Outputs's index in a Transaction with
id `txid`.
"""
self.txid = txid
self.output = output
def __bool__(self):
return self.txid is not None and self.output is not None
def __eq__(self, other):
# TODO: If `other !== TransactionLink` return `False`
return self.to_dict() == other.to_dict()
def __hash__(self):
return hash((self.txid, self.output))
@classmethod
def from_dict(cls, link):
"""Transforms a Python dictionary to a TransactionLink object.
Args:
link (dict): The link to be transformed.
Returns:
:class:`~planetmint.transactions.common.transaction.TransactionLink`
"""
try:
return cls(link['transaction_id'], link['output_index'])
except TypeError:
return cls()
def to_dict(self):
"""Transforms the object to a Python dictionary.
Returns:
(dict|None): The link as an alternative serialization format.
"""
if self.txid is None and self.output is None:
return None
else:
return {
'transaction_id': self.txid,
'output_index': self.output,
}
def to_uri(self, path=''):
if self.txid is None and self.output is None:
return None
return '{}/transactions/{}/outputs/{}'.format(path, self.txid,
self.output)

View File

@ -3,12 +3,16 @@
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
# Code is Apache-2.0 and docs are CC-BY-4.0
import base58
import time
import re
import rapidjson
import planetmint
from planetmint.common.exceptions import ValidationError
from planetmint.transactions.common.exceptions import ValidationError
from cryptoconditions import ThresholdSha256, Ed25519Sha256
from planetmint.transactions.common.exceptions import ThresholdTooDeep
from cryptoconditions.exceptions import UnsupportedTypeError
def gen_timestamp():
@ -163,3 +167,52 @@ def validate_key(obj_name, key):
'key name cannot contain characters '
'".", "$" or null characters').format(key, obj_name)
raise ValidationError(error_str)
def _fulfillment_to_details(fulfillment):
"""Encode a fulfillment as a details dictionary
Args:
fulfillment: Crypto-conditions Fulfillment object
"""
if fulfillment.type_name == 'ed25519-sha-256':
return {
'type': 'ed25519-sha-256',
'public_key': base58.b58encode(fulfillment.public_key).decode(),
}
if fulfillment.type_name == 'threshold-sha-256':
subconditions = [
_fulfillment_to_details(cond['body'])
for cond in fulfillment.subconditions
]
return {
'type': 'threshold-sha-256',
'threshold': fulfillment.threshold,
'subconditions': subconditions,
}
raise UnsupportedTypeError(fulfillment.type_name)
def _fulfillment_from_details(data, _depth=0):
"""Load a fulfillment for a signing spec dictionary
Args:
data: tx.output[].condition.details dictionary
"""
if _depth == 100:
raise ThresholdTooDeep()
if data['type'] == 'ed25519-sha-256':
public_key = base58.b58decode(data['public_key'])
return Ed25519Sha256(public_key=public_key)
if data['type'] == 'threshold-sha-256':
threshold = ThresholdSha256(data['threshold'])
for cond in data['subconditions']:
cond = _fulfillment_from_details(cond, _depth + 1)
threshold.add_subfulfillment(cond)
return threshold
raise UnsupportedTypeError(data.get('type'))

View File

@ -0,0 +1,77 @@
# 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
from planetmint.transactions.common.transaction import Transaction
from planetmint.transactions.common.input import Input
from planetmint.transactions.common.output import Output
class Create(Transaction):
OPERATION = 'CREATE'
ALLOWED_OPERATIONS = (OPERATION,)
@classmethod
def validate(self, tx_signers, recipients, asset, metadata):
if not isinstance(tx_signers, list):
raise TypeError('`tx_signers` must be a list instance')
if not isinstance(recipients, list):
raise TypeError('`recipients` must be a list instance')
if len(tx_signers) == 0:
raise ValueError('`tx_signers` list cannot be empty')
if len(recipients) == 0:
raise ValueError('`recipients` list cannot be empty')
if not (asset is None or isinstance(asset, dict)):
raise TypeError('`asset` must be a dict or None')
if not (metadata is None or isinstance(metadata, dict)):
raise TypeError('`metadata` must be a dict or None')
inputs = []
outputs = []
# generate_outputs
for recipient in recipients:
if not isinstance(recipient, tuple) or len(recipient) != 2:
raise ValueError(('Each `recipient` in the list must be a'
' tuple of `([<list of public keys>],'
' <amount>)`'))
pub_keys, amount = recipient
outputs.append(Output.generate(pub_keys, amount))
# generate inputs
inputs.append(Input.generate(tx_signers))
return (inputs, outputs)
@classmethod
def generate(cls, tx_signers, recipients, metadata=None, asset=None):
"""A simple way to generate a `CREATE` transaction.
Note:
This method currently supports the following Cryptoconditions
use cases:
- Ed25519
- ThresholdSha256
Additionally, it provides support for the following Planetmint
use cases:
- Multiple inputs and outputs.
Args:
tx_signers (:obj:`list` of :obj:`str`): A list of keys that
represent the signers of the CREATE Transaction.
recipients (:obj:`list` of :obj:`tuple`): A list of
([keys],amount) that represent the recipients of this
Transaction.
metadata (dict): The metadata to be stored along with the
Transaction.
asset (dict): The metadata associated with the asset that will
be created in this Transaction.
Returns:
:class:`~planetmint.common.transaction.Transaction`
"""
(inputs, outputs) = cls.validate(tx_signers, recipients, asset, metadata)
return cls(cls.OPERATION, {'data': asset}, inputs, outputs, metadata)

View File

@ -0,0 +1,80 @@
# 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
from planetmint.transactions.common.transaction import Transaction
from planetmint.transactions.common.output import Output
from copy import deepcopy
class Transfer(Transaction):
OPERATION = 'TRANSFER'
ALLOWED_OPERATIONS = (OPERATION,)
@classmethod
def validate(cls, inputs, recipients, asset_id, metadata):
if not isinstance(inputs, list):
raise TypeError('`inputs` must be a list instance')
if len(inputs) == 0:
raise ValueError('`inputs` must contain at least one item')
if not isinstance(recipients, list):
raise TypeError('`recipients` must be a list instance')
if len(recipients) == 0:
raise ValueError('`recipients` list cannot be empty')
outputs = []
for recipient in recipients:
if not isinstance(recipient, tuple) or len(recipient) != 2:
raise ValueError(('Each `recipient` in the list must be a'
' tuple of `([<list of public keys>],'
' <amount>)`'))
pub_keys, amount = recipient
outputs.append(Output.generate(pub_keys, amount))
if not isinstance(asset_id, str):
raise TypeError('`asset_id` must be a string')
return (deepcopy(inputs), outputs)
@classmethod
def generate(cls, inputs, recipients, asset_id, metadata=None):
"""A simple way to generate a `TRANSFER` transaction.
Note:
Different cases for threshold conditions:
Combining multiple `inputs` with an arbitrary number of
`recipients` can yield interesting cases for the creation of
threshold conditions we'd like to support. The following
notation is proposed:
1. The index of a `recipient` corresponds to the index of
an input:
e.g. `transfer([input1], [a])`, means `input1` would now be
owned by user `a`.
2. `recipients` can (almost) get arbitrary deeply nested,
creating various complex threshold conditions:
e.g. `transfer([inp1, inp2], [[a, [b, c]], d])`, means
`a`'s signature would have a 50% weight on `inp1`
compared to `b` and `c` that share 25% of the leftover
weight respectively. `inp2` is owned completely by `d`.
Args:
inputs (:obj:`list` of :class:`~planetmint.common.transaction.
Input`): Converted `Output`s, intended to
be used as inputs in the transfer to generate.
recipients (:obj:`list` of :obj:`tuple`): A list of
([keys],amount) that represent the recipients of this
Transaction.
asset_id (str): The asset ID of the asset to be transferred in
this Transaction.
metadata (dict): Python dictionary to be stored along with the
Transaction.
Returns:
:class:`~planetmint.common.transaction.Transaction`
"""
(inputs, outputs) = cls.validate_transfer(inputs, recipients, asset_id, metadata)
return cls(cls.OPERATION, {'id': asset_id}, inputs, outputs, metadata)

View File

@ -8,18 +8,17 @@ import base58
from uuid import uuid4
from planetmint import backend
from planetmint.elections.vote import Vote
from planetmint.common.exceptions import (InvalidSignature,
MultipleInputsError,
InvalidProposer,
UnequalValidatorSet,
DuplicateTransaction)
from planetmint.transactions.types.assets.create import Create
from planetmint.transactions.types.assets.transfer import Transfer
from planetmint.transactions.types.elections.vote import Vote
from planetmint.transactions.common.exceptions import (
InvalidSignature, MultipleInputsError, InvalidProposer,
UnequalValidatorSet, DuplicateTransaction)
from planetmint.tendermint_utils import key_from_base64, public_key_to_base64
from planetmint.common.crypto import (public_key_from_ed25519_key)
from planetmint.common.transaction import Transaction
from planetmint.common.schema import (_validate_schema,
TX_SCHEMA_COMMON,
TX_SCHEMA_CREATE)
from planetmint.transactions.common.crypto import (public_key_from_ed25519_key)
from planetmint.transactions.common.transaction import Transaction
from planetmint.transactions.common.schema import (
_validate_schema, TX_SCHEMA_COMMON, TX_SCHEMA_CREATE)
class Election(Transaction):
@ -161,11 +160,11 @@ class Election(Transaction):
@classmethod
def create(cls, tx_signers, recipients, metadata=None, asset=None):
raise NotImplementedError
Create.generate(tx_signers, recipients, metadata=None, asset=None)
@classmethod
def transfer(cls, tx_signers, recipients, metadata=None, asset=None):
raise NotImplementedError
Transfer.generate(tx_signers, recipients, metadata=None, asset=None)
@classmethod
def to_public_key(cls, election_id):

View File

@ -3,11 +3,11 @@
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
# Code is Apache-2.0 and docs are CC-BY-4.0
from planetmint.common.transaction import Transaction
from planetmint.common.schema import (_validate_schema,
TX_SCHEMA_COMMON,
TX_SCHEMA_TRANSFER,
TX_SCHEMA_VOTE)
from planetmint.transactions.types.assets.create import Create
from planetmint.transactions.types.assets.transfer import Transfer
from planetmint.transactions.common.transaction import Transaction
from planetmint.transactions.common.schema import (
_validate_schema, TX_SCHEMA_COMMON, TX_SCHEMA_TRANSFER, TX_SCHEMA_VOTE)
class Vote(Transaction):
@ -57,8 +57,8 @@ class Vote(Transaction):
@classmethod
def create(cls, tx_signers, recipients, metadata=None, asset=None):
raise NotImplementedError
return Create.generate(tx_signers, recipients, metadata=None, asset=None)
@classmethod
def transfer(cls, tx_signers, recipients, metadata=None, asset=None):
raise NotImplementedError
return Transfer.generate(tx_signers, recipients, metadata=None, asset=None)

View File

@ -3,9 +3,9 @@
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
# Code is Apache-2.0 and docs are CC-BY-4.0
from planetmint.common.exceptions import InvalidPowerChange
from planetmint.elections.election import Election
from planetmint.common.schema import TX_SCHEMA_VALIDATOR_ELECTION
from planetmint.transactions.common.exceptions import InvalidPowerChange
from planetmint.transactions.types.elections.election import Election
from planetmint.transactions.common.schema import TX_SCHEMA_VALIDATOR_ELECTION
from .validator_utils import (new_validator_set, encode_validator, validate_asset_public_key)

View File

@ -4,7 +4,7 @@ import codecs
from tendermint.abci import types_pb2
from tendermint.crypto import keys_pb2
from planetmint.common.exceptions import InvalidPublicKey
from planetmint.transactions.common.exceptions import InvalidPublicKey
def encode_validator(v):
ed25519_public_key = v['public_key']['value']

View File

@ -13,7 +13,7 @@ import setproctitle
from packaging import version
from planetmint.version import __tm_supported_versions__
from planetmint.tendermint_utils import key_from_base64
from planetmint.common.crypto import key_pair_from_ed25519_key
from planetmint.transactions.common.crypto import key_pair_from_ed25519_key
class ProcessGroup(object):

View File

@ -5,10 +5,8 @@
import re
from planetmint.common.transaction_mode_types import (BROADCAST_TX_COMMIT,
BROADCAST_TX_ASYNC,
BROADCAST_TX_SYNC)
from planetmint.transactions.common.transaction_mode_types import (
BROADCAST_TX_COMMIT, BROADCAST_TX_ASYNC, BROADCAST_TX_SYNC)
def valid_txid(txid):
if re.match('^[a-fA-F0-9]{64}$', txid):

View File

@ -12,8 +12,8 @@ import logging
from flask import current_app, request, jsonify
from flask_restful import Resource, reqparse
from planetmint.common.transaction_mode_types import BROADCAST_TX_ASYNC
from planetmint.common.exceptions import SchemaValidationError, ValidationError
from planetmint.transactions.common.transaction_mode_types import BROADCAST_TX_ASYNC
from planetmint.transactions.common.exceptions import SchemaValidationError, ValidationError
from planetmint.web.views.base import make_error
from planetmint.web.views import parameters
from planetmint.models import Transaction

View File

@ -138,5 +138,5 @@ setup(
'dev': dev_require + tests_require + docs_require,
'docs': docs_require,
},
package_data={'planetmint.common.schema': ['*.yaml']},
package_data={'planetmint.transactions.common.schema': ['*.yaml']},
)

View File

@ -21,7 +21,7 @@ def test_asset_transfer(b, signed_create_tx, user_pk, user_sk):
def test_validate_transfer_asset_id_mismatch(b, signed_create_tx, user_pk, user_sk):
from planetmint.common.exceptions import AssetIdMismatch
from planetmint.transactions.common.exceptions import AssetIdMismatch
from planetmint.models import Transaction
tx_transfer = Transaction.transfer(signed_create_tx.to_inputs(), [([user_pk], 1)],
@ -52,7 +52,7 @@ def test_get_asset_id_transfer_transaction(b, signed_create_tx, user_pk):
def test_asset_id_mismatch(alice, user_pk):
from planetmint.models import Transaction
from planetmint.common.exceptions import AssetIdMismatch
from planetmint.transactions.common.exceptions import AssetIdMismatch
tx1 = Transaction.create([alice.public_key], [([user_pk], 1)],
metadata={'msg': random.random()})

View File

@ -6,7 +6,7 @@
import pytest
import random
from planetmint.common.exceptions import DoubleSpend
from planetmint.transactions.common.exceptions import DoubleSpend
# CREATE divisible asset
@ -99,7 +99,7 @@ def test_single_in_single_own_multiple_out_mix_own_create(alice, user_pk, b):
def test_single_in_multiple_own_single_out_single_own_create(alice, b, user_pk,
user_sk):
from planetmint.models import Transaction
from planetmint.common.transaction import _fulfillment_to_details
from planetmint.transactions.common.utils import _fulfillment_to_details
tx = Transaction.create([alice.public_key, user_pk], [([user_pk], 100)], asset={'name': random.random()})
tx_signed = tx.sign([alice.private_key, user_sk])
@ -249,7 +249,7 @@ def test_single_in_single_own_multiple_out_mix_own_transfer(alice, b, user_pk,
def test_single_in_multiple_own_single_out_single_own_transfer(alice, b, user_pk,
user_sk):
from planetmint.models import Transaction
from planetmint.common.transaction import _fulfillment_to_details
from planetmint.transactions.common.utils import _fulfillment_to_details
# CREATE divisible asset
tx_create = Transaction.create([alice.public_key], [([alice.public_key, user_pk], 100)],
@ -316,7 +316,7 @@ def test_multiple_in_single_own_single_out_single_own_transfer(alice, b, user_pk
def test_multiple_in_multiple_own_single_out_single_own_transfer(alice, b, user_pk,
user_sk):
from planetmint.models import Transaction
from planetmint.common.transaction import _fulfillment_to_details
from planetmint.transactions.common.utils import _fulfillment_to_details
# CREATE divisible asset
tx_create = Transaction.create([alice.public_key], [([user_pk, alice.public_key], 50),
@ -357,7 +357,7 @@ def test_multiple_in_multiple_own_single_out_single_own_transfer(alice, b, user_
def test_muiltiple_in_mix_own_multiple_out_single_own_transfer(alice, b, user_pk,
user_sk):
from planetmint.models import Transaction
from planetmint.common.transaction import _fulfillment_to_details
from planetmint.transactions.common.utils import _fulfillment_to_details
# CREATE divisible asset
tx_create = Transaction.create([alice.public_key], [([user_pk], 50), ([user_pk, alice.public_key], 50)],
@ -397,7 +397,7 @@ def test_muiltiple_in_mix_own_multiple_out_single_own_transfer(alice, b, user_pk
def test_muiltiple_in_mix_own_multiple_out_mix_own_transfer(alice, b, user_pk,
user_sk):
from planetmint.models import Transaction
from planetmint.common.transaction import _fulfillment_to_details
from planetmint.transactions.common.utils import _fulfillment_to_details
# CREATE divisible asset
tx_create = Transaction.create([alice.public_key], [([user_pk], 50), ([user_pk, alice.public_key], 50)],
@ -486,7 +486,7 @@ def test_multiple_in_different_transactions(alice, b, user_pk, user_sk):
# In other words `amount_in_inputs - amount_in_outputs == 0`
def test_amount_error_transfer(alice, b, user_pk, user_sk):
from planetmint.models import Transaction
from planetmint.common.exceptions import AmountError
from planetmint.transactions.common.exceptions import AmountError
# CREATE divisible asset
tx_create = Transaction.create([alice.public_key], [([user_pk], 100)], asset={'name': random.random()})

View File

@ -238,7 +238,7 @@ def test_get_spending_transactions(user_pk, user_sk):
def test_get_spending_transactions_multiple_inputs():
from planetmint.backend import connect, query
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
conn = connect()
(alice_sk, alice_pk) = generate_key_pair()
(bob_sk, bob_pk) = generate_key_pair()

View File

@ -7,7 +7,7 @@ import pytest
def test_get_connection_raises_a_configuration_error(monkeypatch):
from planetmint.common.exceptions import ConfigurationError
from planetmint.transactions.common.exceptions import ConfigurationError
from planetmint.backend import connect
with pytest.raises(ConfigurationError):

View File

@ -34,7 +34,7 @@ def mock_processes_start(monkeypatch):
@pytest.fixture
def mock_generate_key_pair(monkeypatch):
monkeypatch.setattr('planetmint.common.crypto.generate_key_pair', lambda: ('privkey', 'pubkey'))
monkeypatch.setattr('planetmint.transactions.common.crypto.generate_key_pair', lambda: ('privkey', 'pubkey'))
@pytest.fixture

View File

@ -13,7 +13,7 @@ import pytest
from planetmint import ValidatorElection
from planetmint.commands.planetmint import run_election_show
from planetmint.elections.election import Election
from planetmint.transactions.types.elections.election import Election
from planetmint.lib import Block
from planetmint.migrations.chain_migration_election import ChainMigrationElection
@ -123,7 +123,7 @@ def test_drop_db_when_interactive_yes(mock_db_drop, monkeypatch):
def test_drop_db_when_db_does_not_exist(mock_db_drop, capsys):
from planetmint import config
from planetmint.commands.planetmint import run_drop
from planetmint.common.exceptions import DatabaseDoesNotExist
from planetmint.transactions.common.exceptions import DatabaseDoesNotExist
args = Namespace(config=None, yes=True)
mock_db_drop.side_effect = DatabaseDoesNotExist
@ -404,7 +404,7 @@ def test_election_new_upsert_validator_invalid_election(caplog, b, priv_validato
@pytest.mark.bdb
def test_election_new_upsert_validator_invalid_power(caplog, b, priv_validator_path, user_sk):
from planetmint.commands.planetmint import run_election_new_upsert_validator
from planetmint.common.exceptions import InvalidPowerChange
from planetmint.transactions.common.exceptions import InvalidPowerChange
def mock_write(tx, mode):
b.store_bulk_transactions([tx])

View File

@ -100,31 +100,31 @@ def user2_Ed25519(user2_pub):
@pytest.fixture
def user_input(user_Ed25519, user_pub):
from planetmint.common.transaction import Input
from planetmint.transactions.common.transaction import Input
return Input(user_Ed25519, [user_pub])
@pytest.fixture
def user_user2_threshold_output(user_user2_threshold, user_pub, user2_pub):
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
return Output(user_user2_threshold, [user_pub, user2_pub])
@pytest.fixture
def user_user2_threshold_input(user_user2_threshold, user_pub, user2_pub):
from planetmint.common.transaction import Input
from planetmint.transactions.common.transaction import Input
return Input(user_user2_threshold, [user_pub, user2_pub])
@pytest.fixture
def user_output(user_Ed25519, user_pub):
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
return Output(user_Ed25519, [user_pub])
@pytest.fixture
def user2_output(user2_Ed25519, user2_pub):
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
return Output(user2_Ed25519, [user2_pub])
@ -140,7 +140,7 @@ def data():
@pytest.fixture
def utx(user_input, user_output):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
return Transaction(Transaction.CREATE, {'data': None}, [user_input],
[user_output])
@ -152,8 +152,8 @@ def tx(utx, user_priv):
@pytest.fixture
def transfer_utx(user_output, user2_output, utx):
from planetmint.common.transaction import (Input, TransactionLink,
Transaction)
from planetmint.transactions.common.transaction import (
Input, TransactionLink, Transaction)
user_output = user_output.to_dict()
input = Input(utx.outputs[0].fulfillment,
user_output['public_keys'],

View File

@ -7,8 +7,8 @@ import pytest
from copy import deepcopy
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.common.memoize import to_dict, from_dict
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.transactions.common.memoize import to_dict, from_dict
pytestmark = pytest.mark.bdb

View File

@ -13,8 +13,8 @@ from hypothesis import given
from hypothesis.strategies import from_regex as regex
from pytest import raises
from planetmint.common.exceptions import SchemaValidationError
from planetmint.common.schema import (
from planetmint.transactions.common.exceptions import SchemaValidationError
from planetmint.transactions.common.schema import (
TX_SCHEMA_COMMON,
validate_transaction_schema,
)

View File

@ -21,7 +21,7 @@ pytestmark = mark.bdb
def test_input_serialization(ffill_uri, user_pub):
from planetmint.common.transaction import Input
from planetmint.transactions.common.transaction import Input
from cryptoconditions import Fulfillment
expected = {
@ -34,7 +34,7 @@ def test_input_serialization(ffill_uri, user_pub):
def test_input_deserialization_with_uri(ffill_uri, user_pub):
from planetmint.common.transaction import Input
from planetmint.transactions.common.transaction import Input
from cryptoconditions import Fulfillment
expected = Input(Fulfillment.from_uri(ffill_uri), [user_pub])
@ -50,7 +50,7 @@ def test_input_deserialization_with_uri(ffill_uri, user_pub):
@mark.skip(reason='None is tolerated because it is None before fulfilling.')
def test_input_deserialization_with_invalid_input(user_pub):
from planetmint.common.transaction import Input
from planetmint.transactions.common.transaction import Input
ffill = {
'owners_before': [user_pub],
@ -62,8 +62,8 @@ def test_input_deserialization_with_invalid_input(user_pub):
def test_input_deserialization_with_invalid_fulfillment_uri(user_pub):
from planetmint.common.exceptions import InvalidSignature
from planetmint.common.transaction import Input
from planetmint.transactions.common.exceptions import InvalidSignature
from planetmint.transactions.common.transaction import Input
ffill = {
'owners_before': [user_pub],
@ -75,7 +75,7 @@ def test_input_deserialization_with_invalid_fulfillment_uri(user_pub):
def test_input_deserialization_with_unsigned_fulfillment(ffill_uri, user_pub):
from planetmint.common.transaction import Input
from planetmint.transactions.common.transaction import Input
from cryptoconditions import Fulfillment
expected = Input(Fulfillment.from_uri(ffill_uri), [user_pub])
@ -90,7 +90,7 @@ def test_input_deserialization_with_unsigned_fulfillment(ffill_uri, user_pub):
def test_output_serialization(user_Ed25519, user_pub):
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
expected = {
'condition': {
@ -110,7 +110,7 @@ def test_output_serialization(user_Ed25519, user_pub):
def test_output_deserialization(user_Ed25519, user_pub):
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
expected = Output(user_Ed25519, [user_pub], 1)
cond = {
@ -130,7 +130,7 @@ def test_output_deserialization(user_Ed25519, user_pub):
def test_output_hashlock_serialization():
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
from cryptoconditions import PreimageSha256
secret = b'wow much secret'
@ -149,7 +149,7 @@ def test_output_hashlock_serialization():
def test_output_hashlock_deserialization():
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
from cryptoconditions import PreimageSha256
secret = b'wow much secret'
@ -169,8 +169,8 @@ def test_output_hashlock_deserialization():
def test_invalid_output_initialization(cond_uri, user_pub):
from planetmint.common.transaction import Output
from planetmint.common.exceptions import AmountError
from planetmint.transactions.common.transaction import Output
from planetmint.transactions.common.exceptions import AmountError
with raises(TypeError):
Output(cond_uri, user_pub)
@ -181,7 +181,7 @@ def test_invalid_output_initialization(cond_uri, user_pub):
def test_generate_output_split_half_recursive(user_pub, user2_pub, user3_pub):
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
from cryptoconditions import Ed25519Sha256, ThresholdSha256
expected_simple1 = Ed25519Sha256(public_key=b58decode(user_pub))
@ -201,7 +201,7 @@ def test_generate_output_split_half_recursive(user_pub, user2_pub, user3_pub):
def test_generate_outputs_split_half_single_owner(user_pub,
user2_pub, user3_pub):
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
from cryptoconditions import Ed25519Sha256, ThresholdSha256
expected_simple1 = Ed25519Sha256(public_key=b58decode(user_pub))
@ -220,7 +220,7 @@ def test_generate_outputs_split_half_single_owner(user_pub,
def test_generate_outputs_flat_ownage(user_pub, user2_pub, user3_pub):
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
from cryptoconditions import Ed25519Sha256, ThresholdSha256
expected_simple1 = Ed25519Sha256(public_key=b58decode(user_pub))
@ -237,7 +237,7 @@ def test_generate_outputs_flat_ownage(user_pub, user2_pub, user3_pub):
def test_generate_output_single_owner(user_pub):
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
from cryptoconditions import Ed25519Sha256
expected = Ed25519Sha256(public_key=b58decode(user_pub))
@ -247,7 +247,7 @@ def test_generate_output_single_owner(user_pub):
def test_generate_output_single_owner_with_output(user_pub):
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
from cryptoconditions import Ed25519Sha256
expected = Ed25519Sha256(public_key=b58decode(user_pub))
@ -257,8 +257,8 @@ def test_generate_output_single_owner_with_output(user_pub):
def test_generate_output_invalid_parameters(user_pub, user2_pub, user3_pub):
from planetmint.common.transaction import Output
from planetmint.common.exceptions import AmountError
from planetmint.transactions.common.transaction import Output
from planetmint.transactions.common.exceptions import AmountError
with raises(ValueError):
Output.generate([], 1)
@ -273,7 +273,7 @@ def test_generate_output_invalid_parameters(user_pub, user2_pub, user3_pub):
def test_invalid_transaction_initialization(asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
with raises(ValueError):
Transaction(operation='invalid operation', asset=asset_definition)
@ -305,7 +305,7 @@ def test_invalid_transaction_initialization(asset_definition):
def test_create_default_asset_on_tx_initialization(asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
expected = {'data': None}
tx = Transaction(Transaction.CREATE, asset=expected)
@ -315,7 +315,7 @@ def test_create_default_asset_on_tx_initialization(asset_definition):
def test_transaction_serialization(user_input, user_output, data):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
expected = {
'id': None,
@ -339,14 +339,14 @@ def test_transaction_serialization(user_input, user_output, data):
def test_transaction_deserialization(tri_state_transaction):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
from .utils import validate_transaction_model
tx = Transaction.from_dict(tri_state_transaction)
validate_transaction_model(tx)
def test_invalid_input_initialization(user_input, user_pub):
from planetmint.common.transaction import Input
from planetmint.transactions.common.transaction import Input
with raises(TypeError):
Input(user_input, user_pub)
@ -355,7 +355,7 @@ def test_invalid_input_initialization(user_input, user_pub):
def test_transaction_link_serialization():
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
tx_id = 'a transaction id'
expected = {
@ -368,7 +368,7 @@ def test_transaction_link_serialization():
def test_transaction_link_serialization_with_empty_payload():
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
expected = None
tx_link = TransactionLink()
@ -377,7 +377,7 @@ def test_transaction_link_serialization_with_empty_payload():
def test_transaction_link_deserialization():
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
tx_id = 'a transaction id'
expected = TransactionLink(tx_id, 0)
@ -391,7 +391,7 @@ def test_transaction_link_deserialization():
def test_transaction_link_deserialization_with_empty_payload():
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
expected = TransactionLink()
tx_link = TransactionLink.from_dict(None)
@ -400,7 +400,7 @@ def test_transaction_link_deserialization_with_empty_payload():
def test_transaction_link_empty_to_uri():
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
expected = None
tx_link = TransactionLink().to_uri()
@ -409,7 +409,7 @@ def test_transaction_link_empty_to_uri():
def test_transaction_link_to_uri():
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
expected = 'path/transactions/abc/outputs/0'
tx_link = TransactionLink('abc', 0).to_uri('path')
@ -418,7 +418,7 @@ def test_transaction_link_to_uri():
def test_cast_transaction_link_to_boolean():
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
assert bool(TransactionLink()) is False
assert bool(TransactionLink('a', None)) is False
@ -428,7 +428,7 @@ def test_cast_transaction_link_to_boolean():
def test_transaction_link_eq():
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
assert TransactionLink(1, 2) == TransactionLink(1, 2)
assert TransactionLink(2, 2) != TransactionLink(1, 2)
@ -437,7 +437,7 @@ def test_transaction_link_eq():
def test_add_input_to_tx(user_input, asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
from .utils import validate_transaction_model
tx = Transaction(Transaction.CREATE, asset_definition, [], [])
@ -449,7 +449,7 @@ def test_add_input_to_tx(user_input, asset_definition):
def test_add_input_to_tx_with_invalid_parameters(asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx = Transaction(Transaction.CREATE, asset_definition)
with raises(TypeError):
@ -457,7 +457,7 @@ def test_add_input_to_tx_with_invalid_parameters(asset_definition):
def test_add_output_to_tx(user_output, user_input, asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
from .utils import validate_transaction_model
tx = Transaction(Transaction.CREATE, asset_definition, [user_input])
@ -469,7 +469,7 @@ def test_add_output_to_tx(user_output, user_input, asset_definition):
def test_add_output_to_tx_with_invalid_parameters(asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx = Transaction(Transaction.CREATE, asset_definition, [], [])
with raises(TypeError):
@ -485,7 +485,7 @@ def test_sign_with_invalid_parameters(utx, user_priv):
def test_validate_tx_simple_create_signature(user_input, user_output, user_priv,
asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
from .utils import validate_transaction_model
tx = Transaction(Transaction.CREATE, asset_definition, [user_input], [user_output])
@ -507,7 +507,7 @@ def test_validate_tx_simple_create_signature(user_input, user_output, user_priv,
def test_invoke_simple_signature_fulfillment_with_invalid_params(utx,
user_input):
from planetmint.common.exceptions import KeypairMismatchException
from planetmint.transactions.common.exceptions import KeypairMismatchException
with raises(KeypairMismatchException):
invalid_key_pair = {'wrong_pub_key': 'wrong_priv_key'}
@ -518,7 +518,7 @@ def test_invoke_simple_signature_fulfillment_with_invalid_params(utx,
def test_sign_threshold_with_invalid_params(utx, user_user2_threshold_input,
user3_pub, user3_priv):
from planetmint.common.exceptions import KeypairMismatchException
from planetmint.transactions.common.exceptions import KeypairMismatchException
with raises(KeypairMismatchException):
utx._sign_threshold_signature_fulfillment(user_user2_threshold_input,
@ -532,7 +532,7 @@ def test_sign_threshold_with_invalid_params(utx, user_user2_threshold_input,
def test_validate_input_with_invalid_parameters(utx):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
input_conditions = [out.fulfillment.condition_uri for out in utx.outputs]
tx_dict = utx.to_dict()
@ -548,7 +548,7 @@ def test_validate_tx_threshold_create_signature(user_user2_threshold_input,
user_priv,
user2_priv,
asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
from .utils import validate_transaction_model
tx = Transaction(Transaction.CREATE, asset_definition,
@ -576,7 +576,7 @@ def test_validate_tx_threshold_create_signature(user_user2_threshold_input,
def test_validate_tx_threshold_duplicated_pk(user_pub, user_priv,
asset_definition):
from cryptoconditions import Ed25519Sha256, ThresholdSha256
from planetmint.common.transaction import Input, Output, Transaction
from planetmint.transactions.common.transaction import Input, Output, Transaction
threshold = ThresholdSha256(threshold=2)
threshold.add_subfulfillment(
@ -621,8 +621,8 @@ def test_multiple_input_validation_of_transfer_tx(user_input, user_output,
user2_priv, user3_pub,
user3_priv,
asset_definition):
from planetmint.common.transaction import (Transaction, TransactionLink,
Input, Output)
from planetmint.transactions.common.transaction import (
Transaction, TransactionLink, Input, Output)
from cryptoconditions import Ed25519Sha256
from .utils import validate_transaction_model
@ -647,7 +647,7 @@ def test_multiple_input_validation_of_transfer_tx(user_input, user_output,
def test_validate_inputs_of_transfer_tx_with_invalid_params(
transfer_tx, cond_uri, utx, user2_pub, user_priv, ffill_uri):
from planetmint.common.transaction import Output
from planetmint.transactions.common.transaction import Output
from cryptoconditions import Ed25519Sha256
invalid_out = Output(Ed25519Sha256.from_uri(ffill_uri), ['invalid'])
@ -668,7 +668,7 @@ def test_validate_inputs_of_transfer_tx_with_invalid_params(
def test_create_create_transaction_single_io(user_output, user_pub, data):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
from .utils import validate_transaction_model
expected = {
@ -703,7 +703,7 @@ def test_create_create_transaction_single_io(user_output, user_pub, data):
def test_validate_single_io_create_transaction(user_pub, user_priv, data,
asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx = Transaction.create([user_pub], [([user_pub], 1)], metadata=data)
tx = tx.sign([user_priv])
@ -712,7 +712,7 @@ def test_validate_single_io_create_transaction(user_pub, user_priv, data,
def test_create_create_transaction_multiple_io(user_output, user2_output, user_pub,
user2_pub, asset_definition):
from planetmint.common.transaction import Transaction, Input
from planetmint.transactions.common.transaction import Transaction, Input
# a fulfillment for a create transaction with multiple `owners_before`
# is a fulfillment for an implicit threshold condition with
@ -739,7 +739,7 @@ def test_create_create_transaction_multiple_io(user_output, user2_output, user_p
def test_validate_multiple_io_create_transaction(user_pub, user_priv,
user2_pub, user2_priv,
asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
from .utils import validate_transaction_model
tx = Transaction.create([user_pub, user2_pub],
@ -754,7 +754,7 @@ def test_validate_multiple_io_create_transaction(user_pub, user_priv,
def test_create_create_transaction_threshold(user_pub, user2_pub, user3_pub,
user_user2_threshold_output,
user_user2_threshold_input, data):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
expected = {
'outputs': [user_user2_threshold_output.to_dict()],
@ -785,7 +785,7 @@ def test_create_create_transaction_threshold(user_pub, user2_pub, user3_pub,
def test_validate_threshold_create_transaction(user_pub, user_priv, user2_pub,
data, asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
from .utils import validate_transaction_model
tx = Transaction.create([user_pub], [([user_pub, user2_pub], 1)],
@ -797,7 +797,7 @@ def test_validate_threshold_create_transaction(user_pub, user_priv, user2_pub,
def test_create_create_transaction_with_invalid_parameters(user_pub):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
with raises(TypeError):
Transaction.create('not a list')
@ -832,7 +832,7 @@ def test_outputs_to_inputs(tx):
def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub,
user2_output, user_priv):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
from .utils import validate_transaction_model
expected = {
@ -887,7 +887,7 @@ def test_create_transfer_transaction_multiple_io(user_pub, user_priv,
user2_pub, user2_priv,
user3_pub, user2_output,
asset_definition):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx = Transaction.create([user_pub], [([user_pub], 1), ([user2_pub], 1)],
metadata={'message': 'hello'})
@ -941,7 +941,7 @@ def test_create_transfer_transaction_multiple_io(user_pub, user_priv,
def test_create_transfer_with_invalid_parameters(tx, user_pub):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
with raises(TypeError):
Transaction.transfer({}, [], tx.id)
@ -964,7 +964,7 @@ def test_create_transfer_with_invalid_parameters(tx, user_pub):
def test_cant_add_empty_output():
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx = Transaction(Transaction.CREATE, None)
with raises(TypeError):
@ -972,7 +972,7 @@ def test_cant_add_empty_output():
def test_cant_add_empty_input():
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx = Transaction(Transaction.CREATE, None)
with raises(TypeError):
@ -980,7 +980,7 @@ def test_cant_add_empty_input():
def test_unfulfilled_transaction_serialized(unfulfilled_transaction):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx_obj = Transaction.from_dict(unfulfilled_transaction)
expected = json.dumps(unfulfilled_transaction, sort_keys=True,
separators=(',', ':'), ensure_ascii=True)
@ -988,7 +988,7 @@ def test_unfulfilled_transaction_serialized(unfulfilled_transaction):
def test_fulfilled_transaction_serialized(fulfilled_transaction):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx_obj = Transaction.from_dict(fulfilled_transaction)
expected = json.dumps(fulfilled_transaction, sort_keys=True,
separators=(',', ':'), ensure_ascii=True)
@ -996,7 +996,7 @@ def test_fulfilled_transaction_serialized(fulfilled_transaction):
def test_transaction_hash(fulfilled_transaction):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx_obj = Transaction.from_dict(fulfilled_transaction)
assert tx_obj._id is None
assert tx_obj.id is None
@ -1009,8 +1009,8 @@ def test_transaction_hash(fulfilled_transaction):
def test_output_from_dict_invalid_amount(user_output):
from planetmint.common.transaction import Output
from planetmint.common.exceptions import AmountError
from planetmint.transactions.common.transaction import Output
from planetmint.transactions.common.exceptions import AmountError
out = user_output.to_dict()
out['amount'] = 'a'
@ -1019,7 +1019,7 @@ def test_output_from_dict_invalid_amount(user_output):
def test_unspent_outputs_property(merlin, alice, bob, carol):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx = Transaction.create(
[merlin.public_key],
[([alice.public_key], 1),

View File

@ -5,8 +5,8 @@
def validate_transaction_model(tx):
from planetmint.common.transaction import Transaction
from planetmint.common.schema import validate_transaction_schema
from planetmint.transactions.common.transaction import Transaction
from planetmint.transactions.common.schema import validate_transaction_schema
tx_dict = tx.to_dict()
# Check that a transaction is valid by re-serializing it

View File

@ -23,13 +23,13 @@ import pytest
from pymongo import MongoClient
from planetmint import ValidatorElection
from planetmint.common import crypto
from planetmint.common.transaction_mode_types import BROADCAST_TX_COMMIT
from planetmint.transactions.common import crypto
from planetmint.transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT
from planetmint.tendermint_utils import key_from_base64
from planetmint.backend import schema, query
from planetmint.common.crypto import (key_pair_from_ed25519_key,
public_key_from_ed25519_key)
from planetmint.common.exceptions import DatabaseDoesNotExist
from planetmint.transactions.common.crypto import (
key_pair_from_ed25519_key, public_key_from_ed25519_key)
from planetmint.transactions.common.exceptions import DatabaseDoesNotExist
from planetmint.lib import Block
from tests.utils import gen_vote
@ -149,7 +149,7 @@ def _bdb(_setup_database, _configure_planetmint):
from planetmint import config
from planetmint.backend import connect
from .utils import flush_db
from planetmint.common.memoize import to_dict, from_dict
from planetmint.transactions.common.memoize import to_dict, from_dict
from planetmint.models import Transaction
conn = connect()
yield
@ -205,13 +205,13 @@ def user2_pk():
@pytest.fixture
def alice():
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
return generate_key_pair()
@pytest.fixture
def bob():
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
return generate_key_pair()
@ -227,7 +227,7 @@ def bob_pubkey(carol):
@pytest.fixture
def carol():
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
return generate_key_pair()
@ -243,7 +243,7 @@ def carol_pubkey(carol):
@pytest.fixture
def merlin():
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
return generate_key_pair()

View File

@ -15,7 +15,7 @@ class TestBigchainApi(object):
def test_get_spent_with_double_spend_detected(self, b, alice):
from planetmint.models import Transaction
from planetmint.common.exceptions import DoubleSpend
from planetmint.transactions.common.exceptions import DoubleSpend
from planetmint.exceptions import CriticalDoubleSpend
tx = Transaction.create([alice.public_key], [([alice.public_key], 1)])
@ -81,8 +81,8 @@ class TestBigchainApi(object):
@pytest.mark.usefixtures('inputs')
def test_non_create_input_not_found(self, b, user_pk):
from cryptoconditions import Ed25519Sha256
from planetmint.common.exceptions import InputDoesNotExist
from planetmint.common.transaction import Input, TransactionLink
from planetmint.transactions.common.exceptions import InputDoesNotExist
from planetmint.transactions.common.transaction import Input, TransactionLink
from planetmint.models import Transaction
# Create an input for a non existing transaction
@ -117,8 +117,8 @@ class TestBigchainApi(object):
class TestTransactionValidation(object):
def test_non_create_input_not_found(self, b, signed_transfer_tx):
from planetmint.common.exceptions import InputDoesNotExist
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.exceptions import InputDoesNotExist
from planetmint.transactions.common.transaction import TransactionLink
signed_transfer_tx.inputs[0].fulfills = TransactionLink('c', 0)
with pytest.raises(InputDoesNotExist):
@ -126,8 +126,8 @@ class TestTransactionValidation(object):
@pytest.mark.usefixtures('inputs')
def test_non_create_valid_input_wrong_owner(self, b, user_pk):
from planetmint.common.crypto import generate_key_pair
from planetmint.common.exceptions import InvalidSignature
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.transactions.common.exceptions import InvalidSignature
from planetmint.models import Transaction
input_tx = b.fastquery.get_outputs_by_public_key(user_pk).pop()
@ -144,7 +144,7 @@ class TestTransactionValidation(object):
@pytest.mark.usefixtures('inputs')
def test_non_create_double_spend(self, b, signed_create_tx,
signed_transfer_tx, double_spend_tx):
from planetmint.common.exceptions import DoubleSpend
from planetmint.transactions.common.exceptions import DoubleSpend
b.store_bulk_transactions([signed_create_tx, signed_transfer_tx])
@ -156,7 +156,7 @@ class TestMultipleInputs(object):
def test_transfer_single_owner_single_input(self, b, inputs, user_pk,
user_sk):
from planetmint.common import crypto
from planetmint.transactions.common import crypto
from planetmint.models import Transaction
user2_sk, user2_pk = crypto.generate_key_pair()
@ -177,7 +177,7 @@ class TestMultipleInputs(object):
user_sk,
user_pk,
inputs):
from planetmint.common import crypto
from planetmint.transactions.common import crypto
from planetmint.models import Transaction
user2_sk, user2_pk = crypto.generate_key_pair()
@ -199,7 +199,7 @@ class TestMultipleInputs(object):
user_sk,
user_pk,
alice):
from planetmint.common import crypto
from planetmint.transactions.common import crypto
from planetmint.models import Transaction
user2_sk, user2_pk = crypto.generate_key_pair()
@ -227,7 +227,7 @@ class TestMultipleInputs(object):
user_sk,
user_pk,
alice):
from planetmint.common import crypto
from planetmint.transactions.common import crypto
from planetmint.models import Transaction
user2_sk, user2_pk = crypto.generate_key_pair()
@ -252,8 +252,8 @@ class TestMultipleInputs(object):
assert len(tx.outputs) == 1
def test_get_owned_ids_single_tx_single_output(self, b, user_sk, user_pk, alice):
from planetmint.common import crypto
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common import crypto
from planetmint.transactions.common.transaction import TransactionLink
from planetmint.models import Transaction
user2_sk, user2_pk = crypto.generate_key_pair()
@ -280,8 +280,8 @@ class TestMultipleInputs(object):
def test_get_owned_ids_single_tx_multiple_outputs(self, b, user_sk,
user_pk, alice):
from planetmint.common import crypto
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common import crypto
from planetmint.transactions.common.transaction import TransactionLink
from planetmint.models import Transaction
user2_sk, user2_pk = crypto.generate_key_pair()
@ -314,8 +314,8 @@ class TestMultipleInputs(object):
TransactionLink(tx_transfer.id, 1)]
def test_get_owned_ids_multiple_owners(self, b, user_sk, user_pk, alice):
from planetmint.common import crypto
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common import crypto
from planetmint.transactions.common.transaction import TransactionLink
from planetmint.models import Transaction
user2_sk, user2_pk = crypto.generate_key_pair()
@ -346,7 +346,7 @@ class TestMultipleInputs(object):
assert not spent_user1
def test_get_spent_single_tx_single_output(self, b, user_sk, user_pk, alice):
from planetmint.common import crypto
from planetmint.transactions.common import crypto
from planetmint.models import Transaction
user2_sk, user2_pk = crypto.generate_key_pair()
@ -372,7 +372,7 @@ class TestMultipleInputs(object):
assert spent_inputs_user1 == tx
def test_get_spent_single_tx_multiple_outputs(self, b, user_sk, user_pk, alice):
from planetmint.common import crypto
from planetmint.transactions.common import crypto
from planetmint.models import Transaction
# create a new users
@ -409,7 +409,7 @@ class TestMultipleInputs(object):
assert b.get_spent(tx_create.to_inputs()[2].fulfills.txid, 2) is None
def test_get_spent_multiple_owners(self, b, user_sk, user_pk, alice):
from planetmint.common import crypto
from planetmint.transactions.common import crypto
from planetmint.models import Transaction
user2_sk, user2_pk = crypto.generate_key_pair()
@ -445,7 +445,7 @@ class TestMultipleInputs(object):
def test_get_outputs_filtered_only_unspent():
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
from planetmint.lib import Planetmint
go = 'planetmint.fastquery.FastQuery.get_outputs_by_public_key'
@ -461,7 +461,7 @@ def test_get_outputs_filtered_only_unspent():
def test_get_outputs_filtered_only_spent():
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
from planetmint.lib import Planetmint
go = 'planetmint.fastquery.FastQuery.get_outputs_by_public_key'
with patch(go) as get_outputs:
@ -478,7 +478,7 @@ def test_get_outputs_filtered_only_spent():
@patch('planetmint.fastquery.FastQuery.filter_unspent_outputs')
@patch('planetmint.fastquery.FastQuery.filter_spent_outputs')
def test_get_outputs_filtered(filter_spent, filter_unspent):
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
from planetmint.lib import Planetmint
go = 'planetmint.fastquery.FastQuery.get_outputs_by_public_key'
@ -497,7 +497,7 @@ def test_cant_spend_same_input_twice_in_tx(b, alice):
https://github.com/planetmint/planetmint/issues/1099
"""
from planetmint.models import Transaction
from planetmint.common.exceptions import DoubleSpend
from planetmint.transactions.common.exceptions import DoubleSpend
# create a divisible asset
tx_create = Transaction.create([alice.public_key], [([alice.public_key], 100)])
@ -517,7 +517,7 @@ def test_cant_spend_same_input_twice_in_tx(b, alice):
def test_transaction_unicode(b, alice):
import copy
from planetmint.common.utils import serialize
from planetmint.transactions.common.utils import serialize
from planetmint.models import Transaction
# http://www.fileformat.info/info/unicode/char/1f37a/index.htm

View File

@ -3,7 +3,7 @@ import pytest
from tests.utils import generate_election, generate_validators
from planetmint.lib import Block
from planetmint.elections.election import Election
from planetmint.transactions.types.elections.election import Election
from planetmint.migrations.chain_migration_election import ChainMigrationElection
from planetmint.upsert_validator.validator_election import ValidatorElection

View File

@ -12,11 +12,11 @@ from tendermint.crypto import keys_pb2
from planetmint import App
from planetmint.backend.localmongodb import query
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.core import (OkCode,
CodeTypeError,
rollback)
from planetmint.elections.election import Election
from planetmint.transactions.types.elections.election import Election
from planetmint.lib import Block
from planetmint.migrations.chain_migration_election import ChainMigrationElection
from planetmint.upsert_validator.validator_election import ValidatorElection
@ -203,7 +203,7 @@ def test_info(b):
def test_check_tx__signed_create_is_ok(b):
from planetmint import App
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
bob = generate_key_pair()
@ -220,7 +220,7 @@ def test_check_tx__signed_create_is_ok(b):
def test_check_tx__unsigned_create_is_error(b):
from planetmint import App
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
bob = generate_key_pair()
@ -237,7 +237,7 @@ def test_deliver_tx__valid_create_updates_db_and_emits_event(b, init_chain_reque
import multiprocessing as mp
from planetmint import App
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
bob = generate_key_pair()
@ -274,7 +274,7 @@ def test_deliver_tx__valid_create_updates_db_and_emits_event(b, init_chain_reque
def test_deliver_tx__double_spend_fails(b, init_chain_request):
from planetmint import App
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
bob = generate_key_pair()
@ -303,7 +303,7 @@ def test_deliver_tx__double_spend_fails(b, init_chain_request):
def test_deliver_transfer_tx__double_spend_fails(b, init_chain_request):
from planetmint import App
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
app = App(b)
app.init_chain(init_chain_request)

View File

@ -5,7 +5,7 @@
import pytest
from planetmint.common.transaction import TransactionLink
from planetmint.transactions.common.transaction import TransactionLink
from planetmint.models import Transaction

View File

@ -13,7 +13,7 @@ import pytest
from abci.server import ProtocolHandler
from abci.utils import read_messages
from planetmint.common.transaction_mode_types import BROADCAST_TX_COMMIT, BROADCAST_TX_SYNC
from planetmint.transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT, BROADCAST_TX_SYNC
from planetmint.version import __tm_supported_versions__
from io import BytesIO
@ -22,7 +22,7 @@ from io import BytesIO
def test_app(b, eventqueue_fixture, init_chain_request):
from planetmint import App
from planetmint.tendermint_utils import calculate_hash
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.models import Transaction
app = App(b, eventqueue_fixture)
@ -113,7 +113,7 @@ def test_app(b, eventqueue_fixture, init_chain_request):
@pytest.mark.abci
def test_post_transaction_responses(tendermint_ws_url, b):
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.models import Transaction
alice = generate_key_pair()

View File

@ -17,9 +17,8 @@ import pytest
from pymongo import MongoClient
from planetmint import backend
from planetmint.common.transaction_mode_types import (BROADCAST_TX_COMMIT,
BROADCAST_TX_ASYNC,
BROADCAST_TX_SYNC)
from planetmint.transactions.common.transaction_mode_types import (
BROADCAST_TX_COMMIT, BROADCAST_TX_ASYNC, BROADCAST_TX_SYNC)
from planetmint.lib import Block
@ -27,7 +26,7 @@ from planetmint.lib import Block
def test_asset_is_separated_from_transaciton(b):
import copy
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
bob = generate_key_pair()
@ -83,7 +82,7 @@ def test_get_empty_block(_0, _1, b):
def test_validation_error(b):
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
tx = Transaction.create([alice.public_key],
@ -98,7 +97,7 @@ def test_validation_error(b):
@patch('requests.post')
def test_write_and_post_transaction(mock_post, b):
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.tendermint_utils import encode_transaction
alice = generate_key_pair()
@ -125,7 +124,7 @@ def test_write_and_post_transaction(mock_post, b):
])
def test_post_transaction_valid_modes(mock_post, b, mode):
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
tx = Transaction.create([alice.public_key],
[([alice.public_key], 1)],
@ -140,8 +139,8 @@ def test_post_transaction_valid_modes(mock_post, b, mode):
def test_post_transaction_invalid_mode(b):
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.common.exceptions import ValidationError
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.transactions.common.exceptions import ValidationError
alice = generate_key_pair()
tx = Transaction.create([alice.public_key],
[([alice.public_key], 1)],
@ -357,7 +356,7 @@ def test_get_utxoset_merkle_root(b, utxoset):
def test_get_spent_transaction_critical_double_spend(b, alice, bob, carol):
from planetmint.models import Transaction
from planetmint.exceptions import CriticalDoubleSpend
from planetmint.common.exceptions import DoubleSpend
from planetmint.transactions.common.exceptions import DoubleSpend
asset = {'test': 'asset'}
@ -404,7 +403,7 @@ def test_get_spent_transaction_critical_double_spend(b, alice, bob, carol):
def test_validation_with_transaction_buffer(b):
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.models import Transaction
priv_key, pub_key = generate_key_pair()
@ -461,8 +460,8 @@ def test_migrate_abci_chain_generates_new_chains(b, chain, block_height,
def test_get_spent_key_order(b, user_pk, user_sk, user2_pk, user2_sk):
from planetmint import backend
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.common.exceptions import DoubleSpend
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.transactions.common.exceptions import DoubleSpend
alice = generate_key_pair()
bob = generate_key_pair()

View File

@ -298,7 +298,7 @@ def test_file_config():
def test_invalid_file_config():
from planetmint.config_utils import file_config
from planetmint.common import exceptions
from planetmint.transactions.common import exceptions
with patch('builtins.open', mock_open(read_data='{_INVALID_JSON_}')):
with pytest.raises(exceptions.ConfigurationError):
file_config()

View File

@ -12,11 +12,11 @@ from tendermint.crypto import keys_pb2
from planetmint import App
from planetmint.backend.localmongodb import query
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.core import (OkCode,
CodeTypeError,
rollback)
from planetmint.elections.election import Election
from planetmint.transactions.types.elections.election import Election
from planetmint.lib import Block
from planetmint.migrations.chain_migration_election import ChainMigrationElection
from planetmint.upsert_validator.validator_election import ValidatorElection
@ -203,7 +203,7 @@ def test_info(b):
def test_check_tx__signed_create_is_ok(b):
from planetmint import App
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
bob = generate_key_pair()
@ -220,7 +220,7 @@ def test_check_tx__signed_create_is_ok(b):
def test_check_tx__unsigned_create_is_error(b):
from planetmint import App
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
bob = generate_key_pair()
@ -237,7 +237,7 @@ def test_deliver_tx__valid_create_updates_db_and_emits_event(b, init_chain_reque
import multiprocessing as mp
from planetmint import App
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
bob = generate_key_pair()
@ -274,7 +274,7 @@ def test_deliver_tx__valid_create_updates_db_and_emits_event(b, init_chain_reque
def test_deliver_tx__double_spend_fails(b, eventqueue_fixture, init_chain_request):
from planetmint import App
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
bob = generate_key_pair()
@ -303,7 +303,7 @@ def test_deliver_tx__double_spend_fails(b, eventqueue_fixture, init_chain_reques
def test_deliver_transfer_tx__double_spend_fails(b, init_chain_request):
from planetmint import App
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
app = App(b)
app.init_chain(init_chain_request)

View File

@ -5,7 +5,7 @@
import pytest
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.models import Transaction

View File

@ -19,7 +19,7 @@ def valid_upsert_validator_election_b(b, node_key, new_validator):
@pytest.fixture
@patch('planetmint.elections.election.uuid4', lambda: 'mock_uuid4')
@patch('planetmint.transactions.types.elections.election.uuid4', lambda: 'mock_uuid4')
def fixed_seed_election(b_mock, node_key, new_validator):
voters = ValidatorElection.recipients(b_mock)
return ValidatorElection.generate([node_key.public_key],

View File

@ -6,14 +6,14 @@
import pytest
import codecs
from planetmint.elections.election import Election
from planetmint.transactions.types.elections.election import Election
from planetmint.tendermint_utils import public_key_to_base64
from planetmint.upsert_validator import ValidatorElection
from planetmint.common.exceptions import AmountError
from planetmint.common.crypto import generate_key_pair
from planetmint.common.exceptions import ValidationError
from planetmint.common.transaction_mode_types import BROADCAST_TX_COMMIT
from planetmint.elections.vote import Vote
from planetmint.transactions.common.exceptions import AmountError
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.transactions.common.exceptions import ValidationError
from planetmint.transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT
from planetmint.transactions.types.elections.vote import Vote
from tests.utils import generate_block, gen_vote
pytestmark = [pytest.mark.execute]

View File

@ -9,11 +9,9 @@ import pytest
from planetmint.tendermint_utils import public_key_to_base64
from planetmint.upsert_validator import ValidatorElection
from planetmint.common.exceptions import (DuplicateTransaction,
UnequalValidatorSet,
InvalidProposer,
MultipleInputsError,
InvalidPowerChange)
from planetmint.transactions.common.exceptions import (
DuplicateTransaction, UnequalValidatorSet, InvalidProposer,
MultipleInputsError, InvalidPowerChange)
pytestmark = pytest.mark.bdb
@ -27,7 +25,7 @@ def test_upsert_validator_valid_election(b_mock, new_validator, node_key):
def test_upsert_validator_invalid_election_public_key(b_mock, new_validator, node_key):
from planetmint.common.exceptions import InvalidPublicKey
from planetmint.transactions.common.exceptions import InvalidPublicKey
for iv in ['ed25519-base32', 'ed25519-base64']:
new_validator['public_key']['type'] = iv
@ -51,7 +49,7 @@ def test_upsert_validator_invalid_power_election(b_mock, new_validator, node_key
def test_upsert_validator_invalid_proposed_election(b_mock, new_validator, node_key):
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
voters = ValidatorElection.recipients(b_mock)
@ -63,7 +61,7 @@ def test_upsert_validator_invalid_proposed_election(b_mock, new_validator, node_
def test_upsert_validator_invalid_inputs_election(b_mock, new_validator, node_key):
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
voters = ValidatorElection.recipients(b_mock)
@ -74,7 +72,7 @@ def test_upsert_validator_invalid_inputs_election(b_mock, new_validator, node_ke
election.validate(b_mock)
@patch('planetmint.elections.election.uuid4', lambda: 'mock_uuid4')
@patch('planetmint.transactions.types.elections.election.uuid4', lambda: 'mock_uuid4')
def test_upsert_validator_invalid_election(b_mock, new_validator, node_key, fixed_seed_election):
voters = ValidatorElection.recipients(b_mock)
duplicate_election = ValidatorElection.generate([node_key.public_key],

View File

@ -11,9 +11,9 @@ from functools import singledispatch
from planetmint.backend.localmongodb.connection import LocalMongoDBConnection
from planetmint.backend.schema import TABLES
from planetmint.common import crypto
from planetmint.common.transaction_mode_types import BROADCAST_TX_COMMIT
from planetmint.elections.election import Election, Vote
from planetmint.transactions.common import crypto
from planetmint.transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT
from planetmint.transactions.types.elections.election import Election, Vote
from planetmint.tendermint_utils import key_to_base64
@ -29,7 +29,7 @@ def flush_localmongo_db(connection, dbname):
def generate_block(planet):
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.models import Transaction
alice = generate_key_pair()

View File

@ -16,10 +16,10 @@ except ImportError:
import sha3
from unittest.mock import MagicMock
from planetmint.common.exceptions import (AmountError,
SchemaValidationError,
ThresholdTooDeep)
from planetmint.transactions.common.exceptions import (
AmountError, SchemaValidationError, ThresholdTooDeep)
from planetmint.models import Transaction
from planetmint.transactions.common.utils import _fulfillment_to_details, _fulfillment_from_details
################################################################################
# Helper functions
@ -54,8 +54,8 @@ def test_tx_serialization_hash_function(signed_create_tx):
def test_tx_serialization_with_incorrect_hash(signed_create_tx):
from planetmint.common.transaction import Transaction
from planetmint.common.exceptions import InvalidHash
from planetmint.transactions.common.transaction import Transaction
from planetmint.transactions.common.exceptions import InvalidHash
tx = signed_create_tx.to_dict()
tx['id'] = 'a' * 64
with pytest.raises(InvalidHash):
@ -63,7 +63,7 @@ def test_tx_serialization_with_incorrect_hash(signed_create_tx):
def test_tx_serialization_with_no_hash(signed_create_tx):
from planetmint.common.exceptions import InvalidHash
from planetmint.transactions.common.exceptions import InvalidHash
tx = signed_create_tx.to_dict()
del tx['id']
with pytest.raises(InvalidHash):
@ -104,7 +104,7 @@ def test_validate_fails_metadata_empty_dict(b, create_tx, alice):
# Asset
def test_transfer_asset_schema(user_sk, signed_transfer_tx):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx = signed_transfer_tx.to_dict()
validate(tx)
tx['id'] = None
@ -149,7 +149,7 @@ def test_no_inputs(b, create_tx, alice):
def test_create_single_input(b, create_tx, alice):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx = create_tx.to_dict()
tx['inputs'] += tx['inputs']
tx = Transaction.from_dict(tx).sign([alice.private_key]).to_dict()
@ -161,7 +161,7 @@ def test_create_single_input(b, create_tx, alice):
def test_create_tx_no_fulfills(b, create_tx, alice):
from planetmint.common.transaction import Transaction
from planetmint.transactions.common.transaction import Transaction
tx = create_tx.to_dict()
tx['inputs'][0]['fulfills'] = {'transaction_id': 'a' * 64,
'output_index': 0}
@ -213,8 +213,6 @@ def test_high_amounts(b, create_tx, alice):
# Conditions
def test_handle_threshold_overflow():
from planetmint.common import transaction
cond = {
'type': 'ed25519-sha-256',
'public_key': 'a' * 43,
@ -226,18 +224,17 @@ def test_handle_threshold_overflow():
'subconditions': [cond],
}
with pytest.raises(ThresholdTooDeep):
transaction._fulfillment_from_details(cond)
_fulfillment_from_details(cond)
def test_unsupported_condition_type():
from planetmint.common import transaction
from cryptoconditions.exceptions import UnsupportedTypeError
with pytest.raises(UnsupportedTypeError):
transaction._fulfillment_from_details({'type': 'a'})
_fulfillment_from_details({'type': 'a'})
with pytest.raises(UnsupportedTypeError):
transaction._fulfillment_to_details(MagicMock(type_name='a'))
_fulfillment_to_details(MagicMock(type_name='a'))
################################################################################

View File

@ -84,7 +84,7 @@ def test_get_outputs_endpoint_with_invalid_spent(client, user_pk):
@pytest.mark.abci
def test_get_divisble_transactions_returns_500(b, client):
from planetmint.models import Transaction
from planetmint.common import crypto
from planetmint.transactions.common import crypto
import json
TX_ENDPOINT = '/api/v1/transactions'

View File

@ -14,10 +14,9 @@ try:
except ImportError:
from sha3 import sha3_256
from planetmint.common import crypto
from planetmint.common.transaction_mode_types import (BROADCAST_TX_COMMIT,
BROADCAST_TX_ASYNC,
BROADCAST_TX_SYNC)
from planetmint.transactions.common import crypto
from planetmint.transactions.common.transaction_mode_types import (
BROADCAST_TX_COMMIT, BROADCAST_TX_ASYNC, BROADCAST_TX_SYNC)
TX_ENDPOINT = '/api/v1/transactions/'
@ -133,7 +132,7 @@ def test_post_create_transaction_with_invalid_key(b, client, field, value,
@pytest.mark.abci
@patch('planetmint.web.views.base.logger')
def test_post_create_transaction_with_invalid_id(mock_logger, b, client):
from planetmint.common.exceptions import InvalidHash
from planetmint.transactions.common.exceptions import InvalidHash
from planetmint.models import Transaction
user_priv, user_pub = crypto.generate_key_pair()
@ -170,7 +169,7 @@ def test_post_create_transaction_with_invalid_id(mock_logger, b, client):
def test_post_create_transaction_with_invalid_signature(mock_logger,
b,
client):
from planetmint.common.exceptions import InvalidSignature
from planetmint.transactions.common.exceptions import InvalidSignature
from planetmint.models import Transaction
user_priv, user_pub = crypto.generate_key_pair()
@ -274,7 +273,7 @@ def test_post_create_transaction_with_invalid_schema(mock_logger, client):
))
@patch('planetmint.web.views.base.logger')
def test_post_invalid_transaction(mock_logger, client, exc, msg, monkeypatch,):
from planetmint.common import exceptions
from planetmint.transactions.common import exceptions
exc_cls = getattr(exceptions, exc)
def mock_validation(self_, tx):
@ -326,7 +325,7 @@ def test_post_transfer_transaction_endpoint(client, user_pk, user_sk, posted_cre
@pytest.mark.abci
def test_post_invalid_transfer_transaction_returns_400(client, user_pk, posted_create_tx):
from planetmint.models import Transaction
from planetmint.common.exceptions import InvalidSignature
from planetmint.transactions.common.exceptions import InvalidSignature
transfer_tx = Transaction.transfer(posted_create_tx.to_inputs(),
[([user_pk], 1)],
@ -344,7 +343,7 @@ def test_post_invalid_transfer_transaction_returns_400(client, user_pk, posted_c
@pytest.mark.abci
def test_post_wrong_asset_division_transfer_returns_400(b, client, user_pk):
from planetmint.models import Transaction
from planetmint.common.exceptions import AmountError
from planetmint.transactions.common.exceptions import AmountError
priv_key, pub_key = crypto.generate_key_pair()
@ -425,7 +424,7 @@ def test_transactions_get_list_bad(client):
])
def test_post_transaction_valid_modes(mock_post, client, mode):
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
def _mock_post(*args, **kwargs):
return Mock(json=Mock(return_value={'result': {'code': 0}}))
@ -446,7 +445,7 @@ def test_post_transaction_valid_modes(mock_post, client, mode):
@pytest.mark.abci
def test_post_transaction_invalid_mode(client):
from planetmint.models import Transaction
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
alice = generate_key_pair()
tx = Transaction.create([alice.public_key],
[([alice.public_key], 1)],

View File

@ -22,7 +22,7 @@ class MockWebSocket:
def test_eventify_block_works_with_any_transaction():
from planetmint.web.websocket_server import eventify_block
from planetmint.common.crypto import generate_key_pair
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.lib import Transaction
alice = generate_key_pair()
@ -139,7 +139,7 @@ async def test_websocket_block_event(b, test_client, loop):
from planetmint import events
from planetmint.web.websocket_server import init_app, POISON_PILL, EVENTS_ENDPOINT
from planetmint.models import Transaction
from planetmint.common import crypto
from planetmint.transactions.common import crypto
user_priv, user_pub = crypto.generate_key_pair()
tx = Transaction.create([user_pub], [([user_pub], 1)])
@ -180,7 +180,7 @@ def test_integration_from_webapi_to_websocket(monkeypatch, client, loop):
import random
import aiohttp
from planetmint.common import crypto
from planetmint.transactions.common import crypto
# TODO processes does not exist anymore, when reactivating this test it
# will fail because of this
from planetmint import processes