Skip to content
Snippets Groups Projects
Commit b39bed50 authored by matograine's avatar matograine
Browse files

[feat] #111: change functions to handle amounts list.

* modify
    * handle_intpermediary_transaction(),
    * generate_and_send_transaction(),
    * generate_transaction_document()
* all will now use tx_amounts list

* create a unit test for generate_transaction_document()
* create a patched head_block() function.

/!\ the created patched function does not return a whole fake block, only relevant infos for now.
parent 65211508
No related branches found
No related tags found
2 merge requests!146Merge dev into master branch to complete v0.8.0 development cycle,!108#111: Multiple amounts support for multi-recipients transaction
......@@ -267,12 +267,12 @@ async def get_list_input_for_transaction(pubkey, TXamount):
async def handle_intermediaries_transactions(
key, issuers, AmountTransfered, outputAddresses, Comment="", OutputbackChange=None
key, issuers, tx_amounts, outputAddresses, Comment="", OutputbackChange=None,
):
client = ClientInstance().client
while True:
listinput_and_amount = await get_list_input_for_transaction(
issuers, AmountTransfered * len(outputAddresses)
issuers, sum(tx_amounts)
)
intermediatetransaction = listinput_and_amount[2]
......@@ -281,9 +281,9 @@ async def handle_intermediaries_transactions(
await generate_and_send_transaction(
key,
issuers,
totalAmountInput,
[totalAmountInput],
listinput_and_amount,
issuers,
[issuers],
"Change operation",
)
sleep(1) # wait 1 second before sending a new transaction
......@@ -292,7 +292,7 @@ async def handle_intermediaries_transactions(
await generate_and_send_transaction(
key,
issuers,
AmountTransfered,
tx_amounts,
listinput_and_amount,
outputAddresses,
Comment,
......@@ -305,7 +305,7 @@ async def handle_intermediaries_transactions(
async def generate_and_send_transaction(
key,
issuers,
amount,
tx_amounts,
listinput_and_amount,
outputAddresses,
Comment,
......@@ -321,18 +321,14 @@ async def generate_and_send_transaction(
else:
print("Generate Transaction:")
print(" - From: " + issuers)
if isinstance(outputAddresses, str):
display_sent_tx(outputAddresses, amount)
else:
for outputAddress in outputAddresses:
display_sent_tx(outputAddress, amount)
if len(outputAddresses) > 1:
print(" - Total: " + str(amount / 100 * len(outputAddresses)))
for tx_amount, outputAddress in zip(tx_amounts, outputAddresses):
display_sent_tx(outputAddress, tx_amount)
print(" - Total: " + str(sum(tx_amounts) / 100))
client = ClientInstance().client
transaction = await generate_transaction_document(
issuers,
amount,
tx_amounts,
listinput_and_amount,
outputAddresses,
Comment,
......@@ -354,17 +350,16 @@ def display_sent_tx(outputAddress, amount):
async def generate_transaction_document(
issuers,
AmountTransfered,
tx_amounts,
listinput_and_amount,
outputAddresses,
Comment="",
OutputbackChange=None,
):
totalAmountTransfered = AmountTransfered * len(outputAddresses)
listinput = listinput_and_amount[0]
totalAmountInput = listinput_and_amount[1]
total_tx_amount = sum(tx_amounts)
head_block = await HeadBlock().head_block
currency_name = head_block["currency"]
......@@ -376,22 +371,18 @@ async def generate_transaction_document(
# if it's not a foreign exchange transaction, we remove units after 2 digits after the decimal point.
if issuers not in outputAddresses:
totalAmountTransfered = (
totalAmountTransfered // 10 ** curentUnitBase
total_tx_amount = (
total_tx_amount // 10 ** curentUnitBase
) * 10 ** curentUnitBase
# Generate output
################
listoutput = []
# Outputs to receiver (if not himself)
if isinstance(outputAddresses, str):
generate_output(listoutput, curentUnitBase, AmountTransfered, outputAddresses)
else:
for outputAddress in outputAddresses:
generate_output(listoutput, curentUnitBase, AmountTransfered, outputAddress)
for tx_amount, outputAddress in zip(tx_amounts, outputAddresses):
generate_output(listoutput, curentUnitBase, tx_amount, outputAddress)
# Outputs to himself
rest = totalAmountInput - totalAmountTransfered
rest = totalAmountInput - total_tx_amount
generate_output(listoutput, curentUnitBase, rest, OutputbackChange)
# Unlocks
......
......@@ -35,3 +35,14 @@ async def is_member(pubkey):
# mock CurrencySymbol().symbol
async def currency_symbol(self):
return G1_SYMBOL
## mock head_block()
async def head_block(self):
mocked_head_block = {
"number": 48000,
"unitbase": 0,
"currency": "g1",
"hash": "0000010D30B1284D34123E036B7BE0A449AE9F2B928A77D7D20E3BDEAC7EE14C",
}
return mocked_head_block
......@@ -4,12 +4,23 @@ from silkaj.tx import (
transaction_confirmation,
compute_amounts,
transaction_amount,
generate_transaction_document,
)
from silkaj.tui import display_pubkey, display_amount
from silkaj.money import UDValue
from silkaj.constants import G1_SYMBOL, MINIMAL_TX_AMOUNT, CENT_MULT_TO_UNIT
from silkaj.constants import G1_SYMBOL, CENT_MULT_TO_UNIT, MINIMAL_TX_AMOUNT
from duniterpy.documents.transaction import (
InputSource,
Transaction,
OutputSource,
Unlock,
SIGParameter,
)
from duniterpy.documents.block_uid import BlockUID
import patched
# truncBase()
@pytest.mark.parametrize(
"amount,base,expected",
......@@ -300,3 +311,118 @@ async def test_transaction_amount(
assert expected == await transaction_amount(
amounts, UDs_amounts, outputAddresses
)
# generate_transaction_document()
# expected results
# result 1 : with two amounts/outputs and an outputbackchange
result1 = Transaction(
version=10,
currency="g1",
blockstamp=BlockUID(
48000, "0000010D30B1284D34123E036B7BE0A449AE9F2B928A77D7D20E3BDEAC7EE14C"
),
locktime=0,
issuers=["BFb5yv8z1fowR6Z8mBXTALy5z7gHfMU976WtXhmRsUMh"],
inputs=[
InputSource(
10000,
0,
"T",
"B37D161185A760FD81C3242D73FABD3D01F4BD9EAD98C2842061A75BAD4DFA61",
1,
),
InputSource(
257,
0,
"T",
"16F1CF9C9B89BB8C34A945F56073AB3C3ACFD858D5FA420047BA7AED1575D1FE",
1,
),
],
unlocks=[
Unlock(index=0, parameters=[SIGParameter(0)]),
Unlock(index=1, parameters=[SIGParameter(0)]),
],
outputs=[
OutputSource(
amount=str(1000),
base=0,
condition="SIG(DBM6F5ChMJzpmkUdL5zD9UXKExmZGfQ1AgPDQy4MxSBw)",
),
OutputSource(
amount=str(4000),
base=0,
condition="SIG(4szFkvQ5tzzhwcfUtZD32hdoG2ZzhvG3ZtfR61yjnxdw)",
),
OutputSource(
amount=str(5000),
base=0,
condition="SIG(BFb5yv8z1fowR6Z8mBXTALy5z7gHfMU976WtXhmRsUMh)",
),
],
comment="Test comment",
signatures=[],
)
@pytest.mark.parametrize(
"issuers, tx_amounts, listinput_and_amount, outputAddresses, Comment, OutputbackChange, result",
[
# test 1 : with two amounts/outputs and an outputbackchange
(
"BFb5yv8z1fowR6Z8mBXTALy5z7gHfMU976WtXhmRsUMh",
(1000, 4000),
[
[
InputSource(
10000,
0,
"T",
"B37D161185A760FD81C3242D73FABD3D01F4BD9EAD98C2842061A75BAD4DFA61",
1,
),
InputSource(
257,
0,
"T",
"16F1CF9C9B89BB8C34A945F56073AB3C3ACFD858D5FA420047BA7AED1575D1FE",
1,
),
],
10000,
False,
],
(
"DBM6F5ChMJzpmkUdL5zD9UXKExmZGfQ1AgPDQy4MxSBw",
"4szFkvQ5tzzhwcfUtZD32hdoG2ZzhvG3ZtfR61yjnxdw",
),
"Test comment",
"BFb5yv8z1fowR6Z8mBXTALy5z7gHfMU976WtXhmRsUMh",
result1,
)
],
)
@pytest.mark.asyncio
async def test_generate_transaction_document(
issuers,
tx_amounts,
listinput_and_amount,
outputAddresses,
Comment,
OutputbackChange,
result,
monkeypatch,
):
# patch Head_block
monkeypatch.setattr("silkaj.network_tools.HeadBlock.get_head", patched.head_block)
assert result == await generate_transaction_document(
issuers,
tx_amounts,
listinput_and_amount,
outputAddresses,
Comment,
OutputbackChange,
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment