From c1b1c89f3f7aeab9a0756ff10cb4d8ca8ebf256d Mon Sep 17 00:00:00 2001
From: matograine <tom.ngr@zaclys.net>
Date: Fri, 14 Feb 2020 13:39:33 +0100
Subject: [PATCH] [feat] #281 limit input number and optimize document size *
 creation of constants :     * MAX_OUTPUTS,     * MAX_INPUTX_PER_TX,     *
 MAX_LINES_IN_TX_DOC,     * FIX_LINES, * creation of function
 max_inputs_number() * test for max_inputs_number()

---
 silkaj/tx.py          | 22 ++++++++++++++++++++++
 tests/test_unit_tx.py | 18 ++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/silkaj/tx.py b/silkaj/tx.py
index edbe3b16..061f5835 100644
--- a/silkaj/tx.py
+++ b/silkaj/tx.py
@@ -44,6 +44,17 @@ from duniterpy.documents.transaction import OutputSource, Unlock, SIGParameter
 MAX_COMMENT_LENGTH = 255
 
 
+# max size for tx doc is 100 lines. Formula for accepted field numbers is : (2 * IU + 2 * IS + O) <= ( MAX_LINES - FIX_LINES)
+# with IU = inputs/unlocks ; IS = Issuers/Signatures ; O = Outouts.
+MAX_LINES_IN_TX_DOC = 100
+# 2 lines are necessary, and we block 1 more for the comment
+FIX_LINES = 3
+# assuming there is only 1 issuer and 2 outputs, max inputs is 46
+MAX_INPUTS_PER_TX = 46
+# assuming there is 1 issuer and 1 input, max outputs is 93.
+MAX_OUTPUTS = 93
+
+
 @command("tx", help="Send transaction")
 @option(
     "amounts",
@@ -339,6 +350,17 @@ async def handle_intermediaries_transactions(
             break
 
 
+def max_inputs_number(outputs_number, issuers_number):
+    """
+    returns the maximum number of inputs.
+    This function does not take care of backchange line.
+    formula is IU <= (MAX_LINES - FIX_LINES - O - 2*IS)/2
+    """
+    return int(
+        (MAX_LINES_IN_TX_DOC - FIX_LINES - (2 * issuers_number) - outputs_number) / 2
+    )
+
+
 async def generate_and_send_transaction(
     key,
     issuers,
diff --git a/tests/test_unit_tx.py b/tests/test_unit_tx.py
index bcab87b3..5ab9d2ea 100644
--- a/tests/test_unit_tx.py
+++ b/tests/test_unit_tx.py
@@ -1471,3 +1471,21 @@ def test_generate_output(listoutput, unitbase, rest, recipient_address, expected
     assert len(expected) == len(listoutput)
     for e, o in zip(expected, listoutput):
         assert e == o
+
+
+# test max_inputs_number
+@pytest.mark.parametrize(
+    "outputs_number, issuers_number, expected",
+    [
+        (1, 1, 47),
+        (2, 1, 46),
+        (93, 1, 1),
+    ],
+)
+def test_max_inputs_number(outputs_number, issuers_number, expected):
+    """
+    returns the maximum number of inputs.
+    This function does not take care of backchange line.
+    formula is IU <= (MAX_LINES - FIX_LINES - O - 2*IS)/2
+    """
+    assert tx.max_inputs_number(outputs_number, issuers_number) == expected
-- 
GitLab