Skip to content
This repository has been archived by the owner on Aug 23, 2020. It is now read-only.

Commit

Permalink
Added step and bundlecreation
Browse files Browse the repository at this point in the history
  • Loading branch information
Brord van Wierst committed Mar 25, 2020
1 parent efd176d commit fc6a005
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 1 deletion.
28 changes: 28 additions & 0 deletions python-regression/tests/features/steps/transaction_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,34 @@ def create_inconsistent_transaction(step, node):

set_world_object(node, 'inconsistentTransactions', transaction_hash.hash)

@step(r'a split bundle is generated referencing the previous transaction with:')
def create_split_bundle(step):
"""
Create a bundle that reuses the last transaction from another bundle in its own
This test fails if we do not find the correct balance after confirming the second bundle(reattachment)
:param step.hashes: A gherkin table present in the feature file specifying the
arguments and the associated type.
"""
node = world.config['nodeId']
previous = world.responses['evaluate_and_send'][node][0]
seed = get_step_value(step, "seed")
api = api_utils.prepare_api_call(node, seed=seed)

tag = get_step_value(step, "tag")[0]
value = int(get_step_value(step, "value"))
addressTo = get_step_value(step, "address")[0]

response = api.get_inputs(start=0, stop=1, threshold=0, security_level=3)
addressFrom = response['inputs'][0]

bundles = bundle_scenario_setup.create_split_bundles(api, seed, addressFrom, addressTo, static.SPLIT_REST_ADDRESS, tag, value, previous)

api.broadcast_and_store(bundles[0].as_tryte_strings())
api.broadcast_and_store(bundles[1].as_tryte_strings())

set_previous_transaction(node, [bundles[1][0].hash])
set_world_object(node, "reattachSplitSpend", [bundles[1][0].hash])

@step(r'a stitching transaction is issued on "([^"]*)" with the tag "([^"]*)"')
def issue_stitching_transaction(step, node, tag):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,108 @@ def create_fake_transfer_bundle(api, seed, tag, value):
bundle.add_inputs([Address(addresses[0], value, 0, 1), Address(addresses[1], value, 1, 1)])
bundle.finalize()
bundle.sign_inputs(KeyGenerator(seed))
return bundle
return bundle

def create_split_bundles(api, seedFrom, addressFrom, addressTo, addressRest, tag, value, reference):
"""
Create a bundle that reuses the last transaction form another bundle in its own
:param api: Api used to create and attach the first bundle
:param seedfrom: The seed used for signing, addressFrom should be created form this
:param addressFrom: The address we will use as input
:param addressTo: The address we will use to send value to
:param addressRest: Where the rest of the balance gets send to, if any
:param tag: The tag that will be associated with the transaction
:param value: The value we will send
:param reference: The reference we use to connect the trunk with
"""
bundle1 = ProposedBundle()
bundle1.add_transaction(ProposedTransaction(
address = Address(addressTo),
tag = Tag(tag),
value = value
))
bundle1.add_inputs([Address(
addressFrom,
balance = addressFrom.balance,
key_index = addressFrom.key_index,
security_level = addressFrom.security_level
),
])
bundle1.send_unspent_inputs_to(Address(addressRest))
bundle1.finalize()
bundle1.sign_inputs(KeyGenerator(seedFrom))

gtta_response = api.get_transactions_to_approve(3)

trunk = reference
branch = gtta_response.get('branchTransaction')

attached_original_trytes = api.attach_to_tangle(trunk, branch, bundle1.as_tryte_strings()).get('trytes')

# So we have the original bundle attached, time to construct the new one
# We need to re-attach, but take special care, so we dont use the api, rather we do it ourself

re_attached_trytes = custom_attach(attached_original_trytes, 14)

original_bundle = Bundle.from_tryte_strings(attached_original_trytes)

re_attached_bundle = Bundle.from_tryte_strings(re_attached_trytes)
return [original_bundle, re_attached_bundle]

def custom_attach(trytes, mwm):
"""
Custom attach to to tangle.
Takes already attached bundle trytes, and except for the the head transaction,
updates `attachment_timestamp` and re-does the pow, resulting in a new
nonce and transaction hash.
The head transaction remains the same as in the original bundle.
:param trytes: List[TransactionTrytes]
:param mwm: int
"""
# Install the pow package together with pyota:
# $ pip install pyota[pow]
from pow.ccurl_interface import get_powed_tx_trytes, get_hash_trytes, \
get_current_ms

previoustx = None

# Construct bundle object
bundle = Bundle.from_tryte_strings(trytes)

# and we need the head tx first
for txn in reversed(bundle.transactions):
if (not previoustx): # this is the head transaction
# head tx stays the same, it is the original
previoustx = txn.hash
continue

# It is not a head transaction
# only updae the trunk reference
txn.trunk_transaction_hash = previoustx # the previous transaction
txn.attachment_timestamp = get_current_ms()

# Let's do the pow locally
txn_string = txn.as_tryte_string().__str__()
# returns a python unicode string
powed_txn_string = get_powed_tx_trytes(txn_string, mwm)
# construct trytestring from python string
powed_txn_trytes = TryteString(powed_txn_string)
# compute transaction hash
hash_string = get_hash_trytes(powed_txn_string)
hash_trytes = TryteString(hash_string)
hash_= TransactionHash(hash_trytes)

# Create powed txn object
powed_txn = Transaction.from_tryte_string(
trytes=powed_txn_trytes,
hash_=hash_
)

previoustx = powed_txn.hash
# put that back in the bundle
bundle.transactions[txn.current_index] = powed_txn
return bundle.as_tryte_strings()

0 comments on commit fc6a005

Please sign in to comment.