From d21fac0010a5ec6fc348ae2537e8066542cb7a68 Mon Sep 17 00:00:00 2001
From: Evgeniy Kramsakov <sobiegrus@gmail.com>
Date: Thu, 25 Aug 2022 15:31:03 +0300
Subject: [PATCH] [*] Move hotfixes from master branch. Fix some math and
 str-to-256

---
 dap-sdk/core/include/dap_math_ops.h | 39 ++++++++++++++++++-----------
 modules/common/dap_chain_common.c   | 29 ++++++++++-----------
 2 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/dap-sdk/core/include/dap_math_ops.h b/dap-sdk/core/include/dap_math_ops.h
index 348c37c26e..4d16ade7f3 100755
--- a/dap-sdk/core/include/dap_math_ops.h
+++ b/dap-sdk/core/include/dap_math_ops.h
@@ -1022,21 +1022,20 @@ static inline int MULT_256_FRAC_FRAC(uint256_t a_val, uint256_t a_mult, uint256_
 static inline int MULT_256_COIN(uint256_t a_val, uint256_t b_val, uint256_t* result) {
     uint256_t tmp;
     uint256_t rem;
-    uint256_t ten17 = GET_256_FROM_64(100000000000000000ULL);
+    uint256_t ten18 = GET_256_FROM_64(1000000000000000000ULL);
     uint256_t ten = GET_256_FROM_64(10ULL);
     uint256_t five = GET_256_FROM_64(500000000000000000);
     int overflow = MULT_256_256(a_val, b_val, &tmp);
-    divmod_impl_256(tmp, ten17, &tmp, &rem);
+    divmod_impl_256(tmp, ten18, &tmp, &rem);
     if (compare256(rem, five) >= 0) {
         SUM_256_256(tmp, ten, &tmp);
     }
-    if (compare256(ten, uint256_0) != 0)
-        DIV_256(tmp, ten, result);
+    *result = tmp;
     return overflow;
 }
 
 /**
- * Divides to fixed-point values, represented as 256-bit values
+ * Divides two fixed-point values, represented as 256-bit values
  * @param a_val
  * @param b_val
  * @param result is a fixed-point value, represented as 256-bit value
@@ -1044,16 +1043,26 @@ static inline int MULT_256_COIN(uint256_t a_val, uint256_t b_val, uint256_t* res
  */
 static inline void DIV_256_COIN(uint256_t a, uint256_t b, uint256_t *res)
 {
-    // define 10^36
-#ifdef DAP_GLOBAL_IS_INT128
-    uint128_t quad = *(uint128_t *)"\x0\x0\x0\x0\x10\x9f\x4b\xb3\x15\x07\xc9\x7b\xce\x97\xc0\x0";
-#else
-    uint128_t quad = {.lo = 54210108624275221ULL, .hi = 12919594847110692864ULL};
-#endif
-    uint256_t quad256 = GET_256_FROM_128(quad);
-    uint256_t tmp = uint256_0;
-    DIV_256(quad256, b, &tmp);  // assertion with zero divisor inside
-    MULT_256_COIN(a, tmp, res);
+    if (compare256(a, uint256_0) == 0) {
+        *res = uint256_0;
+        return;
+    }
+    int counter = 0;
+    uint256_t a_copy = a;
+    uint256_t ten18 = GET_256_FROM_64(1000000000000000000ULL);
+    uint256_t ten = GET_256_FROM_64(10l);
+    while (compare256(a_copy, b) < 0) {
+        counter++;
+        MULT_256_256(a_copy, ten, &a_copy);
+    }
+    DIV_256(a_copy, b, &a_copy);
+    MULT_256_256(a_copy, ten18, &a_copy);
+    uint256_t loan = GET_256_FROM_64(1l);
+    while(counter--) {
+        MULT_256_256(loan, ten, &loan); //maybe we should use same table as in dap_chain_common.c instead of cycle ?
+    }
+    DIV_256(a_copy, loan, &a_copy);
+    *res = a_copy;
 }
 
 #ifdef __cplusplus
diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c
index e1ce522736..6a1c644986 100644
--- a/modules/common/dap_chain_common.c
+++ b/modules/common/dap_chain_common.c
@@ -274,7 +274,7 @@ uint128_t dap_chain_uint128_from_uint256(uint256_t a_from)
 
 char *dap_chain_balance_print128(uint128_t a_balance)
 {
-    char *l_buf = DAP_NEW_Z_SIZE(char, DATOSHI_POW + 3);
+    char *l_buf = DAP_NEW_Z_SIZE(char, DATOSHI_POW + 2);
     int l_pos = 0;
     uint128_t l_value = a_balance;
 #ifdef DAP_GLOBAL_IS_INT128
@@ -394,7 +394,7 @@ char *dap_chain_balance_to_coins256(uint256_t a_balance)
 const union __c_pow10__ {
     uint64_t u64[2];
     uint32_t u32[4];
-} DAP_ALIGN_PACKED c_pow10[DATOSHI_POW + 1] = {
+} DAP_ALIGN_PACKED c_pow10[DATOSHI_POW] = {
         { .u64 = {0,                         1ULL} },                          // 0
         { .u64 = {0,                         10ULL} },                         // 1
         { .u64 = {0,                         100ULL} },                        // 2
@@ -440,7 +440,7 @@ uint128_t dap_chain_balance_scan128(const char *a_balance)
 {
     int l_strlen = strlen(a_balance);
     uint128_t l_ret = uint128_0, l_nul = uint128_0;
-    if (l_strlen > DATOSHI_POW + 1)
+    if (l_strlen > DATOSHI_POW)
         return l_nul;
     for (int i = 0; i < l_strlen ; i++) {
         char c = a_balance[l_strlen - i - 1];
@@ -503,10 +503,10 @@ uint256_t dap_chain_balance_scan(const char *a_balance)
 
 uint128_t dap_chain_coins_to_balance128(const char *a_coins)
 {
-    char l_buf [DATOSHI_POW + 3] = {0};
+    char l_buf [DATOSHI_POW + 2] = {0};
     uint128_t l_ret = uint128_0, l_nul = uint128_0;
 
-    if (strlen(a_coins) > DATOSHI_POW + 2) {
+    if (strlen(a_coins) > DATOSHI_POW + 1) {
         log_it(L_WARNING, "Incorrect balance format - too long");
         return l_nul;
     }
@@ -569,9 +569,9 @@ uint256_t dap_chain_coins_to_balance256(const char *a_coins)
     uint256_t l_nul = {0};
 
     /* "12300000000.0000456" */
-    if ( (l_len = strnlen(a_coins, DATOSHI_POW256 + 3)) > DATOSHI_POW256 + 2)/* Check for legal length */ /* 1 symbol for \0, one for '.', if more, there is an error */
+    if ( (l_len = strnlen(a_coins, DATOSHI_POW256 + 1)) > DATOSHI_POW256)/* Check for legal length */ /* 1 symbol for \0, one for '.', if more, there is an error */
         return  log_it(L_WARNING, "Incorrect balance format of '%s' - too long (%d > %d)", a_coins,
-                       l_len, DATOSHI_POW256 + 2), l_nul;
+                       l_len, DATOSHI_POW256), l_nul;
 
     /* Find , check and remove 'precision' dot symbol */
     memcpy (l_buf, a_coins, l_len);                                         /* Make local copy */
@@ -605,7 +605,7 @@ uint256_t dap_chain_coins_to_balance256(const char *a_coins)
 
 
 char *dap_cvt_uint256_to_str(uint256_t a_uint256) {
-    char *l_buf = DAP_NEW_Z_SIZE(char, DATOSHI_POW256 + 3);
+    char *l_buf = DAP_NEW_Z_SIZE(char, DATOSHI_POW256 + 1);
 #ifdef DAP_GLOBAL_IS_INT128
     int l_pos = 0;
     uint256_t l_value = a_uint256;
@@ -631,7 +631,7 @@ char *dap_cvt_uint256_to_str(uint256_t a_uint256) {
 const union __c_pow10_double__ {
     uint64_t u64[4];
     uint32_t u32[8];
-} DAP_ALIGN_PACKED c_pow10_double[DATOSHI_POW * 2 + 1] = {
+} DAP_ALIGN_PACKED c_pow10_double[DATOSHI_POW256] = {
         { .u64 = {0,                            0,                           0,                         1ULL} },                          // 0
         { .u64 = {0,                            0,                           0,                         10ULL} },                         // 1
         { .u64 = {0,                            0,                           0,                         100ULL} },                        // 2
@@ -709,6 +709,7 @@ const union __c_pow10_double__ {
         { .u64 = {15930919111324522ULL,         14209320429820033867ULL,     8387114520361296896ULL,    0ULL} },                            // 74
         { .u64 = {159309191113245227ULL,        12965995782233477362ULL,     10084168908774762496ULL,   0ULL} },                            // 75
         { .u64 = {1593091911132452277ULL,       532749306367912313ULL,       8607968719199866880ULL,    0ULL} },                            // 76
+        { .u64 = {15930919111324522770ULL,       5327493063679123134ULL,       12292710897160462336ULL,    0ULL} },                         // 77
 };
 
 
@@ -731,7 +732,7 @@ uint256_t dap_cvt_str_to_uint256(const char *a_256bit_num)
 {
     uint256_t l_ret = uint256_0, l_nul = uint256_0;
     int  l_strlen;
-    char l_256bit_num[DAP_CHAIN$SZ_MAX256DEC];
+    char l_256bit_num[DAP_CHAIN$SZ_MAX256DEC + 1];
 
     /* Compute & check length */
     if ( (l_strlen = strnlen(a_256bit_num, DAP_CHAIN$SZ_MAX256DEC + 1) ) > DAP_CHAIN$SZ_MAX256DEC)
@@ -786,9 +787,9 @@ uint256_t dap_cvt_str_to_uint256(const char *a_256bit_num)
         l_tmp.hi = 0;
         l_tmp.lo = (uint128_t)c_pow10_double[i].u64[3] * (uint128_t) l_digit;
         SUM_256_256(l_ret, l_tmp, &l_ret);
-        if (l_ret.hi == 0 && l_ret.lo == 0) {
-            return l_nul;
-        }
+//        if (l_ret.hi == 0 && l_ret.lo == 0) {
+//            return l_nul;
+//        }
         uint128_t l_mul = (uint128_t) c_pow10_double[i].u64[2] * (uint128_t) l_digit;
         l_tmp.lo = l_mul << 64;
         l_tmp.hi = l_mul >> 64;
@@ -805,7 +806,7 @@ uint256_t dap_cvt_str_to_uint256(const char *a_256bit_num)
             return l_nul;
         }
 
-        l_mul = (uint128_t) c_pow10_double->u64[0] * (uint128_t) l_digit;
+        l_mul = (uint128_t) c_pow10_double[i].u64[0] * (uint128_t) l_digit;
         if (l_mul >> 64) {
             log_it(L_WARNING, "Input number is too big");
             return l_nul;
-- 
GitLab