mirror of
https://github.com/planetmint/planetmint.git
synced 2025-03-30 15:08:31 +00:00

* creating first github action Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * fix syntax error Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * renamed action, using black stable Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * updated checkout action on workflow black Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * formatted code with black Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * replaced lint with black service Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * removed black service added black check to makefile Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * replaced flake8 with black Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added pull_request to black actions trigger Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * replaced flake8 with black style checker (#212) * updated version number to 1.0.0 Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * creating first github action Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * fix syntax error Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * renamed action, using black stable Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * updated checkout action on workflow black Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * formatted code with black Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * version bumpt Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * removed some comments and unsused import Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * replaced lint with black service Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * removed black service added black check to makefile Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * replaced flake8 with black Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added pull_request to black actions trigger Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * started on unit test workflow Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * removed run step Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * fixed typo Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * testing docker-compose Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * check docker-compose Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * try running pytest Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * check out -f Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * changed path Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * increased health check retries, added job dependency Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added path to docker-compose.yml to test action Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * moved container startup to test step Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added checkout step to test job Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * different kind of execution Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * checking build step Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * fixed missing keyword Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added checkout to build step Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * storing artifacts Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added needs Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * changed Dockerfile-dev to python-slim Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added job matrix back in Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added abci to build job matrix Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * updated test job steps Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * fixed typo Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * replaced docker exec with docker-compose exec for abci test Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added first version of acceptance and integration test action Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added runs-on Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * fixed syntax error Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * reverted to docker exec Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added copyright notice and env to start container step Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * separated abci from non abci test job Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * renamed pytest workflow to unit-test Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added codecov workflow Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added pytest install to codecov step Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added pip install Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * moved codecov to unit-test Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * show files Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * changed paths Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * removed debug job steps Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * renamed black to lint, added audit workflow Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * checking if dc down is necessary Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * removed dc down step from acceptance and integration Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * fixed lint error Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added tox documentation to github acitons (#226) * added documentation job Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added docs dependency install to docs workflow Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * add more dependencies Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * install rapidjson manually Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added python-rapidjson to docs requirements text Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * changed gh config on tox.ini Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added base58 to docs require Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * changed docs require to dev Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * reversed changes to docs require Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * changed gh to gh-actions Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * increased verbosity for debugging Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * added -e docsroot manually Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * removed verbosity Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * removed travis ci files Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> * changed audit step to trigger on schedule Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com> Co-authored-by: enesturk <enes.m.turk@gmail.com>
266 lines
7.7 KiB
Python
266 lines
7.7 KiB
Python
# Copyright © 2020 Interplanetary Database Association e.V.,
|
|
# Planetmint and IPDB software contributors.
|
|
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
|
|
# Code is Apache-2.0 and docs are CC-BY-4.0
|
|
|
|
"""All tests of transaction structure. The concern here is that transaction
|
|
structural / schematic issues are caught when reading a transaction
|
|
(ie going from dict -> transaction).
|
|
"""
|
|
import json
|
|
|
|
import pytest
|
|
|
|
try:
|
|
import hashlib as sha3
|
|
except ImportError:
|
|
import sha3
|
|
from unittest.mock import MagicMock
|
|
|
|
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
|
|
|
|
|
|
def validate(tx):
|
|
if isinstance(tx, Transaction):
|
|
tx = tx.to_dict()
|
|
Transaction.from_dict(tx)
|
|
|
|
|
|
def validate_raises(tx, exc=SchemaValidationError):
|
|
with pytest.raises(exc):
|
|
validate(tx)
|
|
|
|
|
|
# We should test that validation works when we expect it to
|
|
def test_validation_passes(signed_create_tx):
|
|
Transaction.from_dict(signed_create_tx.to_dict())
|
|
|
|
|
|
################################################################################
|
|
# ID
|
|
|
|
|
|
def test_tx_serialization_hash_function(signed_create_tx):
|
|
tx = signed_create_tx.to_dict()
|
|
tx["id"] = None
|
|
payload = json.dumps(tx, skipkeys=False, sort_keys=True, separators=(",", ":"))
|
|
assert sha3.sha3_256(payload.encode()).hexdigest() == signed_create_tx.id
|
|
|
|
|
|
def test_tx_serialization_with_incorrect_hash(signed_create_tx):
|
|
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):
|
|
Transaction.validate_id(tx)
|
|
|
|
|
|
def test_tx_serialization_with_no_hash(signed_create_tx):
|
|
from planetmint.transactions.common.exceptions import InvalidHash
|
|
|
|
tx = signed_create_tx.to_dict()
|
|
del tx["id"]
|
|
with pytest.raises(InvalidHash):
|
|
Transaction.from_dict(tx)
|
|
|
|
|
|
################################################################################
|
|
# Operation
|
|
|
|
|
|
def test_validate_invalid_operation(b, create_tx, alice):
|
|
create_tx.operation = "something invalid"
|
|
signed_tx = create_tx.sign([alice.private_key])
|
|
validate_raises(signed_tx)
|
|
|
|
|
|
################################################################################
|
|
# Metadata
|
|
|
|
|
|
def test_validate_fails_metadata_empty_dict(b, create_tx, alice):
|
|
create_tx.metadata = {"a": 1}
|
|
signed_tx = create_tx.sign([alice.private_key])
|
|
validate(signed_tx)
|
|
|
|
create_tx._id = None
|
|
create_tx.fulfillment = None
|
|
create_tx.metadata = None
|
|
signed_tx = create_tx.sign([alice.private_key])
|
|
validate(signed_tx)
|
|
|
|
create_tx._id = None
|
|
create_tx.fulfillment = None
|
|
create_tx.metadata = {}
|
|
signed_tx = create_tx.sign([alice.private_key])
|
|
validate_raises(signed_tx)
|
|
|
|
|
|
################################################################################
|
|
# Asset
|
|
|
|
|
|
def test_transfer_asset_schema(user_sk, signed_transfer_tx):
|
|
from planetmint.transactions.common.transaction import Transaction
|
|
|
|
tx = signed_transfer_tx.to_dict()
|
|
validate(tx)
|
|
tx["id"] = None
|
|
tx["asset"]["data"] = {}
|
|
tx = Transaction.from_dict(tx).sign([user_sk]).to_dict()
|
|
validate_raises(tx)
|
|
tx["id"] = None
|
|
del tx["asset"]["data"]
|
|
tx["asset"]["id"] = "b" * 63
|
|
tx = Transaction.from_dict(tx).sign([user_sk]).to_dict()
|
|
validate_raises(tx)
|
|
|
|
|
|
def test_create_tx_no_asset_id(b, create_tx, alice):
|
|
create_tx.asset["id"] = "b" * 64
|
|
signed_tx = create_tx.sign([alice.private_key])
|
|
validate_raises(signed_tx)
|
|
|
|
|
|
def test_create_tx_asset_type(b, create_tx, alice):
|
|
create_tx.asset["data"] = "a"
|
|
signed_tx = create_tx.sign([alice.private_key])
|
|
validate_raises(signed_tx)
|
|
|
|
|
|
def test_create_tx_no_asset_data(b, create_tx, alice):
|
|
tx_body = create_tx.to_dict()
|
|
del tx_body["asset"]["data"]
|
|
tx_serialized = json.dumps(tx_body, skipkeys=False, sort_keys=True, separators=(",", ":"))
|
|
tx_body["id"] = sha3.sha3_256(tx_serialized.encode()).hexdigest()
|
|
validate_raises(tx_body)
|
|
|
|
|
|
################################################################################
|
|
# Inputs
|
|
|
|
|
|
def test_no_inputs(b, create_tx, alice):
|
|
create_tx.inputs = []
|
|
signed_tx = create_tx.sign([alice.private_key])
|
|
validate_raises(signed_tx)
|
|
|
|
|
|
def test_create_single_input(b, create_tx, alice):
|
|
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()
|
|
validate_raises(tx)
|
|
tx["id"] = None
|
|
tx["inputs"] = []
|
|
tx = Transaction.from_dict(tx).sign([alice.private_key]).to_dict()
|
|
validate_raises(tx)
|
|
|
|
|
|
def test_create_tx_no_fulfills(b, create_tx, alice):
|
|
from planetmint.transactions.common.transaction import Transaction
|
|
|
|
tx = create_tx.to_dict()
|
|
tx["inputs"][0]["fulfills"] = {"transaction_id": "a" * 64, "output_index": 0}
|
|
tx = Transaction.from_dict(tx).sign([alice.private_key]).to_dict()
|
|
validate_raises(tx)
|
|
|
|
|
|
def test_transfer_has_inputs(user_sk, signed_transfer_tx, alice):
|
|
signed_transfer_tx.inputs = []
|
|
signed_transfer_tx._id = None
|
|
signed_transfer_tx.sign([user_sk])
|
|
validate_raises(signed_transfer_tx)
|
|
|
|
|
|
################################################################################
|
|
# Outputs
|
|
|
|
|
|
def test_low_amounts(b, user_sk, create_tx, signed_transfer_tx, alice):
|
|
for sk, tx in [(alice.private_key, create_tx), (user_sk, signed_transfer_tx)]:
|
|
tx.outputs[0].amount = 0
|
|
tx._id = None
|
|
tx.sign([sk])
|
|
validate_raises(tx, AmountError)
|
|
tx.outputs[0].amount = -1
|
|
tx._id = None
|
|
tx.sign([sk])
|
|
validate_raises(tx)
|
|
|
|
|
|
def test_high_amounts(b, create_tx, alice):
|
|
# Should raise a SchemaValidationError - don't want to allow ridiculously
|
|
# large numbers to get converted to int
|
|
create_tx.outputs[0].amount = 10**21
|
|
create_tx.sign([alice.private_key])
|
|
validate_raises(create_tx)
|
|
# Should raise AmountError
|
|
create_tx.outputs[0].amount = 9 * 10**18 + 1
|
|
create_tx._id = None
|
|
create_tx.sign([alice.private_key])
|
|
validate_raises(create_tx, AmountError)
|
|
# Should pass
|
|
create_tx.outputs[0].amount -= 1
|
|
create_tx._id = None
|
|
create_tx.sign([alice.private_key])
|
|
validate(create_tx)
|
|
|
|
|
|
################################################################################
|
|
# Conditions
|
|
|
|
|
|
def test_handle_threshold_overflow():
|
|
cond = {
|
|
"type": "ed25519-sha-256",
|
|
"public_key": "a" * 43,
|
|
}
|
|
for i in range(1000):
|
|
cond = {
|
|
"type": "threshold-sha-256",
|
|
"threshold": 1,
|
|
"subconditions": [cond],
|
|
}
|
|
with pytest.raises(ThresholdTooDeep):
|
|
_fulfillment_from_details(cond)
|
|
|
|
|
|
def test_unsupported_condition_type():
|
|
from cryptoconditions.exceptions import UnsupportedTypeError
|
|
|
|
with pytest.raises(UnsupportedTypeError):
|
|
_fulfillment_from_details({"type": "a"})
|
|
|
|
with pytest.raises(UnsupportedTypeError):
|
|
_fulfillment_to_details(MagicMock(type_name="a"))
|
|
|
|
|
|
################################################################################
|
|
# Version
|
|
|
|
|
|
def test_validate_version(b, create_tx, alice):
|
|
create_tx.version = "2.0"
|
|
create_tx.sign([alice.private_key])
|
|
validate(create_tx)
|
|
|
|
create_tx.version = "0.10"
|
|
create_tx._id = None
|
|
create_tx.sign([alice.private_key])
|
|
validate_raises(create_tx)
|
|
|
|
create_tx.version = "110"
|
|
create_tx._id = None
|
|
create_tx.sign([alice.private_key])
|
|
validate_raises(create_tx)
|