planetmint/acceptance/python/src/test_analyse_tx.py
Jürgen Eckel 637dc4993b
Ipld (#256)
* added ipld dep

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* Cid tx schema (#252)

* changed asset and metadata schema to string

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* updated fixtures and adjusted some models and test cases

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* adjusted dependencies, fixtures and added comments

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* alignd TX inputs to be CID compatible

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* converted assets to CIDs

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* added multihashes

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* fixed data packaging for IPLD compatible test cases for the unit tests

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* Transaction hierarchy (#254)

* removed Transaction class from models.py, adjusted imports and function calls

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* removed comments

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* removed empty lines

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* resolved linting error

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* adjusted import path

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* added missing argument to mock

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* resolved linting error

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* adjusted mock func signature

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* fixed all unit tests

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* fixed zenroom acceptance test

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* adjusted common tx schema, fixed election validate

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>

* fixed an planetmint-ipld dependency that solved a package namespace collision in the dependencies of IPLD

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* disabled integration and acceptance tests as they rely on planetmint driver.
Plan is to resolve this circular dependency

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* adjusted acceptance tests to IPLD requirements

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* blackified

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* added missing imports

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

* blackified little changes

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>
Co-authored-by: Jürgen Eckel <juergen@riddleandcode.com>
Co-authored-by: Jürgen Eckel <eckelj@users.noreply.github.com>

* increased version
enforce ipld encodings to metadata and asset["data"]

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>
Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
Co-authored-by: Lorenz Herzberger <64837895+LaurentMontBlanc@users.noreply.github.com>
2022-09-16 00:13:51 +02:00

175 lines
7.2 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
# # Basic Acceptance Test
# Here we check that the primitives of the system behave as expected.
# As you will see, this script tests basic stuff like:
#
# - create a transaction
# - check if the transaction is stored
# - check for the outputs of a given public key
# - transfer the transaction to another key
#
# We run a series of checks for each steps, that is retrieving the transaction from
# the remote system, and also checking the `outputs` of a given public key.
# ## Imports
# We need some utils from the `os` package, we will interact with
# env variables.
import os
# For this test case we import and use the Python Driver.
from planetmint_driver import Planetmint
from planetmint_driver.crypto import generate_keypair
from ipld import multihash, marshal
def test_get_tests():
# ## Set up a connection to Planetmint
# To use BighainDB we need a connection. Here we create one. By default we
# connect to localhost, but you can override this value using the env variable
# called `PLANETMINT_ENDPOINT`, a valid value must include the schema:
# `https://example.com:9984`
bdb = Planetmint(os.environ.get("PLANETMINT_ENDPOINT"))
# ## Create keypairs
# This test requires the interaction between two actors with their own keypair.
# The two keypairs will be called—drum roll—Alice and Bob.
alice, bob = generate_keypair(), generate_keypair()
# ## Alice registers her bike in Planetmint
# Alice has a nice bike, and here she creates the "digital twin"
# of her bike.
bike = {"data": multihash(marshal({"bicycle": {"serial_number": 420420}}))}
# She prepares a `CREATE` transaction...
prepared_creation_tx = bdb.transactions.prepare(operation="CREATE", signers=alice.public_key, asset=bike)
# ... and she fulfills it with her private key.
fulfilled_creation_tx = bdb.transactions.fulfill(prepared_creation_tx, private_keys=alice.private_key)
# We will use the `id` of this transaction several time, so we store it in
# a variable with a short and easy name
bike_id = fulfilled_creation_tx["id"]
# Now she is ready to send it to the Planetmint Network.
sent_transfer_tx = bdb.transactions.send_commit(fulfilled_creation_tx)
# And just to be 100% sure, she also checks if she can retrieve
# it from the Planetmint node.
assert bdb.transactions.retrieve(bike_id), "Cannot find transaction {}".format(bike_id)
# Alice is now the proud owner of one unspent asset.
assert len(bdb.outputs.get(alice.public_key, spent=False)) == 1
assert bdb.outputs.get(alice.public_key)[0]["transaction_id"] == bike_id
# ## Alice transfers her bike to Bob
# After registering her bike, Alice is ready to transfer it to Bob.
# She needs to create a new `TRANSFER` transaction.
# A `TRANSFER` transaction contains a pointer to the original asset. The original asset
# is identified by the `id` of the `CREATE` transaction that defined it.
transfer_asset = {"id": bike_id}
# Alice wants to spend the one and only output available, the one with index `0`.
output_index = 0
output = fulfilled_creation_tx["outputs"][output_index]
# Here, she defines the `input` of the `TRANSFER` transaction. The `input` contains
# several keys:
#
# - `fulfillment`, taken from the previous `CREATE` transaction.
# - `fulfills`, that specifies which condition she is fulfilling.
# - `owners_before`.
transfer_input = {
"fulfillment": output["condition"]["details"],
"fulfills": {"output_index": output_index, "transaction_id": fulfilled_creation_tx["id"]},
"owners_before": output["public_keys"],
}
# Now that all the elements are set, she creates the actual transaction...
prepared_transfer_tx = bdb.transactions.prepare(
operation="TRANSFER", asset=transfer_asset, inputs=transfer_input, recipients=bob.public_key
)
# ... and signs it with her private key.
fulfilled_transfer_tx = bdb.transactions.fulfill(prepared_transfer_tx, private_keys=alice.private_key)
# She finally sends the transaction to a Planetmint node.
sent_transfer_tx = bdb.transactions.send_commit(fulfilled_transfer_tx)
# And just to be 100% sure, she also checks if she can retrieve
# it from the Planetmint node.
assert bdb.transactions.retrieve(fulfilled_transfer_tx["id"]) == sent_transfer_tx
# Now Alice has zero unspent transactions.
assert len(bdb.outputs.get(alice.public_key, spent=False)) == 0
# While Bob has one.copy
assert len(bdb.outputs.get(bob.public_key, spent=False)) == 1
# Bob double checks what he got was the actual bike.
bob_tx_id = bdb.outputs.get(bob.public_key, spent=False)[0]["transaction_id"]
assert bdb.transactions.retrieve(bob_tx_id) == sent_transfer_tx
transfer_asset = {"id": bike_id}
# Alice wants to spend the one and only output available, the one with index `0`.
output_index = 0
output = fulfilled_transfer_tx["outputs"][output_index]
# Here, she defines the `input` of the `TRANSFER` transaction. The `input` contains
# several keys:
#
# - `fulfillment`, taken from the previous `CREATE` transaction.
# - `fulfills`, that specifies which condition she is fulfilling.
# - `owners_before`.
transfer_input = {
"fulfillment": output["condition"]["details"],
"fulfills": {"output_index": output_index, "transaction_id": fulfilled_transfer_tx["id"]},
"owners_before": output["public_keys"],
}
# Now that all the elements are set, she creates the actual transaction...
prepared_transfer_tx = bdb.transactions.prepare(
operation="TRANSFER", asset=transfer_asset, inputs=transfer_input, recipients=bob.public_key
)
# ... and signs it with her private key.
fulfilled_transfer_tx = bdb.transactions.fulfill(prepared_transfer_tx, private_keys=bob.private_key)
# She finally sends the transaction to a Planetmint node.
sent_transfer_tx = bdb.transactions.send_commit(fulfilled_transfer_tx)
assert bdb.transactions.retrieve(fulfilled_transfer_tx["id"]) == sent_transfer_tx
# from urllib3 import request
import urllib3
import json
http = urllib3.PoolManager()
# verify that 3 transactions contain the asset_id
asset_id = bike_id
url = "http://planetmint:9984/api/v1/transactions?asset_id=" + asset_id
r = http.request("GET", url)
tmp_json = http.request("GET", url)
tmp_json = json.loads(tmp_json.data.decode("utf-8"))
assert len(tmp_json) == 3
# verify that one transaction is the create TX
url = "http://planetmint:9984/api/v1/transactions?asset_id=" + asset_id + "&operation=CREATE"
r = http.request("GET", url)
tmp_json = http.request("GET", url)
tmp_json = json.loads(tmp_json.data.decode("utf-8"))
assert len(tmp_json) == 1
# verify that 2 transactoins are of type transfer
url = "http://planetmint:9984/api/v1/transactions?asset_id=" + asset_id + "&operation=transfer"
r = http.request("GET", url)
tmp_json = http.request("GET", url)
tmp_json = json.loads(tmp_json.data.decode("utf-8"))
assert len(tmp_json) == 2