diff --git a/silkaj/tx.py b/silkaj/tx.py index b74be66a77091108838c0163b05cbddde1a65ebd..064dd02618146791db420ddf73ff0a3f8ba279f6 100644 --- a/silkaj/tx.py +++ b/silkaj/tx.py @@ -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 diff --git a/tests/patched.py b/tests/patched.py index 16b87d25dea40f0516d944918f7263a5f60be895..b7cfcfce1485c74cc03e580c265f4f1c0d709f77 100644 --- a/tests/patched.py +++ b/tests/patched.py @@ -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 diff --git a/tests/test_unit_tx.py b/tests/test_unit_tx.py index dd608cb40b6a05d9c33f9dc3984735005bdef71f..142171842b4f82f39c1fbdea1a139f453a2994a1 100644 --- a/tests/test_unit_tx.py +++ b/tests/test_unit_tx.py @@ -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, + )