diff --git a/CHANGELOG.md b/CHANGELOG.md index 469cc5a..5e2708f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ For reference, the possible headings are: * **Known Issues** * **Notes** +## [1.4.0] - 2022-12-12 +* **Added** added upgrade compatibility to older nodes to support v2.0 TX validity for nodes supporting v3.0 transactions (planetmint-transactions >= 0.4.1) ## [1.3.2] - 2022-28-11 * **Changed** new zenroom 2.3.1 support diff --git a/planetmint/backend/tarantool/convert.py b/planetmint/backend/tarantool/convert.py index 571ef3f..f03757c 100644 --- a/planetmint/backend/tarantool/convert.py +++ b/planetmint/backend/tarantool/convert.py @@ -8,18 +8,19 @@ from planetmint.backend.utils import module_dispatch_registrar from planetmint.backend import convert from planetmint.backend.tarantool.connection import TarantoolDBConnection +from transactions import Transaction register_query = module_dispatch_registrar(convert) @register_query(TarantoolDBConnection) -def prepare_asset(connection, transaction_type, transaction_id, filter_operation, assets): - asset_id = transaction_id - if transaction_type not in filter_operation: - asset_id = assets[0]["id"] - return tuple([assets, transaction_id, asset_id]) +def prepare_asset(connection, transaction: Transaction, filter_operation, assets): + asset_id = transaction.id + if transaction.operation not in filter_operation: + asset_id = Transaction.read_out_asset_id(transaction) + return tuple([assets, transaction.id, asset_id]) @register_query(TarantoolDBConnection) -def prepare_metadata(connection, transaction_id, metadata): - return {"id": transaction_id, "metadata": metadata} +def prepare_metadata(connection, transaction: Transaction, metadata): + return {"id": transaction.id, "metadata": metadata} diff --git a/planetmint/lib.py b/planetmint/lib.py index 912a94c..e031edd 100644 --- a/planetmint/lib.py +++ b/planetmint/lib.py @@ -143,23 +143,24 @@ class Planetmint(object): assets = [] txn_metadatas = [] - for t in transactions: - transaction = t.tx_dict if t.tx_dict else rapidjson.loads(rapidjson.dumps(t.to_dict())) + for tx in transactions: + transaction = tx.tx_dict if tx.tx_dict else rapidjson.loads(rapidjson.dumps(tx.to_dict())) - tx_assets = transaction.pop("assets") + tx_assets = transaction.pop(Transaction.get_assets_tag(tx.version)) metadata = transaction.pop("metadata") tx_assets = backend.convert.prepare_asset( self.connection, - transaction_type=transaction["operation"], - transaction_id=transaction["id"], - filter_operation=[t.CREATE, t.VALIDATOR_ELECTION, t.CHAIN_MIGRATION_ELECTION], + tx, + filter_operation=[ + Transaction.CREATE, + Transaction.VALIDATOR_ELECTION, + Transaction.CHAIN_MIGRATION_ELECTION, + ], assets=tx_assets, ) - metadata = backend.convert.prepare_metadata( - self.connection, transaction_id=transaction["id"], metadata=metadata - ) + metadata = backend.convert.prepare_metadata(self.connection, tx, metadata=metadata) txn_metadatas.append(metadata) assets.append(tx_assets) @@ -437,7 +438,7 @@ class Planetmint(object): # validate asset id asset_id = tx.get_asset_id(input_txs) - if asset_id != tx.assets[0]["id"]: + if asset_id != Transaction.read_out_asset_id(tx): raise AssetIdMismatch(("The asset id of the input does not" " match the asset id of the" " transaction")) if not tx.inputs_valid(input_conditions): diff --git a/planetmint/version.py b/planetmint/version.py index 643df2c..874c6f9 100644 --- a/planetmint/version.py +++ b/planetmint/version.py @@ -3,8 +3,8 @@ # SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) # Code is Apache-2.0 and docs are CC-BY-4.0 -__version__ = "1.3.2" -__short_version__ = "1.3" +__version__ = "1.4.0" +__short_version__ = "1.4" # Supported Tendermint versions __tm_supported_versions__ = ["0.34.15"] diff --git a/planetmint/web/views/transactions.py b/planetmint/web/views/transactions.py index 2660588..39fe56c 100644 --- a/planetmint/web/views/transactions.py +++ b/planetmint/web/views/transactions.py @@ -92,6 +92,13 @@ class TransactionListApi(Resource): except ValidationError as e: return make_error(400, "Invalid transaction ({}): {}".format(type(e).__name__, e)) else: + if tx_obj.version != Transaction.VERSION: + return make_error( + 401, + "Invalid transaction version: The transaction is valid, \ + but this node only accepts transaction with higher \ + schema version number.", + ) status_code, message = planet.write_transaction(tx_obj, mode) if status_code == 202: diff --git a/setup.py b/setup.py index f41e21a..ba3b458 100644 --- a/setup.py +++ b/setup.py @@ -130,7 +130,7 @@ install_requires = [ "planetmint-ipld>=0.0.3", "pyasn1>=0.4.8", "python-decouple", - "planetmint-transactions>=0.2.2", + "planetmint-transactions>=0.4.1", ] setup( diff --git a/tests/assets/test_digital_assets.py b/tests/assets/test_digital_assets.py index eaf4a10..6d63211 100644 --- a/tests/assets/test_digital_assets.py +++ b/tests/assets/test_digital_assets.py @@ -73,3 +73,19 @@ def test_create_valid_divisible_asset(b, user_pk, user_sk): tx = Create.generate([user_pk], [([user_pk], 2)]) tx_signed = tx.sign([user_sk]) assert b.validate_transaction(tx_signed) == tx_signed + + +def test_v_2_0_validation_create(b, signed_2_0_create_tx): + validated = b.validate_transaction(signed_2_0_create_tx) + assert validated.to_dict() == signed_2_0_create_tx + + +def test_v_2_0_validation_create_invalid(b, signed_2_0_create_tx_assets): + assert b.validate_transaction(signed_2_0_create_tx_assets) + + +def test_v_2_0_validation_transfer(b, signed_2_0_create_tx, signed_2_0_transfer_tx): + validated = b.validate_transaction(signed_2_0_create_tx) + b.store_bulk_transactions([validated]) + assert validated.to_dict() == signed_2_0_create_tx + assert b.validate_transaction(signed_2_0_transfer_tx).to_dict() == signed_2_0_transfer_tx diff --git a/tests/conftest.py b/tests/conftest.py index 8ab02fc..f2cf233 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -770,3 +770,110 @@ def generate_votes(election, voters, keys): v = gen_vote(election, voter, keys) votes.append(v) return votes + + +@pytest.fixture +def signed_2_0_create_tx(): + return { + "inputs": [ + { + "owners_before": ["7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx"], + "fulfills": None, + "fulfillment": "pGSAIGC5nQ37hCCMAWIUBAJn4wVBOkHlURaWzWLjE5rTzG91gUC0Akx2m_AoPy1H6yTz7Ou2I-OGjNjWgvR5EATn8XZ1u-g91XL3CkSXXiL2sUJqDibJQJjGZjag_7fRu5_VkDUD", + } + ], + "outputs": [ + { + "public_keys": ["7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx"], + "condition": { + "details": { + "type": "ed25519-sha-256", + "public_key": "7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx", + }, + "uri": "ni:///sha-256;xtKK2YRiX7_EPF2harsf-PELcJwfHQM7jZ_YvilEOOI?fpt=ed25519-sha-256&cost=131072", + }, + "amount": "3000", + } + ], + "operation": "CREATE", + "metadata": "QmRBri4SARi56PgB2ALFVjHsLhQDUh4jYbeiHaU94vLoxd", + "asset": {"data": "QmW5GVMW98D3mktSDfWHS8nX2UiCd8gP1uCiujnFX4yK8n"}, + "version": "2.0", + "id": "334014a29d99a488789c711b7dc5fceb534d1a9290b14d0270dbe6b60e2f036e", + } + + +@pytest.fixture +def signed_2_0_create_tx_assets(): + return { + "inputs": [ + { + "owners_before": ["5V4AANHTSLdQH1mEA1pohW3jMduY9xMJ1voos7gRfMQF"], + "fulfills": None, + "fulfillment": "pGSAIEKelMEu8AzcA9kcDLrsEXhSpZG-lf2c9CuZpzZU_ONkgUBMztcnweWqwHVfVk9Y-IRgfdh864yXYTrTKzSMy6uvNjQeLtGzKxz4gjb01NUu6WLvZBAvr0Ws4glfxKiDLjkP", + } + ], + "outputs": [ + { + "public_keys": ["5V4AANHTSLdQH1mEA1pohW3jMduY9xMJ1voos7gRfMQF"], + "condition": { + "details": { + "type": "ed25519-sha-256", + "public_key": "5V4AANHTSLdQH1mEA1pohW3jMduY9xMJ1voos7gRfMQF", + }, + "uri": "ni:///sha-256;M3l9yVs7ItjP-lxT7B2ta6rpRa-GHt6TBSYpy8l-IS8?fpt=ed25519-sha-256&cost=131072", + }, + "amount": "3000", + } + ], + "operation": "CREATE", + "metadata": "QmRBri4SARi56PgB2ALFVjHsLhQDUh4jYbeiHaU94vLoxd", + "assets": {"data": "QmW5GVMW98D3mktSDfWHS8nX2UiCd8gP1uCiujnFX4yK8n"}, + "version": "2.0", + "id": "3e2a2c5eef5e6a0c4e1e5f8d0dc1d3d9b4f035592a9788f8bfa7d59f86d123d3", + } + + +@pytest.fixture +def signed_2_0_transfer_tx(): + return { + "inputs": [ + { + "owners_before": ["7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx"], + "fulfills": { + "transaction_id": "334014a29d99a488789c711b7dc5fceb534d1a9290b14d0270dbe6b60e2f036e", + "output_index": 0, + }, + "fulfillment": "pGSAIGC5nQ37hCCMAWIUBAJn4wVBOkHlURaWzWLjE5rTzG91gUBHNp8jobEyMqcIcIFl-TaAEDHRMyigDutgCIIomyVgb1a0LIk5eEpMTVP4ACxZnrVH-SIKEDHNdH4FGyBMka4B", + } + ], + "outputs": [ + { + "public_keys": ["3m1tUV5hmWPBaNQEoyFtZxFgDFiHYAYvPMzczNHwWp5v"], + "condition": { + "details": { + "type": "ed25519-sha-256", + "public_key": "3m1tUV5hmWPBaNQEoyFtZxFgDFiHYAYvPMzczNHwWp5v", + }, + "uri": "ni:///sha-256;4pXSmxViATpOG8Mcc0gYsa-4bjRnLk5MY06VXv_UeJA?fpt=ed25519-sha-256&cost=131072", + }, + "amount": "50", + }, + { + "public_keys": ["7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx"], + "condition": { + "details": { + "type": "ed25519-sha-256", + "public_key": "7WaJCRqUJMZjVyQxqq8GNjkw11gacFmDAZGPLdNxfBgx", + }, + "uri": "ni:///sha-256;xtKK2YRiX7_EPF2harsf-PELcJwfHQM7jZ_YvilEOOI?fpt=ed25519-sha-256&cost=131072", + }, + "amount": "2950", + }, + ], + "operation": "TRANSFER", + "metadata": "QmTjWHzypFxE8uuXJXMJQJxgAEKjoWmQimGiutmPyJ6CAB", + "asset": {"id": "334014a29d99a488789c711b7dc5fceb534d1a9290b14d0270dbe6b60e2f036e"}, + "version": "2.0", + "id": "e577641b0e2eb619e282f802516ce043e9d4af51dd4b6c959e18246e85cae2a6", + }