diff --git a/dap-sdk/core/include/dap_math_ops.h b/dap-sdk/core/include/dap_math_ops.h index fb2a1708b7112125d9e5614d235a636459257b36..f3f3061f34d5d22a47d5b5595c63fa02f89265b1 100755 --- a/dap-sdk/core/include/dap_math_ops.h +++ b/dap-sdk/core/include/dap_math_ops.h @@ -1,4 +1,5 @@ #pragma once + #include <stdint.h> #include <stdio.h> #include "assert.h" @@ -13,18 +14,22 @@ #if __SIZEOF_INT128__ == 16 #define DAP_GLOBAL_IS_INT128 + +#endif + + +#ifdef DAP_GLOBAL_IS_INT128 typedef __int128 _dap_int128_t; -#if !defined (int128_t) +//#if !defined (int128_t) typedef __int128 int128_t; -#endif +//#endif -#if !defined (uint128_t) +//#if !defined (uint128_t) typedef unsigned __int128 uint128_t; -#endif - +//#endif -#else // __SIZEOF_INT128__ == 16 +#else //DAP_GLOBAL_IS_INT128 typedef union uint128 { struct{ @@ -40,25 +45,19 @@ typedef union int128 { int32_t i32[4]; } int128_t; -typedef int128_t _dap_int128_t; +#endif //DAP_GLOBAL_IS_INT128 -#endif // __SIZEOF_INT128__ == 16 +typedef int128_t _dap_int128_t; -typedef struct uint256_t { +typedef struct uint256 { uint128_t hi; uint128_t lo; +} uint256_t; - } uint256_t; - -typedef struct uint512_t { +typedef struct uint512 { uint256_t hi; uint256_t lo; - - } uint512_t; - - - - +} uint512_t; #endif //defined(__GNUC__) || defined (__clang__) @@ -66,18 +65,56 @@ typedef struct uint512_t { #ifndef DAP_GLOBAL_IS_INT128 +// uint128_t dap_uint128_substract(uint128_t a, uint128_t b); +// uint128_t dap_uint128_add(uint128_t a, uint128_t b); +// bool dap_uint128_check_equal(uint128_t a, uint128_t b); const uint128_t two_power_64={ .hi = 1, .lo = 0}; const uint128_t lo_64={ .hi = 0, .lo = 0xffffffffffffffff}; const uint128_t hi_64={ .hi = 0xffffffffffffffff, .lo = 0}; -const uint128_t zero_128={.hi=0,.lo=0}; +// const uint128_t zero_128={.hi=0,.lo=0}; +// #define zero_128 ((uint128_t){.hi=0,.lo=0}) + +#define uint128_0 ((uint128_t){.hi=0,.lo=0}) +#define uint128_1 ((uint128_t){.hi=0,.lo=1}) + +// const uint64_t lo_32=0xffffffff; +// const uint64_t hi_32=0xffffffff00000000; +// const uint64_t ones_64=0xffffffffffffffff; + +#else // DAP_GLOBAL_IS_INT128 + +// #define zero_128 ((uint128_t)0) +#define uint128_0 ((uint128_t)0) +#define uint128_1 ((uint128_t)1) -const uint256_t zero_256={.hi=zero_128,.lo=zero_128}; +#endif // DAP_GLOBAL_IS_INT128 -const uint64_t lo_32=0xffffffff; -const uint64_t hi_32=0xffffffff00000000; -const uint64_t ones_64=0xffffffffffffffff; +// const uint256_t zero_256={.hi=zero_128,.lo=zero_128}; +// #define zero_256 ((uint256_t){.hi=zero_128,.lo=zero_128}) +#define uint256_0 ((uint256_t){.hi=uint128_0,.lo=uint128_0}) +#define uint256_1 ((uint256_t){.hi=uint128_0,.lo=uint128_1}) +#define uint512_0 ((uint512_t){.hi=uint256_0,.lo=uint256_0}) +#define lo_32 ((uint64_t)0xffffffff) +#define hi_32 ((uint64_t)0xffffffff00000000) +#define ones_64 ((uint64_t)0xffffffffffffffff) + +static inline uint128_t GET_128_FROM_64(uint64_t n) { +#ifdef DAP_GLOBAL_IS_INT128 + return (uint128_t) n; +#else + return (uint128_t){.hi=0,.lo=n}; #endif +} + +static inline uint256_t GET_256_FROM_64(uint64_t n) { + return (uint256_t){.hi=uint128_0,.lo=GET_128_FROM_64(n)}; +} + +static inline uint256_t GET_256_FROM_128(uint128_t n) { + return (uint256_t){.hi=uint128_0,.lo=n}; +} + static inline bool EQUAL_128(uint128_t a_128_bit, uint128_t b_128_bit){ #ifdef DAP_GLOBAL_IS_INT128 @@ -86,7 +123,12 @@ static inline bool EQUAL_128(uint128_t a_128_bit, uint128_t b_128_bit){ return a_128_bit.lo==b_128_bit.lo && a_128_bit.hi==b_128_bit.hi; #endif } - + + +static inline bool IS_ZERO_128(uint128_t a_128_bit){ + return EQUAL_128(a_128_bit, uint128_0); +} + static inline bool EQUAL_256(uint256_t a_256_bit, uint256_t b_256_bit){ #ifdef DAP_GLOBAL_IS_INT128 @@ -100,17 +142,21 @@ static inline bool EQUAL_256(uint256_t a_256_bit, uint256_t b_256_bit){ #endif } +static inline bool IS_ZERO_256(uint256_t a_256_bit){ + + return a_256_bit.lo == (uint128_t)0; +} + + static inline uint128_t AND_128(uint128_t a_128_bit,uint128_t b_128_bit){ #ifdef DAP_GLOBAL_IS_INT128 return a_128_bit&b_128_bit; - #else - uint128_t output={ .hi = 0, .lo = 0}; + uint128_t output=uint128_0; output.hi= a_128_bit.hi & b_128_bit.hi; output.lo= a_128_bit.lo & b_128_bit.lo; return output; - #endif } @@ -119,69 +165,46 @@ static inline uint128_t OR_128(uint128_t a_128_bit,uint128_t b_128_bit){ #ifdef DAP_GLOBAL_IS_INT128 return a_128_bit|b_128_bit; -#else - uint128_t output={ .hi = 0, .lo = 0}; +#else + uint128_t output=uint128_0; output.hi= a_128_bit.hi | b_128_bit.hi; output.lo= a_128_bit.lo | b_128_bit.lo; return output; - #endif } static inline uint256_t AND_256(uint256_t a_256_bit,uint256_t b_256_bit){ - -#ifdef DAP_GLOBAL_IS_INT128 - uint256_t output = {}; - output.hi= a_256_bit.hi | b_256_bit.hi; - output.lo= a_256_bit.lo | b_256_bit.lo; + uint256_t output = uint256_0; + output.hi = AND_128(a_256_bit.hi, b_256_bit.hi); + output.lo = AND_128(a_256_bit.lo, b_256_bit.lo); return output; - -#else - uint256_t output={ .hi = zero_128, .lo = zero_128}; - output.hi= AND_128(a_256_bit.hi, b_256_bit.hi); - output.lo= AND_128(a_256_bit.lo, b_256_bit.lo); - return output; - -#endif } static inline uint256_t OR_256(uint256_t a_256_bit,uint256_t b_256_bit){ - -#ifdef DAP_GLOBAL_IS_INT128 - uint256_t output= {}; - output.hi= a_256_bit.hi | b_256_bit.hi; - output.lo= a_256_bit.lo | b_256_bit.lo; + uint256_t output = uint256_0; + output.hi = OR_128(a_256_bit.hi, b_256_bit.hi); + output.lo = OR_128(a_256_bit.lo, b_256_bit.lo); return output; - -#else - uint256_t output={ .hi = zero_128, .lo = zero_128}; - output.hi= OR_128(a_256_bit.hi, b_256_bit.hi); - output.lo= OR_128(a_256_bit.lo, b_256_bit.lo); - return output; - -#endif } static inline void LEFT_SHIFT_128(uint128_t a_128_bit,uint128_t* b_128_bit,int n){ assert (n <= 128); #ifdef DAP_GLOBAL_IS_INT128 - *b_128_bit=a_128_bit<<n; + *b_128_bit= a_128_bit << n; #else - if (n >= 64) // shifting 64-bit integer by more than 63 bits is not defined - { + if (n >= 64) { // shifting 64-bit integer by more than 63 bits is not defined a_128_bit.hi=a_128_bit.lo; a_128_bit.lo=0; LEFT_SHIFT_128(a_128_bit,b_128_bit,n-64); } - if (n == 0) - { + if (n == 0) { b_128_bit->hi=a_128_bit.hi; b_128_bit->lo=a_128_bit.lo; } - else - { uint64_t shift_temp; + else { + uint64_t shift_temp; shift_temp=a_128_bit.lo<<n; b_128_bit->lo=shift_temp; b_128_bit->hi=(a_128_bit.hi<<n)|(a_128_bit.lo>>(64-n)); @@ -195,9 +218,7 @@ static inline void RIGHT_SHIFT_128(uint128_t a_128_bit,uint128_t* b_128_bit,int #ifdef DAP_GLOBAL_IS_INT128 (*b_128_bit) = a_128_bit >> n; - #else - if (n >= 64) // shifting 64-bit integer by more than 63 bits is not defined { a_128_bit.lo=a_128_bit.hi; @@ -223,97 +244,48 @@ static inline void LEFT_SHIFT_256(uint256_t a_256_bit,uint256_t* b_256_bit,int n assert (n <= 256); -#ifdef DAP_GLOBAL_IS_INT128 - - if (n >= 128) - { - a_256_bit.hi=a_256_bit.lo; - a_256_bit.lo=0; - LEFT_SHIFT_256(a_256_bit,b_256_bit,n-128); - } - if (n == 0) - { - b_256_bit->hi=a_256_bit.hi; - b_256_bit->lo=a_256_bit.lo; - } - else - { uint128_t shift_temp; - shift_temp=a_256_bit.lo<<n; - b_256_bit->lo=shift_temp; - b_256_bit->hi=(a_256_bit.hi<<n)|(a_256_bit.lo>>(128-n)); - } - -#else - if (n >= 128) // shifting 64-bit integer by more than 63 bits is not defined - { + if (n >= 128) { // shifting 64-bit integer by more than 63 bits is not defined a_256_bit.hi=a_256_bit.lo; - a_256_bit.lo=zero_128; + a_256_bit.lo=uint128_0; LEFT_SHIFT_256(a_256_bit,b_256_bit,n-128); } - if (n == 0) - { + if (n == 0) { b_256_bit->hi=a_256_bit.hi; b_256_bit->lo=a_256_bit.lo; } - if (n<128) - { uint128_t shift_temp{.hi=0, .lo=0}; + if (n<128) { + uint128_t shift_temp=uint128_0; LEFT_SHIFT_128(a_256_bit.lo,&shift_temp,n); b_256_bit->lo=shift_temp; - uint128_t shift_temp_or_left{.hi=0, .lo=0}; - uint128_t shift_temp_or_right{.hi=0, .lo=0}; + uint128_t shift_temp_or_left=uint128_0; + uint128_t shift_temp_or_right=uint128_0; LEFT_SHIFT_128(a_256_bit.hi,&shift_temp_or_left,n); RIGHT_SHIFT_128(a_256_bit.lo,&shift_temp_or_right,128-n); b_256_bit->hi=OR_128(shift_temp_or_left,shift_temp_or_right); } -#endif } static inline void RIGHT_SHIFT_256(uint256_t a_256_bit,uint256_t* b_256_bit,int n){ assert (n <= 256); - -#ifdef DAP_GLOBAL_IS_INT128 - - if (n >= 128) - { - a_256_bit.lo=a_256_bit.hi; - a_256_bit.hi=0; - RIGHT_SHIFT_256(a_256_bit,b_256_bit,n-128); - } - if (n == 0) - { - b_256_bit->hi=a_256_bit.hi; - b_256_bit->lo=a_256_bit.lo; - } - else - { uint64_t shift_temp; - shift_temp=a_256_bit.hi>>n; - b_256_bit->hi=shift_temp; - b_256_bit->lo=(a_256_bit.lo>>n)|(a_256_bit.hi<<(128-n)); - } - -#else - if (n >= 128) // shifting 64-bit integer by more than 63 bits is not defined - { + if (n >= 128) { // shifting 64-bit integer by more than 63 bits is not defined a_256_bit.lo=a_256_bit.hi; - a_256_bit.hi=zero_128; + a_256_bit.hi=uint128_0; RIGHT_SHIFT_256(a_256_bit,b_256_bit,n-128); } - if (n == 0) - { + if (n == 0) { b_256_bit->hi=a_256_bit.hi; b_256_bit->lo=a_256_bit.lo; } - if (n<128) - { uint128_t shift_temp{.hi=0, .lo=0}; + if (n<128) { + uint128_t shift_temp=uint128_0; RIGHT_SHIFT_128(a_256_bit.hi,&shift_temp,n); b_256_bit->hi=shift_temp; - uint128_t shift_temp_or_left{.hi=0, .lo=0}; - uint128_t shift_temp_or_right{.hi=0, .lo=0}; + uint128_t shift_temp_or_left=uint128_0; + uint128_t shift_temp_or_right=uint128_0; RIGHT_SHIFT_128(a_256_bit.lo,&shift_temp_or_left,n); LEFT_SHIFT_128(a_256_bit.hi,&shift_temp_or_right,128-n); b_256_bit->lo=OR_128(shift_temp_or_left,shift_temp_or_right); } -#endif } static inline void INCR_128(uint128_t *a_128_bit){ @@ -330,20 +302,20 @@ static inline void INCR_128(uint128_t *a_128_bit){ #endif } -//static inline void DECR_128(uint128_t* a_128_bit){ -// -//#ifdef DAP_GLOBAL_IS_INT128 -// *a_128_bit--; -// -//#else -// a_128_bit->lo--; -// if(a_128_bit->hi == 0) -// { -// a_128_bit->hi--; -// } -//#endif -//} -// +static inline void DECR_128(uint128_t* a_128_bit){ + +#ifdef DAP_GLOBAL_IS_INT128 + (*a_128_bit)--; + +#else + a_128_bit->lo--; + if(a_128_bit->hi == 0) + { + a_128_bit->hi--; + } +#endif +} + static inline void INCR_256(uint256_t* a_256_bit){ #ifdef DAP_GLOBAL_IS_INT128 @@ -355,36 +327,39 @@ static inline void INCR_256(uint256_t* a_256_bit){ #else INCR_128(&a_256_bit->lo); - if(EQUAL_128(a_256_bit->lo, zero_128)) + if(EQUAL_128(a_256_bit->lo, uint128_0)) { INCR_128(&a_256_bit->hi); } #endif } -static inline int SUM_64_64(uint64_t a_64_bit,uint64_t b_64_bit,uint64_t* c_64_bit ) { - -int overflow_flag; -*c_64_bit=a_64_bit+b_64_bit; -overflow_flag=(*c_64_bit<a_64_bit); -return overflow_flag;} - - - -static inline int OVERFLOW_SUM_64_64(uint64_t a_64_bit,uint64_t b_64_bit) { +static inline int SUM_64_64(uint64_t a_64_bit,uint64_t b_64_bit,uint64_t* c_64_bit ) +{ + int overflow_flag; + *c_64_bit=a_64_bit+b_64_bit; + overflow_flag=(*c_64_bit<a_64_bit); + return overflow_flag; +} -int overflow_flag; -overflow_flag=(a_64_bit+b_64_bit<a_64_bit); -return overflow_flag;} +static inline int OVERFLOW_SUM_64_64(uint64_t a_64_bit,uint64_t b_64_bit) +{ + int overflow_flag; + overflow_flag=(a_64_bit+b_64_bit<a_64_bit); + return overflow_flag; +} -static inline int OVERFLOW_MULT_64_64(uint64_t a_64_bit,uint64_t b_64_bit) { return (a_64_bit>((uint64_t)-1)/b_64_bit); } +static inline int OVERFLOW_MULT_64_64(uint64_t a_64_bit,uint64_t b_64_bit) +{ + return (a_64_bit>((uint64_t)-1)/b_64_bit); +} static inline int MULT_64_64(uint64_t a_64_bit,uint64_t b_64_bit,uint64_t* c_64_bit ) { - -int overflow_flag; -*c_64_bit=a_64_bit*b_64_bit; -overflow_flag=OVERFLOW_MULT_64_64(a_64_bit, b_64_bit); -return overflow_flag;} + int overflow_flag; + *c_64_bit=a_64_bit*b_64_bit; + overflow_flag=OVERFLOW_MULT_64_64(a_64_bit, b_64_bit); + return overflow_flag; +} // //static inline void SUM_64_128(uint64_t a_64_bit,uint64_t b_64_bit,uint128_t* c_128_bit ) { @@ -392,10 +367,16 @@ return overflow_flag;} //c_128_bit->lo=a_64_bit+b_64_bit; //c_128_bit->hi=(c_128_bit->lo<a_64_bit);} -#ifndef DAP_GLOBAL_IS_INT128 + //Mixed precision: add a uint64_t into a uint128_t -static inline int ADD_64_INTO_128(uint64_t a_64_bit,uint128_t* c_128_bit ) { +static inline int ADD_64_INTO_128(uint64_t a_64_bit,uint128_t *c_128_bit ) +{ int overflow_flag=0; +#ifdef DAP_GLOBAL_IS_INT128 + uint128_t temp=*c_128_bit; + *c_128_bit+=(uint128_t)a_64_bit; + overflow_flag=(*c_128_bit<temp); +#else uint64_t overflow_64=0; uint64_t temp=0; temp=c_128_bit->lo; @@ -403,10 +384,19 @@ static inline int ADD_64_INTO_128(uint64_t a_64_bit,uint128_t* c_128_bit ) { overflow_64=overflow_flag; temp=c_128_bit->hi; overflow_flag=SUM_64_64(overflow_64,temp,&c_128_bit->hi); - return overflow_flag;} +#endif + return overflow_flag; +} -static inline int SUM_128_128(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t* c_128_bit){ - int overflow_flag; + +static inline int SUM_128_128(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t* c_128_bit) +{ + int overflow_flag=0; +#ifdef DAP_GLOBAL_IS_INT128 + *c_128_bit=a_128_bit+b_128_bit; + overflow_flag=(*c_128_bit<a_128_bit); + return overflow_flag; +#else int overflow_flag_intermediate; overflow_flag=SUM_64_64(a_128_bit.lo,b_128_bit.lo,&c_128_bit->lo); uint64_t carry_in_64=overflow_flag; @@ -415,46 +405,59 @@ static inline int SUM_128_128(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t overflow_flag=SUM_64_64(carry_in_64,a_128_bit.hi,&intermediate_value); overflow_flag_intermediate=SUM_64_64(intermediate_value,b_128_bit.hi,&c_128_bit->hi); int return_overflow=overflow_flag|overflow_flag_intermediate; - return return_overflow;} + return return_overflow; +#endif +} -static inline int SUBTRACT_128_128(uint128_t a_128_bit, uint128_t b_128_bit,uint128_t* c_128_bit) +static inline int SUBTRACT_128_128(uint128_t a_128_bit, uint128_t b_128_bit, uint128_t* c_128_bit) { + int underflow_flag = 0; +#ifdef DAP_GLOBAL_IS_INT128 + *c_128_bit = a_128_bit - b_128_bit; + underflow_flag = (*c_128_bit < 0) ^ (a_128_bit < b_128_bit); +#else c_128_bit->lo = a_128_bit.lo - b_128_bit.lo; uint64_t carry = (((c_128_bit->lo & b_128_bit.lo) & 1) + (b_128_bit.lo >> 1) + (c_128_bit->lo >> 1)) >> 63; c_128_bit->hi = a_128_bit.hi - (b_128_bit.hi + carry); - int underflow_flag=carry; + underflow_flag=carry; +#endif return underflow_flag; } -//static inline int SUBTRACT_256_256(uint256_t a_256_bit, uint256_t b_256_bit,uint256_t* c_256_bit){ -// -// if -// int carry=0; -// carry=SUBTRACT_128_128(a_256_bit.lo, b_256_bit.lo,&c_256_bit->lo); -// uint64_t carry_64=carry; -// uint128_t carry_128{.hi=0,.lo=carry_64}; -// uint128_t intermediate_val{.hi=0,.lo=0}; -// int dummy_overflow=0; -// dummy_overflow=SUM_128_128(b_256_bit.hi,carry_128,&intermediate_val); -// carry=SUBTRACT_128_128(a_256_bit.hi, intermediate_val,&c_256_bit->hi ); -// return carry; -//} + // //Mixed precision: add a uint128_t into a uint256_t static inline int ADD_128_INTO_256(uint128_t a_128_bit,uint256_t* c_256_bit) { int overflow_flag=0; - uint128_t overflow_128={.hi=0,.lo=0}; - uint128_t temp={.hi=0,.lo=0}; + uint128_t overflow_128 = uint128_0; + uint128_t temp = uint128_0; temp=c_256_bit->lo; overflow_flag=SUM_128_128(a_128_bit,temp,&c_256_bit->lo); + +#ifdef DAP_GLOBAL_IS_INT128 + overflow_128=overflow_flag; +#else overflow_128.lo=overflow_flag; +#endif + temp=c_256_bit->hi; overflow_flag=SUM_128_128(overflow_128,temp,&c_256_bit->hi); - return overflow_flag;} - + return overflow_flag; +} -static inline int SUM_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* c_256_bit){ - int overflow_flag; +static inline int SUM_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* c_256_bit) +{ + int overflow_flag=0; +#ifdef DAP_GLOBAL_IS_INT128 + int overflow_flag_intermediate; + overflow_flag=SUM_128_128(a_256_bit.lo,b_256_bit.lo,&c_256_bit->lo); + uint128_t carry_in_128=overflow_flag; + uint128_t intermediate_value=0; + overflow_flag=0; + overflow_flag=SUM_128_128(carry_in_128,a_256_bit.hi,&intermediate_value); + overflow_flag_intermediate=SUM_128_128(intermediate_value,b_256_bit.hi,&c_256_bit->hi); + overflow_flag=overflow_flag||overflow_flag_intermediate; +#else overflow_flag=SUM_128_128(a_256_bit.lo,b_256_bit.lo,&c_256_bit->lo); uint128_t carry_in_128; carry_in_128.hi=0; @@ -464,17 +467,25 @@ static inline int SUM_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t intermediate_value.lo=0; overflow_flag=0; overflow_flag=SUM_128_128(carry_in_128,a_256_bit.hi,&intermediate_value); - //we store overflow_flag in case there is already overflow int overflow_flag_bis=0; - overflow_flag_bis=SUM_128_128(intermediate_value,b_256_bit.hi,&c_256_bit->hi); overflow_flag=overflow_flag||overflow_flag_bis; - return overflow_flag;} +#endif + return overflow_flag; +} -static inline int SUBTRACT_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* c_256_bit){ - -//(u64 rd[4], const u64 ad[4], const u64 bd[4]) +static inline int SUBTRACT_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* c_256_bit) +{ +#ifdef DAP_GLOBAL_IS_INT128 + int underflow_flag=0; + c_256_bit->lo = a_256_bit.lo - b_256_bit.lo; + uint64_t carry = (((c_256_bit->lo & b_256_bit.lo) & 1) + (b_256_bit.lo >> 1) + (c_256_bit->lo >> 1)) >> 127; + c_256_bit->hi = a_256_bit.hi - (b_256_bit.hi + carry); + underflow_flag=carry; + return underflow_flag; + +#else uint64_t t, r, borrow; t = a_256_bit.lo.lo; @@ -504,24 +515,33 @@ static inline int SUBTRACT_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint c_256_bit->hi.hi = r; return borrow; - - } +#endif +} //Mixed precision: add a uint256_t into a uint512_t static inline int ADD_256_INTO_512(uint256_t a_256_bit,uint512_t* c_512_bit) { int overflow_flag=0; - uint256_t overflow_256={.hi=zero_128,.lo=zero_128}; - uint256_t temp={.hi=zero_128,.lo=zero_128}; + uint256_t overflow_256=uint256_0; + uint256_t temp=uint256_0; temp=c_512_bit->lo; overflow_flag=SUM_256_256(a_256_bit,temp,&c_512_bit->lo); +#ifdef DAP_GLOBAL_IS_INT128 + overflow_256.lo=overflow_flag; +#else overflow_256.lo.lo=overflow_flag; +#endif temp=c_512_bit->hi; overflow_flag=SUM_256_256(overflow_256,temp,&c_512_bit->hi); - return overflow_flag;} + return overflow_flag; +} static inline void MULT_64_128(uint64_t a_64_bit, uint64_t b_64_bit, uint128_t* c_128_bit) { +#ifdef DAP_GLOBAL_IS_INT128 + *c_128_bit = (uint128_t)a_64_bit; + *c_128_bit *= (uint128_t)b_64_bit; +#else uint64_t a_64_bit_hi = (a_64_bit & 0xffffffff); uint64_t b_64_bit_hi = (b_64_bit & 0xffffffff); uint64_t prod_hi = (a_64_bit_hi * b_64_bit_hi); @@ -539,20 +559,39 @@ static inline void MULT_64_128(uint64_t a_64_bit, uint64_t b_64_bit, uint128_t* c_128_bit->hi = (a_64_bit * b_64_bit) + w1 + prod_hi_shift_right; c_128_bit->lo = (prod_hi << 32) + w3; +#endif } static inline void MULT_128_256(uint128_t a_128_bit,uint128_t b_128_bit,uint256_t* c_256_bit ) { - +#ifdef DAP_GLOBAL_IS_INT128 + uint128_t a_128_bit_hi = (a_128_bit & 0xffffffffffffffff); + uint128_t b_128_bit_hi = (b_128_bit & 0xffffffffffffffff); + uint128_t prod_hi = (a_128_bit_hi * b_128_bit_hi); + uint128_t w3 = (prod_hi & 0xffffffffffffffff); + uint128_t prod_hi_shift_right = (prod_hi >> 64); + + a_128_bit >>= 64; + prod_hi = (a_128_bit * b_128_bit_hi) + prod_hi_shift_right; + prod_hi_shift_right = (prod_hi & 0xffffffffffffffff); + uint64_t w1 = (prod_hi >> 64); + + b_128_bit >>= 64; + prod_hi = (a_128_bit_hi * b_128_bit) + prod_hi_shift_right; + prod_hi_shift_right = (prod_hi >> 64); + + c_256_bit->hi = (a_128_bit * b_128_bit) + w1 + prod_hi_shift_right; + c_256_bit->lo = (prod_hi << 64) + w3; +#else //product of .hi terms - stored in .hi field of c_256_bit MULT_64_128(a_128_bit.hi,b_128_bit.hi, &c_256_bit->hi); //product of .lo terms - stored in .lo field of c_256_bit MULT_64_128(a_128_bit.lo,b_128_bit.lo, &c_256_bit->lo); - uint128_t cross_product_one{.hi=0, .lo=0}; - uint128_t cross_product_two{.hi=0, .lo=0}; + uint128_t cross_product_one={.hi=0, .lo=0}; + uint128_t cross_product_two={.hi=0, .lo=0}; MULT_64_128(a_128_bit.hi, b_128_bit.lo, &cross_product_one); c_256_bit->lo.hi += cross_product_one.lo; if(c_256_bit->lo.hi < cross_product_one.lo) // if overflow @@ -576,82 +615,93 @@ static inline void MULT_128_256(uint128_t a_128_bit,uint128_t b_128_bit,uint256_ { c_256_bit->hi.hi+=1; } -} +#endif +} -static inline int MULT_128_128_NEW(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t* accum_128_bit){ - int overflow=0; +// MULT_128_128_NEW +static inline int MULT_128_128(uint128_t a_128_bit, uint128_t b_128_bit, uint128_t* c_128_bit){ + int overflow_flag=0; + +#ifdef DAP_GLOBAL_IS_INT128 + *c_128_bit=a_128_bit*b_128_bit; + overflow_flag=(a_128_bit>((uint128_t)-1)/b_128_bit); +#else int equal_flag=0; - uint256_t full_product_256{.hi=zero_128, .lo=zero_128}; + uint256_t full_product_256={.hi=uint128_0, .lo=uint128_0}; MULT_128_256(a_128_bit,b_128_bit,&full_product_256); - *accum_128_bit=full_product_256.lo; - equal_flag=EQUAL_128(full_product_256.hi,zero_128); - if (!equal_flag) - { - overflow=1; + *c_128_bit=full_product_256.lo; + equal_flag=EQUAL_128(full_product_256.hi,uint128_0); + if (!equal_flag) { + overflow_flag=1; } - return overflow; +#endif + return overflow_flag; } -static inline int MULT_128_128(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t* accum_128_bit) { - uint64_t A=(b_128_bit.lo & lo_32)*(a_128_bit.hi & lo_32); - uint64_t B_32_64=((b_128_bit.lo & lo_32)*(a_128_bit.hi & hi_32))&hi_32; - uint64_t C_32_64=((b_128_bit.lo & hi_32)*(a_128_bit.hi & lo_32))&hi_32; - uint64_t E=(a_128_bit.lo & lo_32)*(b_128_bit.hi & lo_32); - uint64_t F_32_64=((a_128_bit.lo & lo_32)*(b_128_bit.hi & hi_32))&hi_32; - uint64_t G_32_64=((a_128_bit.lo & hi_32)*(b_128_bit.hi & lo_32))&hi_32; - //initialization of overflow counter - int overflow_ctr=0; +// incorrect +// static inline int MULT_128_128(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t* accum_128_bit) { +// uint64_t A=(b_128_bit.lo & lo_32)*(a_128_bit.hi & lo_32); +// uint64_t B_32_64=((b_128_bit.lo & lo_32)*(a_128_bit.hi & hi_32))&hi_32; +// uint64_t C_32_64=((b_128_bit.lo & hi_32)*(a_128_bit.hi & lo_32))&hi_32; +// uint64_t E=(a_128_bit.lo & lo_32)*(b_128_bit.hi & lo_32); +// uint64_t F_32_64=((a_128_bit.lo & lo_32)*(b_128_bit.hi & hi_32))&hi_32; +// uint64_t G_32_64=((a_128_bit.lo & hi_32)*(b_128_bit.hi & lo_32))&hi_32; - //checking of overflow from ".hi terms" - int overflow_from_hi_calc=0; - overflow_from_hi_calc=(a_128_bit.hi*b_128_bit.hi>0); - overflow_ctr+=overflow_from_hi_calc; +// //initialization of overflow counter +// int overflow_ctr=0; + +// //checking of overflow from ".hi terms" +// int overflow_from_hi_calc=0; +// overflow_from_hi_calc=(a_128_bit.hi*b_128_bit.hi>0); +// overflow_ctr+=overflow_from_hi_calc; - //product of two ".lo" terms - MULT_64_128(a_128_bit.lo,b_128_bit.lo,accum_128_bit); +// //product of two ".lo" terms +// MULT_64_128(a_128_bit.lo,b_128_bit.lo,accum_128_bit); - int overflow=0; - uint64_t temp=0; +// int overflow=0; +// uint64_t temp=0; - overflow=SUM_64_64(A,temp,&accum_128_bit->hi); - printf("accum_128_bit->hi after add in of A %" PRIu64 "\n",accum_128_bit->hi); +// overflow=SUM_64_64(A,temp,&accum_128_bit->hi); +// printf("accum_128_bit->hi after add in of A %" PRIu64 "\n",accum_128_bit->hi); - overflow_ctr+=overflow; - temp=accum_128_bit->hi; - overflow=0; - - overflow=SUM_64_64(B_32_64,temp,&accum_128_bit->hi); - overflow_ctr+=overflow; - temp=accum_128_bit->hi; - overflow=0; - - overflow=SUM_64_64(C_32_64,temp,&accum_128_bit->hi); - overflow_ctr+=overflow; - temp=accum_128_bit->hi; - overflow=0; - - overflow=SUM_64_64(E,temp,&accum_128_bit->hi); - overflow_ctr+=overflow; - temp=accum_128_bit->hi; - overflow=0; - - overflow=SUM_64_64(F_32_64,temp,&accum_128_bit->hi); - overflow_ctr+=overflow; - temp=accum_128_bit->hi; - overflow=0; +// overflow_ctr+=overflow; +// temp=accum_128_bit->hi; +// overflow=0; + +// overflow=SUM_64_64(B_32_64,temp,&accum_128_bit->hi); +// overflow_ctr+=overflow; +// temp=accum_128_bit->hi; +// overflow=0; + +// overflow=SUM_64_64(C_32_64,temp,&accum_128_bit->hi); +// overflow_ctr+=overflow; +// temp=accum_128_bit->hi; +// overflow=0; + +// overflow=SUM_64_64(E,temp,&accum_128_bit->hi); +// overflow_ctr+=overflow; +// temp=accum_128_bit->hi; +// overflow=0; + +// overflow=SUM_64_64(F_32_64,temp,&accum_128_bit->hi); +// overflow_ctr+=overflow; +// temp=accum_128_bit->hi; +// overflow=0; - overflow=SUM_64_64(G_32_64,temp,&accum_128_bit->hi); - overflow_ctr+=overflow; - temp=accum_128_bit->hi; - overflow=0; - - if(overflow_ctr>0){ - overflow=1;} - else{overflow=0;} +// overflow=SUM_64_64(G_32_64,temp,&accum_128_bit->hi); +// overflow_ctr+=overflow; +// temp=accum_128_bit->hi; +// overflow=0; + +// if(overflow_ctr>0){ +// overflow=1;} +// else{overflow=0;} - return overflow; - } +// return overflow; +// } + + static inline void MULT_256_512(uint256_t a_256_bit,uint256_t b_256_bit,uint512_t* c_512_bit) { int dummy_overflow; @@ -662,12 +712,12 @@ static inline void MULT_256_512(uint256_t a_256_bit,uint256_t b_256_bit,uint512_ MULT_128_256(a_256_bit.lo,b_256_bit.lo, &c_512_bit->lo); //cross product of .hi and .lo terms - uint256_t cross_product_first_term{ .hi = zero_128, .lo = zero_128}; - uint256_t cross_product_second_term{ .hi = zero_128, .lo = zero_128}; - uint256_t cross_product{ .hi = zero_128, .lo = zero_128}; - uint256_t cross_product_shift_128{ .hi = zero_128, .lo = zero_128}; - uint256_t c_512_bit_lo_copy{ .hi = zero_128, .lo = zero_128}; - uint256_t c_512_bit_hi_copy{ .hi = zero_128, .lo = zero_128}; + uint256_t cross_product_first_term=uint256_0; + uint256_t cross_product_second_term=uint256_0; + uint256_t cross_product=uint256_0; + uint256_t cross_product_shift_128=uint256_0; + uint256_t c_512_bit_lo_copy=uint256_0; + uint256_t c_512_bit_hi_copy=uint256_0; int overflow=0; MULT_128_256(a_256_bit.hi,b_256_bit.lo,&cross_product_first_term); @@ -679,66 +729,75 @@ static inline void MULT_256_512(uint256_t a_256_bit,uint256_t b_256_bit,uint512_ c_512_bit_lo_copy=c_512_bit->lo; dummy_overflow=SUM_256_256(c_512_bit_lo_copy,cross_product_shift_128,&c_512_bit->lo); - cross_product_shift_128.hi = zero_128; - cross_product_shift_128.lo = zero_128; + cross_product_shift_128.hi = uint128_0; + cross_product_shift_128.lo = uint128_0; RIGHT_SHIFT_256(cross_product,&cross_product_shift_128,128); c_512_bit_hi_copy=c_512_bit->hi; dummy_overflow=SUM_256_256(c_512_bit_hi_copy,cross_product_shift_128,&c_512_bit->hi); - } +} +static inline int MULT_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* accum_256_bit){ + int overflow=0; + int equal_flag=0; + uint512_t full_product_512={.hi=uint256_0,.lo=uint256_0,}; + MULT_256_512(a_256_bit,b_256_bit,&full_product_512); + *accum_256_bit=full_product_512.lo; + equal_flag=EQUAL_256(full_product_512.hi,uint256_0); + if (!equal_flag) + { + overflow=1; + } + return overflow; +} -static inline int MULT_256_256_NEW(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* accum_256_bit){ +// incorrect +// static inline int MULT_256_256_NEW(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* accum_256_bit){ - uint128_t two_0_coeff{.hi=0,.lo=0}; - MULT_64_128(a_256_bit.lo.lo,b_256_bit.lo.lo,&two_0_coeff); - accum_256_bit->lo.lo=two_0_coeff.lo; +// uint128_t two_0_coeff={.hi=0,.lo=0}; +// MULT_64_128(a_256_bit.lo.lo,b_256_bit.lo.lo,&two_0_coeff); +// accum_256_bit->lo.lo=two_0_coeff.lo; - uint128_t two_64_coeff{.hi=0,.lo=0}; - uint128_t two_64_coeff_one{.hi=0,.lo=0}; - MULT_64_128(a_256_bit.lo.hi,b_256_bit.lo.lo,&two_64_coeff_one); - uint128_t two_64_coeff_two{.hi=0,.lo=0}; - MULT_64_128(a_256_bit.lo.lo,b_256_bit.lo.hi,&two_64_coeff_two); - uint128_t two_64_coeff_sum{.hi=0,.lo=0}; - int dummy_overflow=0; - dummy_overflow=SUM_128_128(two_64_coeff_one,two_64_coeff_two,&two_64_coeff_sum); - if (two_64_coeff_sum.lo+two_0_coeff.hi<two_64_coeff_sum.lo){ +// uint128_t two_64_coeff={.hi=0,.lo=0}; +// uint128_t two_64_coeff_one={.hi=0,.lo=0}; +// MULT_64_128(a_256_bit.lo.hi,b_256_bit.lo.lo,&two_64_coeff_one); +// uint128_t two_64_coeff_two={.hi=0,.lo=0}; +// MULT_64_128(a_256_bit.lo.lo,b_256_bit.lo.hi,&two_64_coeff_two); +// uint128_t two_64_coeff_sum={.hi=0,.lo=0}; +// int dummy_overflow=0; +// dummy_overflow=SUM_128_128(two_64_coeff_one,two_64_coeff_two,&two_64_coeff_sum); +// if (two_64_coeff_sum.lo+two_0_coeff.hi<two_64_coeff_sum.lo){ - two_64_coeff.lo=two_64_coeff_sum.lo+two_0_coeff.hi; - two_64_coeff.hi=1+two_64_coeff_sum.hi;} - else{ - two_64_coeff.lo=two_64_coeff_sum.lo+two_0_coeff.hi; - two_64_coeff.hi=two_64_coeff_sum.hi; - } - accum_256_bit->lo.hi=two_64_coeff.lo; +// two_64_coeff.lo=two_64_coeff_sum.lo+two_0_coeff.hi; +// two_64_coeff.hi=1+two_64_coeff_sum.hi;} +// else{ +// two_64_coeff.lo=two_64_coeff_sum.lo+two_0_coeff.hi; +// two_64_coeff.hi=two_64_coeff_sum.hi; +// } +// accum_256_bit->lo.hi=two_64_coeff.lo; - uint128_t two_128_coeff{.hi=0,.lo=0}; - uint128_t two_128_coeff_one{.hi=0,.lo=0}; - MULT_64_128(a_256_bit.lo.lo,b_256_bit.hi.lo,&two_128_coeff_one); - uint128_t two_128_coeff_two{.hi=0,.lo=0}; - MULT_64_128(a_256_bit.hi.lo,b_256_bit.lo.lo,&two_128_coeff_two); - uint128_t two_128_coeff_three{.hi=0,.lo=0}; - MULT_64_128(a_256_bit.lo.hi,b_256_bit.lo.hi,&two_128_coeff_three); - uint128_t two_128_coeff_sum_one{.hi=0,.lo=0}; - dummy_overflow=SUM_128_128(two_128_coeff_one,two_128_coeff_two,&two_128_coeff_sum_one); - uint128_t two_128_coeff_sum_two{.hi=0,.lo=0}; - dummy_overflow=SUM_128_128(two_128_coeff_sum_one,two_128_coeff_three,&two_128_coeff_sum_two); +// uint128_t two_128_coeff={.hi=0,.lo=0}; +// uint128_t two_128_coeff_one={.hi=0,.lo=0}; +// MULT_64_128(a_256_bit.lo.lo,b_256_bit.hi.lo,&two_128_coeff_one); +// uint128_t two_128_coeff_two={.hi=0,.lo=0}; +// MULT_64_128(a_256_bit.hi.lo,b_256_bit.lo.lo,&two_128_coeff_two); +// uint128_t two_128_coeff_three={.hi=0,.lo=0}; +// MULT_64_128(a_256_bit.lo.hi,b_256_bit.lo.hi,&two_128_coeff_three); +// uint128_t two_128_coeff_sum_one={.hi=0,.lo=0}; +// dummy_overflow=SUM_128_128(two_128_coeff_one,two_128_coeff_two,&two_128_coeff_sum_one); +// uint128_t two_128_coeff_sum_two={.hi=0,.lo=0}; +// dummy_overflow=SUM_128_128(two_128_coeff_sum_one,two_128_coeff_three,&two_128_coeff_sum_two); - if (two_128_coeff_sum_two.lo+two_64_coeff.hi<two_128_coeff_sum_two.lo){ +// if (two_128_coeff_sum_two.lo+two_64_coeff.hi<two_128_coeff_sum_two.lo){ - two_128_coeff.lo=two_128_coeff_sum_two.lo+two_64_coeff.hi; - two_128_coeff.hi=1+two_128_coeff_sum_two.hi;} - else{ - two_128_coeff.lo=two_128_coeff_sum_two.lo+two_64_coeff.hi; - two_128_coeff.hi=two_128_coeff_sum_two.hi; - } - accum_256_bit->hi.lo=two_128_coeff.lo; - +// two_128_coeff.lo=two_128_coeff_sum_two.lo+two_64_coeff.hi; +// two_128_coeff.hi=1+two_128_coeff_sum_two.hi;} +// else{ +// two_128_coeff.lo=two_128_coeff_sum_two.lo+two_64_coeff.hi; +// two_128_coeff.hi=two_128_coeff_sum_two.hi; +// } +// accum_256_bit->hi.lo=two_128_coeff.lo; - -// -// -// // uint64_t two_192_coeff=0; // uint64_t two_192_coeff_one=0; // int overflow_two_192_coeff_one=0; @@ -761,33 +820,31 @@ static inline int MULT_256_256_NEW(uint256_t a_256_bit,uint256_t b_256_bit,uint2 // overflow_two_192_coeff_sum_two=SUM_64_64(two_192_coeff_three,two_192_coeff_four,&two_192_coeff_sum_two); // int overflow_two_192_coeff_sum=0; // overflow_two_192_coeff_sum=SUM_64_64(two_192_coeff_sum_one,two_192_coeff_sum_two,&two_192_coeff); - - return 0; - -} +// return 0; +// } -static inline int MULT_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* accum_256_bit){ - int overflow=0; - int equal_flag=0; - uint512_t full_product_512{.hi=zero_256,.lo=zero_256,}; - MULT_256_512(a_256_bit,b_256_bit,&full_product_512); - *accum_256_bit=full_product_512.lo; - equal_flag=EQUAL_256(full_product_512.hi,zero_256); - if (!equal_flag) - { - overflow=1; - } - return overflow; +//#ifndef DAP_GLOBAL_IS_INT128 +// > ret 1 +// == ret 0 +// < ret -1 +static inline int compare128(uint128_t a, uint128_t b) +{ +#ifdef DAP_GLOBAL_IS_INT128 + return ( a > b ? 1 : 0 ) - ( a < b ? 1 : 0 ); +#else + return (((a.hi > b.hi) || ((a.hi == b.hi) && (a.lo > b.lo))) ? 1 : 0) + - (((a.hi < b.hi) || ((a.hi == b.hi) && (a.lo < b.lo))) ? 1 : 0); +#endif } -int compare128(uint128_t N1, uint128_t N2) +static inline int compare256(uint256_t a, uint256_t b) { - return (((N1.hi > N2.hi) || ((N1.hi == N2.hi) && (N1.lo > N2.lo))) ? 1 : 0) - - (((N1.hi < N2.hi) || ((N1.hi == N2.hi) && (N1.lo < N2.lo))) ? 1 : 0); + return (( compare128(a.hi, b.hi) == 1 || (compare128(a.hi, b.hi) == 0 && compare128(a.lo, b.lo) == 1)) ? 1 : 0) + - (( compare128(a.hi, b.hi) == -1 || (compare128(a.hi, b.hi) == 0 && compare128(a.lo, b.lo) == -1)) ? 1 : 0); } -size_t nlz64(uint64_t N) +static inline int nlz64(uint64_t N) { uint64_t I; size_t C; @@ -820,72 +877,135 @@ size_t nlz64(uint64_t N) return C; } -size_t nlz128(uint128_t N) +static inline int nlz128(uint128_t N) { +#ifdef DAP_GLOBAL_IS_INT128 + return ( (N >> 64) == 0) ? nlz64((uint64_t)N) + 64 : nlz64((uint64_t)(N >> 64)); +#else return (N.hi == 0) ? nlz64(N.lo) + 64 : nlz64(N.hi); +#endif } -void shiftleft128(uint128_t N, unsigned S, uint128_t* A) +static inline int nlz256(uint256_t N) { - uint64_t M1, M2; - S &= 127; + return EQUAL_128(N.hi, uint128_0) ? nlz128(N.lo) + 128 : nlz128(N.hi); +} + - M1 = ((((S + 127) | S) & 64) >> 6) - 1llu; - M2 = (S >> 6) - 1llu; - S &= 63; - A->hi = (N.lo << S) & (~M2); - A->lo = (N.lo << S) & M2; - A->hi |= ((N.hi << S) | ((N.lo >> (64 - S)) & M1)) & M2; +#ifndef DAP_GLOBAL_IS_INT128 +static inline int fls128(uint128_t n) { + if ( n.hi != 0 ) { + return 127 - nlz64(n.hi); + } + return 63 - nlz64(n.lo); } -void shiftright128(uint128_t N, unsigned S, uint128_t* A) -{ - uint64_t M1, M2; - S &= 127; - - M1 = ((((S + 127) | S) & 64) >> 6) - 1llu; - M2 = (S >> 6) - 1llu; - S &= 63; - A->lo = (N.hi >> S) & (~M2); - A->hi = (N.hi >> S) & M2; - A->lo |= ((N.lo >> S) | ((N.hi << (64 - S)) & M1)) & M2; -} - -void sub128(uint128_t* Ans, uint128_t N, uint128_t M) +static inline void divmod_impl_128(uint128_t a_dividend, uint128_t a_divisor, uint128_t *a_quotient, uint128_t *a_remainder) { - Ans->lo = N.lo - M.lo; - uint64_t C = (((Ans->lo & M.lo) & 1) + (M.lo >> 1) + (Ans->lo >> 1)) >> 63; - Ans->hi = N.hi - (M.hi + C); + assert( compare128(a_divisor, uint128_0) ); // a_divisor != 0 + if ( compare128(a_divisor, a_dividend) == 1 ) { // a_divisor > a_dividend + *a_quotient = uint128_0; + *a_remainder = a_dividend; + return; + } + if ( compare128(a_divisor, a_dividend) == 0 ) { // a_divisor == a_dividend + *a_quotient = uint128_1; + *a_remainder = uint128_0; + return; + } + + uint128_t l_denominator = a_divisor; + uint128_t l_quotient = uint128_0; + int l_shift = fls128(a_dividend) - fls128(l_denominator); + + LEFT_SHIFT_128(l_denominator, &l_denominator, l_shift); + + for (int i = 0; i <= l_shift; ++i) { + LEFT_SHIFT_128(l_quotient, &l_quotient, 1); + + if( compare128(a_dividend, l_denominator) >= 0 ) { + SUBTRACT_128_128(a_dividend, l_denominator, &a_dividend); + l_quotient = OR_128(l_quotient, uint128_1); //l_quotient.lo |= 1; + } + RIGHT_SHIFT_128(l_denominator, &l_denominator, 1); + } + *a_quotient = l_quotient; + *a_remainder = a_dividend; } -void bindivmod128(uint128_t M, uint128_t N, uint128_t* Q, uint128_t* R) +#endif + + +static inline int fls256(uint256_t n) { + if ( compare128(n.hi, uint128_0) != 0 ) { + return 255 - nlz128(n.hi); + } + return 127 - nlz128(n.lo); +} + +static inline void divmod_impl_256(uint256_t a_dividend, uint256_t a_divisor, uint256_t *a_quotient, uint256_t *a_remainder) { - Q->hi = Q->lo = 0; - size_t Shift = nlz128(N) - nlz128(M); - shiftleft128(N, Shift, &N); + assert( compare256(a_divisor, uint256_0) ); // a_divisor != 0 + if ( compare256(a_divisor, a_dividend) == 1 ) { // a_divisor > a_dividend + *a_quotient = uint256_0; + *a_remainder = a_dividend; + return; + } + if ( compare256(a_divisor, a_dividend) == 0 ) { // a_divisor == a_dividend + *a_quotient = uint256_1; + *a_remainder = uint256_0; + return; + } - do - { - shiftleft128(*Q, 1, Q); - if(compare128(M, N) >= 0) - { - sub128(&M, N, M); - Q->lo |= 1; - } + uint256_t l_denominator = a_divisor; + uint256_t l_quotient = uint256_0; + // int l_shift = nlz256(a_dividend) - nlz256(l_denominator); + int l_shift = fls256(a_dividend) - fls256(l_denominator); + LEFT_SHIFT_256(l_denominator, &l_denominator, l_shift); - shiftright128(N, 1, &N); - }while(Shift-- != 0); + for (int i = 0; i <= l_shift; ++i) { + LEFT_SHIFT_256(l_quotient, &l_quotient, 1); - R->hi = M.hi; - R->lo = M.lo; + if( compare256(a_dividend, l_denominator) >= 0 ) { + SUBTRACT_256_256(a_dividend, l_denominator, &a_dividend); + l_quotient = OR_256(l_quotient, uint256_1); + } + RIGHT_SHIFT_256(l_denominator, &l_denominator, 1); + } + *a_quotient = l_quotient; + *a_remainder = a_dividend; } + +static inline void DIV_128(uint128_t a_128_bit, uint128_t b_128_bit, uint128_t* c_128_bit){ + uint128_t l_ret = uint128_0; +#ifdef DAP_GLOBAL_IS_INT128 + l_ret = a_128_bit / b_128_bit; #else + uint128_t l_remainder = uint128_0; + divmod_impl_128(a_128_bit, b_128_bit, &l_ret, &l_remainder); +#endif + *c_128_bit = l_ret; +} + +static inline void DIV_256(uint256_t a_256_bit, uint256_t b_256_bit, uint256_t* c_256_bit){ + uint256_t l_ret = uint256_0; + uint256_t l_remainder = uint256_0; + divmod_impl_256(a_256_bit, b_256_bit, &l_ret, &l_remainder); + *c_256_bit = l_ret; +} + + +// +// dap_uint128_substract, dap_uint128_add, dap_uint128_check_equal - temporarily, for compatibility static inline uint128_t dap_uint128_substract(uint128_t a, uint128_t b) { - if (a < b) { - return 0; - } - return a - b; + // if (a < b) { + // return 0; + // } + // return a - b; + uint128_t c = uint128_0; + SUBTRACT_128_128(a, b, &c); + return c; } /** @@ -896,11 +1016,14 @@ static inline uint128_t dap_uint128_substract(uint128_t a, uint128_t b) */ static inline uint128_t dap_uint128_add(uint128_t a, uint128_t b) { - uint128_t l_ret = a + b; - if (l_ret < a || l_ret < b) { - return 0; - } - return l_ret; + // uint128_t l_ret = a + b; + // if (l_ret < a || l_ret < b) { + // return 0; + // } + // return l_ret; + uint128_t c = uint128_0; + SUM_128_128( a, b, &c); + return c; } /** @@ -911,6 +1034,6 @@ static inline uint128_t dap_uint128_add(uint128_t a, uint128_t b) */ static inline bool dap_uint128_check_equal(uint128_t a, uint128_t b) { - return a == b; + //return a == b; + return EQUAL_128(a, b); } -#endif diff --git a/dap-sdk/core/test/uint256_t/unit_test.cpp b/dap-sdk/core/test/uint256_t/unit_test.cpp index ac4371c00f3453e25c9e2b960ae34416a03eed21..064d0810b93503a3313483aa2a7f81fc1d57f807 100644 --- a/dap-sdk/core/test/uint256_t/unit_test.cpp +++ b/dap-sdk/core/test/uint256_t/unit_test.cpp @@ -39,17 +39,17 @@ int main() int error_counter_sum_64_128=0; - uint128_t dap_test_128_shift={.hi=0, .lo=0}; - uint128_t dap_test_128_one={.hi=0, .lo=0}; - uint128_t dap_test_128_two={.hi=0, .lo=0}; - uint128_t dap_test_128_sub={.hi=0, .lo=0}; - uint256_t dap_test_256_one={.hi=zero_128, .lo=zero_128}; - uint256_t dap_test_256_two={.hi=zero_128, .lo=zero_128}; - uint256_t dap_test_256_sum={.hi=zero_128, .lo=zero_128}; - uint256_t dap_test_256_sub={.hi=zero_128, .lo=zero_128}; - uint256_t dap_test_256_prod={.hi=zero_128, .lo=zero_128}; - uint256_t dap_test_256_shift={.hi=zero_128, .lo=zero_128}; - uint512_t dap_test_512_prod={.hi=zero_256, .lo=zero_256}; + uint128_t dap_test_128_shift=uint128_0; + uint128_t dap_test_128_one=uint128_0; + uint128_t dap_test_128_two=uint128_0; + uint128_t dap_test_128_sub=uint128_0; + uint256_t dap_test_256_one=uint256_0; + uint256_t dap_test_256_two=uint256_0; + uint256_t dap_test_256_sum=uint256_0; + uint256_t dap_test_256_sub=uint256_0; + uint256_t dap_test_256_prod=uint256_0; + uint256_t dap_test_256_shift=uint256_0; + uint512_t dap_test_512_prod=uint512_0; int overflow_flag; int overflow_flag_prod; int borrow_flag_128; @@ -308,8 +308,8 @@ if (division_enabled==1){ prod_256_256_file << density_index << std::endl;} /////////////////////output of 256*256-->512////////////////////// - dap_test_512_prod.lo=zero_256; - dap_test_512_prod.hi=zero_256; + dap_test_512_prod.lo=uint256_0; + dap_test_512_prod.hi=uint256_0; uint256_t intermed_lo_prod; uint256_t intermed_hi_prod; MULT_128_256(dap_test_256_one.lo,dap_test_256_two.lo,&intermed_lo_prod); @@ -442,8 +442,8 @@ if (division_enabled==1){ dap_test_128_256_prod_one.hi=j; dap_test_128_256_prod_two.lo=max_64-(i+1); dap_test_128_256_prod_two.hi=max_64-2*(j+1); - dap_test_128_256_prod_prod.lo=zero_128; - dap_test_128_256_prod_prod.hi=zero_128; + dap_test_128_256_prod_prod.lo=uint128_0; + dap_test_128_256_prod_prod.hi=uint128_0; boost::multiprecision::uint256_t boost_test_128_256_prod; boost::multiprecision::uint128_t boost_test_128_256_one; diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index b577c8ad0c9a0fb63bf3ff2080eb6586ef27af36..c73c4dcc929d921783ab756df0e6a8c3a77bc4ea 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -251,9 +251,15 @@ static dap_chain_type_t s_chain_type_from_str(const char *a_type_str) if(!dap_strcmp(a_type_str, "emission")) { return CHAIN_TYPE_EMISSION; } + if(!dap_strcmp(a_type_str, "emission_256")) { + return CHAIN_TYPE_256_EMISSION; + } if(!dap_strcmp(a_type_str, "transaction")) { return CHAIN_TYPE_TX; } + if(!dap_strcmp(a_type_str, "transaction_256")) { + return CHAIN_TYPE_256_TX; + } if(!dap_strcmp(a_type_str, "ca")) { return CHAIN_TYPE_CA; } @@ -274,9 +280,15 @@ static uint16_t s_datum_type_from_str(const char *a_type_str) if(!dap_strcmp(a_type_str, "emission")) { return DAP_CHAIN_DATUM_TOKEN_EMISSION; } + if(!dap_strcmp(a_type_str, "emission_256")) { + return DAP_CHAIN_DATUM_256_TOKEN_EMISSION; + } if(!dap_strcmp(a_type_str, "transaction")) { return DAP_CHAIN_DATUM_TX; } + if(!dap_strcmp(a_type_str, "transaction_256")) { + return DAP_CHAIN_DATUM_256_TX; + } return DAP_CHAIN_DATUM_CUSTOM; } @@ -293,8 +305,12 @@ static uint16_t s_chain_type_convert(dap_chain_type_t a_type) return DAP_CHAIN_DATUM_TOKEN_DECL; case CHAIN_TYPE_EMISSION: return DAP_CHAIN_DATUM_TOKEN_EMISSION; + case CHAIN_TYPE_256_EMISSION: + return DAP_CHAIN_DATUM_256_TOKEN_EMISSION; case CHAIN_TYPE_TX: return DAP_CHAIN_DATUM_TX; + case CHAIN_TYPE_256_TX: + return DAP_CHAIN_DATUM_256_TX; default: return DAP_CHAIN_DATUM_CUSTOM; } diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index 8a8b7387df4437c8e2d7ce39ce79a0e47e62950b..69262d327348d8ede447d815d48bec5aa210afc0 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -70,7 +70,10 @@ static pthread_rwlock_t s_verificators_rwlock; #define MAX_OUT_ITEMS 10 typedef struct dap_chain_ledger_token_emission_item { dap_chain_hash_fast_t datum_token_emission_hash; + //union { dap_chain_datum_token_emission_t *datum_token_emission; + // dap_chain_datum_256_token_emission_t *datum_256_token_emission; // 256 + //}; size_t datum_token_emission_size; UT_hash_handle hh; } dap_chain_ledger_token_emission_item_t; @@ -118,11 +121,18 @@ typedef struct dap_chain_ledger_tx_item { } dap_chain_ledger_tx_item_t; typedef struct dap_chain_ledger_tokenizer { + bool type_256; char token_ticker[10]; uint64_t sum; UT_hash_handle hh; } dap_chain_ledger_tokenizer_t; +typedef struct dap_chain_ledger_tokenizer_256 { + char token_ticker[10]; + uint256_t sum; + UT_hash_handle hh; +} dap_chain_ledger_tokenizer_256_t; + typedef struct dap_chain_ledger_tx_bound { dap_chain_hash_fast_t tx_prev_hash_fast; dap_chain_datum_tx_t *tx_prev; @@ -142,7 +152,8 @@ typedef struct dap_chain_ledger_tx_bound { typedef struct dap_ledger_wallet_balance { char *key; char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; - uint128_t balance; + //uint128_t balance; + uint256_t balance; UT_hash_handle hh; } dap_ledger_wallet_balance_t; @@ -1078,7 +1089,8 @@ void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger) if (l_ptr++) { strcpy(l_balance_item->token_ticker, l_ptr); } - l_balance_item->balance = *(uint128_t *)l_objs[i].value; + //l_balance_item->balance = *(uint128_t *)l_objs[i].value; + l_balance_item->balance = *(uint256_t *)l_objs[i].value; HASH_ADD_KEYPTR(hh, l_ledger_pvt->balance_accounts, l_balance_item->key, strlen(l_balance_item->key), l_balance_item); } @@ -1141,8 +1153,12 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ : &l_ledger_priv->treshold_emissions_rwlock); if(l_token_emission_item ) { if(s_debug_more) - log_it(L_ERROR, "Can't add token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s ): already present in cache", - l_token_emission_item->datum_token_emission->hdr.value, c_token_ticker, l_hash_str); + if ( l_token_emission_item->datum_token_emission->hdr.type_value_256 ) + log_it(L_ERROR, "Can't add token emission datum of %s %s ( %s ): already present in cache", + dap_chain_u256tostr(l_token_emission_item->datum_token_emission->hdr.value_256), c_token_ticker, l_hash_str); + else + log_it(L_ERROR, "Can't add token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s ): already present in cache", + l_token_emission_item->datum_token_emission->hdr.value, c_token_ticker, l_hash_str); ret = -1; }else if ( (! l_token_item) && ( l_threshold_emissions_count >= s_treshold_emissions_max)) { if(s_debug_more) @@ -1191,8 +1207,12 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ if (l_aproves < l_aproves_valid ){ if(s_debug_more) - log_it(L_WARNING, "Emission of %"DAP_UINT64_FORMAT_U" datoshi of %s:%s is wrong: only %u valid aproves when %u need", - l_emission->hdr.value, a_ledger->net_name, l_emission->hdr.ticker, l_aproves, l_aproves_valid ); + if ( l_emission->hdr.type_value_256 ) // 256 + log_it(L_WARNING, "Emission of %s datoshi of %s:%s is wrong: only %u valid aproves when %u need", + dap_chain_u256tostr(l_emission->hdr.value_256), a_ledger->net_name, l_emission->hdr.ticker, l_aproves, l_aproves_valid ); + else + log_it(L_WARNING, "Emission of %"DAP_UINT64_FORMAT_U" datoshi of %s:%s is wrong: only %u valid aproves when %u need", + l_emission->hdr.value, a_ledger->net_name, l_emission->hdr.ticker, l_aproves, l_aproves_valid ); ret = -1; } } @@ -1271,11 +1291,20 @@ int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_ DAP_DELETE(l_gdb_group); char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_emission_item->datum_token_emission->hdr.address) ); if(s_debug_more) - log_it(L_NOTICE, "Added token emission datum to %s: type=%s value=%.1Lf token=%s to_addr=%s ", - l_token_item?"emissions cache":"emissions treshold", - c_dap_chain_datum_token_emission_type_str[l_token_emission_item->datum_token_emission->hdr.type ] , - dap_chain_datoshi_to_coins(l_token_emission_item->datum_token_emission->hdr.value), c_token_ticker, - l_token_emission_address_str); + if ( l_token_emission_item->datum_token_emission->hdr.type_value_256 ) // 256 + log_it(L_NOTICE, "Added token emission datum to %s: type=%s value=%.1Lf token=%s to_addr=%s ", + l_token_item?"emissions cache":"emissions treshold", + c_dap_chain_datum_token_emission_type_str[ l_token_emission_item->datum_token_emission->hdr.type ] , + dap_chain_datoshi_to_coins( + dap_chain_uint128_from_uint256(l_token_emission_item->datum_token_emission->hdr.value_256) + ), c_token_ticker, + l_token_emission_address_str); + else + log_it(L_NOTICE, "Added token emission datum to %s: type=%s value=%.1Lf token=%s to_addr=%s ", + l_token_item?"emissions cache":"emissions treshold", + c_dap_chain_datum_token_emission_type_str[ l_token_emission_item->datum_token_emission->hdr.type ] , + dap_chain_datoshi_to_coins(l_token_emission_item->datum_token_emission->hdr.value), c_token_ticker, + l_token_emission_address_str); DAP_DELETE(l_token_emission_address_str); }else{ if(s_debug_more) @@ -1286,9 +1315,12 @@ int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_ } else { if (l_token_item) { if(s_debug_more) - log_it(L_ERROR, "Duplicate token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s )", - ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value, - c_token_ticker, l_hash_str); + if ( ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.type_value_256 ) // 256 + log_it(L_ERROR, "Duplicate token emission datum of %s %s ( %s )", + dap_chain_u256tostr(((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value_256), c_token_ticker, l_hash_str); + else + log_it(L_ERROR, "Duplicate token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s )", + ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value, c_token_ticker, l_hash_str); } ret = -1; } @@ -1319,6 +1351,7 @@ int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token dap_chain_datum_token_emission_t * dap_chain_ledger_token_emission_find(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash) { + dap_ledger_private_t *l_ledger_priv = PVT(a_ledger); dap_chain_datum_token_emission_t * l_token_emission = NULL; dap_chain_ledger_token_item_t * l_token_item = NULL; @@ -1584,6 +1617,10 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // sum of values in 'out' items from the previous transactions dap_chain_ledger_tokenizer_t *l_values_from_prev_tx = NULL, *l_values_from_cur_tx = NULL, *l_value_cur = NULL, *l_tmp = NULL, *l_res = NULL; + + dap_chain_ledger_tokenizer_256_t *l_values_from_prev_tx_256 = NULL, *l_values_from_cur_tx_256 = NULL, + *l_value_cur_256 = NULL, *l_tmp_256 = NULL, *l_res_256 = NULL; + char *l_token = NULL; dap_chain_ledger_token_item_t * l_token_item = NULL; dap_chain_hash_fast_t *l_emission_hash; @@ -1622,6 +1659,9 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_chain_tx_in_cond_t *l_tx_in_cond; dap_chain_hash_fast_t l_tx_prev_hash={0}; uint8_t l_cond_type = *(uint8_t *)l_list_tmp->data; + + bool l_is_type_256 = false; // 256 type + // one of the previous transaction if (l_cond_type == TX_ITEM_TYPE_IN) { l_tx_in = (dap_chain_tx_in_t *)l_list_tmp->data; @@ -1655,12 +1695,17 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_is_first_transaction = true; if (!l_token) { dap_chain_tx_token_t *l_tx_token = (dap_chain_tx_token_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_TOKEN, NULL); - if (!l_tx_token) { + dap_chain_tx_token_t *l_tx_token_256 = (dap_chain_tx_token_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_256_TOKEN, NULL); + if (l_tx_token) { // TX_ITEM_TYPE_TOKEN + l_token = l_tx_token->header.ticker; + l_emission_hash = &l_tx_token->header.token_emission_hash; + } else if (l_tx_token_256) { // TX_ITEM_TYPE_256_TOKEN + l_token = l_tx_token_256->header.ticker; + l_emission_hash = &l_tx_token_256->header.token_emission_hash; + } else { l_err_num = -4; break; } - l_token = l_tx_token->header.ticker; - l_emission_hash = &l_tx_token->header.token_emission_hash; } DAP_DELETE(bound_item); continue; @@ -1702,6 +1747,8 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } uint64_t l_value; + uint256_t l_value_256 = uint256_0; + // Get list of all 'out' items from previous transaction dap_list_t *l_list_prev_out = dap_chain_datum_tx_items_get(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, NULL); // Get one 'out' item in previous transaction bound with current 'in' item @@ -1713,16 +1760,15 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } if (l_cond_type == TX_ITEM_TYPE_IN) { dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_prev_out; - if (l_type == TX_ITEM_TYPE_OUT) { + + if ( l_type == TX_ITEM_TYPE_OUT || l_type == TX_ITEM_TYPE_256_OUT ) { bound_item->out.tx_prev_out = l_tx_prev_out; - memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out->addr,sizeof (bound_item->out.tx_prev_out->addr)); - } else if (l_type == TX_ITEM_TYPE_OUT_EXT) { + memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out->addr,sizeof (bound_item->out.tx_prev_out->addr)); + } else { bound_item->out.tx_prev_out_ext = l_tx_prev_out; memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out_ext->addr,sizeof (bound_item->out.tx_prev_out_ext->addr)); - } else { - l_err_num = -8; - break; } + // calculate hash of public key in current transaction dap_chain_hash_fast_t l_hash_pkey; { @@ -1737,27 +1783,43 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // calculate hash from public key dap_hash_fast(l_pkey_ser, l_pkey_ser_size, &l_hash_pkey); // hash of public key in 'out' item of previous transaction - uint8_t *l_prev_out_addr_key = (l_type == TX_ITEM_TYPE_OUT) ? + + uint8_t *l_prev_out_addr_key = (l_type == TX_ITEM_TYPE_OUT || l_type == TX_ITEM_TYPE_256_OUT) ? bound_item->out.tx_prev_out->addr.data.key : bound_item->out.tx_prev_out_ext->addr.data.key; + // 4. compare public key hashes in the signature of the current transaction and in the 'out' item of the previous transaction if(memcmp(&l_hash_pkey, l_prev_out_addr_key, sizeof(dap_chain_hash_fast_t))) { l_err_num = -9; break; } } - if (l_type == TX_ITEM_TYPE_OUT) { - l_value = bound_item->out.tx_prev_out->header.value; - } else { - l_value = bound_item->out.tx_prev_out_ext->header.value; - l_token = bound_item->out.tx_prev_out_ext->token; + + switch (l_type) { + case TX_ITEM_TYPE_256_OUT: // 256 + l_value_256 = bound_item->out.tx_prev_out->header.value_256; break; + case TX_ITEM_TYPE_OUT: + l_value = bound_item->out.tx_prev_out->header.value; break; + case TX_ITEM_TYPE_256_OUT_EXT: // 256 + l_value_256 = bound_item->out.tx_prev_out_ext->header.value_256; + l_token = bound_item->out.tx_prev_out_ext->token; + break; + case TX_ITEM_TYPE_OUT_EXT: + l_value = bound_item->out.tx_prev_out_ext->header.value; + l_token = bound_item->out.tx_prev_out_ext->token; + break; + default: + log_it(L_DEBUG, "Unknown item type %d", l_type); + break; } + } else { // TX_ITEM_TYPE_IN_COND - if(*(uint8_t *)l_tx_prev_out != TX_ITEM_TYPE_OUT_COND) { + dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_prev_out; + if( l_type != TX_ITEM_TYPE_OUT_COND && l_type != TX_ITEM_TYPE_256_OUT_COND) { l_err_num = -8; break; } - if (! l_token_item){ + if (!l_token_item){ l_err_num = -16; log_it(L_ERROR,"Can't find token item for conditioned tx out"); break; @@ -1771,7 +1833,11 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); size_t l_pkey_ser_size = 0; const uint8_t *l_pkey_ser = dap_sign_get_pkey(l_sign, &l_pkey_ser_size); + dap_chain_tx_out_cond_t *l_tx_prev_out_cond = (dap_chain_tx_out_cond_t *)l_tx_prev_out; + + l_is_type_256 = l_type == TX_ITEM_TYPE_256_OUT_COND ? true : false; + bool l_owner = false; if (l_pkey_ser_size == l_prev_pkey_ser_size && !memcmp(l_prev_pkey_ser, l_pkey_ser, l_prev_pkey_ser_size)) { @@ -1793,9 +1859,13 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_err_num = -14; break; } + bound_item->out.tx_prev_out_cond = l_tx_prev_out_cond; - // calculate sum of values from previous transactions - l_value = l_tx_prev_out_cond->header.value; + if ( l_type == TX_ITEM_TYPE_256_OUT_COND ) { // 256 + l_value_256 = l_tx_prev_out_cond->header.value_256; + } else { + l_value = l_tx_prev_out_cond->header.value; + } l_token = NULL; } if (!l_token || !*l_token) { @@ -1817,6 +1887,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_err_num = -15; break; } + // Check permissions if ( (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED ) || // If all is blocked - check if we're (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN) ){ // in white list @@ -1844,14 +1915,26 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } } - HASH_FIND_STR(l_values_from_prev_tx, l_token, l_value_cur); - if (!l_value_cur) { - l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); - strcpy(l_value_cur->token_ticker, l_token); - HASH_ADD_STR(l_values_from_prev_tx, token_ticker, l_value_cur); + if ( l_is_type_256 ) { // 256 + HASH_FIND_STR(l_values_from_prev_tx_256, l_token, l_value_cur_256); + if (!l_value_cur_256) { + l_value_cur_256 = DAP_NEW_Z(dap_chain_ledger_tokenizer_256_t); + strcpy(l_value_cur_256->token_ticker, l_token); + HASH_ADD_STR(l_values_from_prev_tx_256, token_ticker, l_value_cur_256); + } + SUM_256_256(l_value_cur_256->sum, l_value_256, &l_value_cur_256->sum); + + } else { + HASH_FIND_STR(l_values_from_prev_tx, l_token, l_value_cur); + if (!l_value_cur) { + l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); + strcpy(l_value_cur->token_ticker, l_token); + HASH_ADD_STR(l_values_from_prev_tx, token_ticker, l_value_cur); + } + // calculate sum of values from previous transactions per each token + l_value_cur->sum += l_value; } - // calculate sum of values from previous transactions per each token - l_value_cur->sum += l_value; + l_list_bound_items = dap_list_append(l_list_bound_items, bound_item); } if (l_list_in) @@ -1864,30 +1947,43 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { DAP_DELETE(l_value_cur); } + HASH_ITER(hh, l_values_from_prev_tx_256, l_value_cur_256, l_tmp_256) { + DAP_DELETE(l_value_cur_256); + } return l_err_num; } // 6. Compare sum of values in 'out' items in the current transaction and in the previous transactions // Calculate the sum of values in 'out' items from the current transaction bool l_multichannel = false; - if (HASH_COUNT(l_values_from_prev_tx) > 1) { + if (HASH_COUNT(l_values_from_prev_tx) > 1){ l_multichannel = true; } else { l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); if(l_token) strcpy(l_value_cur->token_ticker, l_token); HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); + + // 256 + l_value_cur_256 = DAP_NEW_Z(dap_chain_ledger_tokenizer_256_t); + if(l_token) + strcpy(l_value_cur_256->token_ticker, l_token); + HASH_ADD_STR(l_values_from_cur_tx_256, token_ticker, l_value_cur_256); } + dap_list_t *l_list_tx_out = NULL; bool emission_flag = !l_is_first_transaction || (l_is_first_transaction && l_ledger_priv->check_token_emission); // find 'out' items dap_list_t *l_list_out = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) a_tx, TX_ITEM_TYPE_OUT_ALL, NULL); uint64_t l_value=0; + uint256_t l_value_256=uint256_0; for (l_list_tmp = l_list_out; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp)) { dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data; dap_chain_addr_t l_tx_out_to={0}; - if (l_type == TX_ITEM_TYPE_OUT) - { + bool l_is_type_256 = false; + + if (l_type == TX_ITEM_TYPE_OUT) { + l_is_type_256 = false; dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)l_list_tmp->data; if (l_multichannel) { // token ticker is mandatory for multichannel transactions l_err_num = -16; @@ -1898,7 +1994,22 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } memcpy(&l_tx_out_to , &l_tx_out->addr, sizeof (l_tx_out_to)); l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); + + } else if (l_type == TX_ITEM_TYPE_256_OUT) { // 256 + l_is_type_256 = true; + dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)l_list_tmp->data; + if (l_multichannel) { // token ticker is mandatory for multichannel transactions + l_err_num = -16; + break; + } + if (emission_flag) { + l_value_256 = l_tx_out->header.value_256; + } + memcpy(&l_tx_out_to , &l_tx_out->addr, sizeof (l_tx_out_to)); + l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); + } else if (l_type == TX_ITEM_TYPE_OUT_EXT) { + l_is_type_256 = false; dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)l_list_tmp->data; if (!l_multichannel) { // token ticker is depricated for single-channel transactions l_err_num = -16; @@ -1910,7 +2021,23 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } memcpy(&l_tx_out_to , &l_tx_out->addr, sizeof (l_tx_out_to)); l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); + + } else if (l_type == TX_ITEM_TYPE_256_OUT_EXT) { // 256 + l_is_type_256 = true; + dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)l_list_tmp->data; + if (!l_multichannel) { // token ticker is depricated for single-channel transactions + l_err_num = -16; + break; + } + if (emission_flag) { + l_value_256 = l_tx_out->header.value_256; + l_token = l_tx_out->token; + } + memcpy(&l_tx_out_to , &l_tx_out->addr, sizeof (l_tx_out_to)); + l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); + } else if (l_type == TX_ITEM_TYPE_OUT_COND) { + l_is_type_256 = false; dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t *)l_list_tmp->data; if (emission_flag) { l_value = l_tx_out->header.value; @@ -1921,16 +2048,42 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t break; } l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); + + } else if (l_type == TX_ITEM_TYPE_256_OUT_COND) { // 256 + l_is_type_256 = true; + dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t *)l_list_tmp->data; + if (emission_flag) { + l_value_256 = l_tx_out->header.value_256; + } + if (l_multichannel) { // out_cond have no field .token + log_it(L_WARNING, "No conditional output support for multichannel transaction"); + l_err_num = -18; + break; + } + l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); } - if (l_multichannel) { - HASH_FIND_STR(l_values_from_cur_tx, l_token, l_value_cur); - if (!l_value_cur) { - l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); - strcpy(l_value_cur->token_ticker, l_token); - HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); + + if (l_is_type_256) { // 256 + if (l_multichannel) { + HASH_FIND_STR(l_values_from_cur_tx_256, l_token, l_value_cur_256); + if (!l_value_cur_256) { + l_value_cur_256 = DAP_NEW_Z(dap_chain_ledger_tokenizer_256_t); + strcpy(l_value_cur_256->token_ticker, l_token); + HASH_ADD_STR(l_values_from_cur_tx_256, token_ticker, l_value_cur_256); + } } + SUM_256_256(l_value_cur_256->sum, l_value_256, &l_value_cur_256->sum); + } else { + if (l_multichannel) { + HASH_FIND_STR(l_values_from_cur_tx, l_token, l_value_cur); + if (!l_value_cur) { + l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); + strcpy(l_value_cur->token_ticker, l_token); + HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); + } + } + l_value_cur->sum += l_value; } - l_value_cur->sum += l_value; // Get permissions for token l_token_item = NULL; @@ -1973,7 +2126,6 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } } - if ( l_list_out ) dap_list_free(l_list_out); @@ -1982,10 +2134,12 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t if (l_ledger_priv->check_token_emission) { // Check the token emission dap_chain_datum_token_emission_t * l_token_emission = dap_chain_ledger_token_emission_find(a_ledger, l_token, l_emission_hash); if (l_token_emission) { - if (l_token_emission->hdr.value != l_value_cur->sum) { + if (l_token_emission->hdr.value != l_value_cur->sum && + !EQUAL_256(l_token_emission->hdr.value_256, l_value_cur_256->sum) ) { l_err_num = -10; } l_value_cur = NULL; + l_value_cur_256 = NULL; } else { log_it(L_WARNING, "Emission for tx_token wasn't found"); l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION; @@ -1994,17 +2148,33 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } break; } + while (!l_is_first_transaction && !l_err_num) { + bool l_err_flag = false; + bool l_err_flag_256 = false; HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { HASH_FIND_STR(l_values_from_cur_tx, l_value_cur->token_ticker, l_res); - if (!l_res || l_res->sum != l_value_cur->sum) { + if (!l_res || (l_res->sum != l_value_cur->sum) ){ //&& !EQUAL_256(l_res->sum_256,l_value_cur->sum_256) ) ) { if(s_debug_more) log_it(L_ERROR, "Sum of values in out items of current tx (%"DAP_UINT64_FORMAT_U") is not equal outs from previous tx (%"DAP_UINT64_FORMAT_U") for token %s", l_res ? l_res->sum : 0, l_value_cur->sum, l_value_cur->token_ticker); - l_err_num = -12; + l_err_flag = true; break; } } + HASH_ITER(hh, l_values_from_prev_tx_256, l_value_cur_256, l_tmp_256) { + HASH_FIND_STR(l_values_from_cur_tx_256, l_value_cur_256->token_ticker, l_res_256); + if (!l_res_256 || !EQUAL_256(l_res_256->sum,l_value_cur_256->sum) ) { + if(s_debug_more) + log_it(L_ERROR, "Sum of values in out items of current tx 256 (%s) is not equal outs from previous tx (%s) for token %s", + dap_chain_u256tostr( ( l_res_256 ? l_res_256->sum : uint256_0) ), dap_chain_u256tostr(l_value_cur_256->sum), l_value_cur_256->token_ticker); + l_err_flag_256 = true; + break; + } + } + if ( l_err_flag && l_err_flag_256 ) + l_err_num = -12; + break; } @@ -2014,6 +2184,15 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t HASH_ITER(hh, l_values_from_cur_tx, l_value_cur, l_tmp) { DAP_DELETE(l_value_cur); } + + // 256 + HASH_ITER(hh, l_values_from_prev_tx_256, l_value_cur_256, l_tmp_256) { + DAP_DELETE(l_value_cur_256); + } + HASH_ITER(hh, l_values_from_cur_tx_256, l_value_cur_256, l_tmp_256) { + DAP_DELETE(l_value_cur_256); + } + if (!a_list_bound_items || l_err_num) { dap_list_free_full(l_list_bound_items, free); } else { @@ -2059,9 +2238,10 @@ int dap_chain_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t * static int s_balance_cache_update(dap_ledger_t *a_ledger, dap_ledger_wallet_balance_t *a_balance) { char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_BALANCES_STR); - uint128_t *l_balance_value = DAP_NEW_Z(uint128_t); + // uint128_t *l_balance_value = DAP_NEW_Z(uint128_t); + uint256_t *l_balance_value = DAP_NEW_Z(uint256_t); *l_balance_value = a_balance->balance; - if (!dap_chain_global_db_gr_set(dap_strdup(a_balance->key), l_balance_value, sizeof(uint128_t), l_gdb_group)) { + if (!dap_chain_global_db_gr_set(dap_strdup(a_balance->key), l_balance_value, sizeof(uint256_t/*uint128_t*/), l_gdb_group)) { if(s_debug_more) log_it(L_WARNING, "Ledger cache mismatch"); DAP_DELETE(l_balance_value); @@ -2165,6 +2345,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, ret = l_ret_check; goto FIN; } + if(s_debug_more) log_it ( L_DEBUG, "dap_chain_ledger_tx_add() check passed for tx %s",l_tx_hash_str); @@ -2177,42 +2358,63 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, // find all bound pairs 'in' and 'out' dap_list_t *l_list_tmp = l_list_bound_items; char *l_ticker_trl = NULL, *l_ticker_old_trl = NULL; + bool l_stake_updated = false; + // Update balance: deducts while(l_list_tmp) { dap_chain_ledger_tx_bound_t *bound_item = l_list_tmp->data; void *l_item_in = *(void **)&bound_item->in; + void *l_item_out = *(void **)&bound_item->out; dap_chain_tx_item_type_t l_type = *(uint8_t *)l_item_in; + dap_chain_tx_item_type_t l_out_type = *(uint8_t *)l_item_out; + dap_chain_ledger_tx_item_t *l_prev_item_out = bound_item->item_out; + l_ticker_trl = *l_prev_item_out->cache_data.token_tiker ? dap_stpcpy(l_token_ticker, l_prev_item_out->cache_data.token_tiker) : dap_stpcpy(l_token_ticker, bound_item->out.tx_prev_out_ext->token); + if (!l_multichannel && l_ticker_old_trl && strcmp(l_token_ticker, l_token_ticker_old)) { l_multichannel = true; } l_ticker_old_trl = dap_stpcpy(l_token_ticker_old, l_token_ticker); int l_tx_prev_out_used_idx; + if (l_type == TX_ITEM_TYPE_IN) { dap_chain_tx_in_t *l_tx_in = bound_item->in.tx_cur_in; dap_ledger_wallet_balance_t *wallet_balance = NULL; - void *l_item_out = *(void **)&bound_item->out; - dap_chain_tx_item_type_t l_out_type = *(uint8_t *)l_item_out; - dap_chain_addr_t *l_addr = (l_out_type == TX_ITEM_TYPE_OUT) ? + //void *l_item_out = *(void **)&bound_item->out; + //dap_chain_tx_item_type_t l_out_type = *(uint8_t *)l_item_out; + + //dap_chain_addr_t *l_addr = NULL; + uint256_t l_value = uint256_0; + + dap_chain_addr_t *l_addr = (l_out_type == TX_ITEM_TYPE_OUT || l_out_type == TX_ITEM_TYPE_256_OUT) ? &bound_item->out.tx_prev_out->addr : &bound_item->out.tx_prev_out_ext->addr; + char *l_addr_str = dap_chain_addr_to_str(l_addr); char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_token_ticker, (char*)NULL); pthread_rwlock_rdlock(&PVT(a_ledger)->balance_accounts_rwlock); HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, wallet_balance); pthread_rwlock_unlock(&PVT(a_ledger)->balance_accounts_rwlock); if (wallet_balance) { - uint64_t l_value = (l_out_type == TX_ITEM_TYPE_OUT) ? - bound_item->out.tx_prev_out->header.value : - bound_item->out.tx_prev_out_ext->header.value; + switch (l_out_type) { + case TX_ITEM_TYPE_256_OUT: l_value = bound_item->out.tx_prev_out->header.value_256; break; + case TX_ITEM_TYPE_OUT: l_value = GET_256_FROM_64(bound_item->out.tx_prev_out->header.value); break; + case TX_ITEM_TYPE_256_OUT_EXT: l_value = bound_item->out.tx_prev_out_ext->header.value_256; break; + case TX_ITEM_TYPE_OUT_EXT: l_value = GET_256_FROM_64(bound_item->out.tx_prev_out_ext->header.value); break; + default: + log_it(L_DEBUG, "Unknown item type %d", l_type); + break; + } + if(s_debug_more) - log_it(L_DEBUG,"SPEND %"DAP_UINT64_FORMAT_U" from addr: %s", l_value, l_wallet_balance_key); - uint128_t l_sub = dap_chain_uint128_from(l_value); - wallet_balance->balance = dap_uint128_substract(wallet_balance->balance, l_sub); + log_it(L_DEBUG,"SPEND %s from addr: %s", dap_chain_u256tostr(l_value), l_wallet_balance_key); + + SUBTRACT_256_256(wallet_balance->balance, l_value, &wallet_balance->balance); + // Update the cache s_balance_cache_update(a_ledger, wallet_balance); } else { @@ -2221,9 +2423,11 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, } DAP_DELETE(l_addr_str); DAP_DELETE(l_wallet_balance_key); + /// Mark 'out' item in cache because it used l_tx_prev_out_used_idx = l_tx_in->header.tx_out_prev_idx; } else { // TX_ITEM_TYPE_IN_COND + // all balance deducts performed with previous conditional transaction dap_chain_tx_in_cond_t *l_tx_in_cond = bound_item->in.tx_cur_in_cond; /// Mark 'out' item in cache because it used @@ -2242,6 +2446,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, l_stake_updated = true; } } + // add a used output memcpy(&(l_prev_item_out->cache_data.tx_hash_spent_fast[l_tx_prev_out_used_idx]), l_tx_hash, sizeof(dap_chain_hash_fast_t)); l_prev_item_out->cache_data.n_outs_used++; @@ -2274,9 +2479,11 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, goto FIN; } } + // go to next previous transaction l_list_tmp = dap_list_next(l_list_tmp); } + if (l_list_bound_items) dap_list_free_full(l_list_bound_items, free); @@ -2286,15 +2493,18 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, //dap_list_t *l_base_tx_list = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_TOKEN, &l_base_tx_count ); //if (l_base_tx_count >=1 && l_base_tx_list){ dap_chain_tx_token_t * l_tx_token = (dap_chain_tx_token_t *) dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_TOKEN, NULL); - if (l_tx_token) + dap_chain_tx_token_t * l_tx_token_256 = (dap_chain_tx_token_t *) dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_256_TOKEN, NULL); + + if ( l_tx_token_256 ) + l_ticker_trl = dap_stpcpy(l_token_ticker, l_tx_token_256->header.ticker); + else if (l_tx_token) l_ticker_trl = dap_stpcpy(l_token_ticker, l_tx_token->header.ticker); - //} } //Update balance : raise for (dap_list_t *l_tx_out = l_list_tx_out; l_tx_out; l_tx_out = dap_list_next(l_tx_out)) { dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_out->data; - if (l_type == TX_ITEM_TYPE_OUT_COND) { + if (l_type == TX_ITEM_TYPE_OUT_COND || l_type == TX_ITEM_TYPE_256_OUT_COND) { // Update stakes if any dap_chain_tx_out_cond_t *l_cond = (dap_chain_tx_out_cond_t *)l_tx_out->data; if (l_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE && !l_stake_updated) { @@ -2309,17 +2519,24 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, } continue; // balance raise will be with next conditional transaction } + dap_chain_tx_out_t *l_out_item = NULL; dap_chain_tx_out_ext_t *l_out_item_ext = NULL; - if (l_type == TX_ITEM_TYPE_OUT) { - l_out_item = (dap_chain_tx_out_t *)l_tx_out->data; - } else { - l_out_item_ext = (dap_chain_tx_out_ext_t *)l_tx_out->data; + switch (l_type) { + case TX_ITEM_TYPE_256_OUT: l_out_item = (dap_chain_tx_out_t *)l_tx_out->data; break; + case TX_ITEM_TYPE_OUT: l_out_item = (dap_chain_tx_out_t *)l_tx_out->data; break; + case TX_ITEM_TYPE_256_OUT_EXT: l_out_item_ext = (dap_chain_tx_out_ext_t *)l_tx_out->data; break; + case TX_ITEM_TYPE_OUT_EXT: l_out_item_ext = (dap_chain_tx_out_ext_t *)l_tx_out->data; break; + default: + log_it(L_DEBUG, "Unknown item type %d", l_type); + break; } + if ((l_out_item || l_out_item_ext) && l_ticker_trl) { - dap_chain_addr_t *l_addr = (l_type == TX_ITEM_TYPE_OUT) ? + dap_chain_addr_t *l_addr = (l_type == TX_ITEM_TYPE_OUT || l_type == TX_ITEM_TYPE_256_OUT) ? &l_out_item->addr : &l_out_item_ext->addr; + char *l_addr_str = dap_chain_addr_to_str(l_addr); //log_it (L_DEBUG, "Check unspent %.03Lf %s for addr %s", @@ -2330,18 +2547,30 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, l_ticker_trl = dap_stpcpy(l_token_ticker, l_out_item_ext->token); } char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_token_ticker, (char*)NULL); - uint64_t l_value = (l_type == TX_ITEM_TYPE_OUT) ? l_out_item->header.value : l_out_item_ext->header.value; + uint64_t l_value = 0; + uint256_t l_value_256 = uint256_0; + switch (l_type) { + case TX_ITEM_TYPE_256_OUT: l_value_256 = l_out_item->header.value_256; break; // _256 + case TX_ITEM_TYPE_OUT: l_value_256 = GET_256_FROM_64(l_out_item->header.value); break; + case TX_ITEM_TYPE_256_OUT_EXT: l_value_256 = l_out_item_ext->header.value_256; break; // _256 + case TX_ITEM_TYPE_OUT_EXT: l_value_256 = GET_256_FROM_64(l_out_item_ext->header.value); break; + default: + log_it(L_DEBUG, "Unknown item type %d", l_type); + break; + } + + // l_value = (l_type == TX_ITEM_TYPE_OUT || l_type == TX_ITEM_TYPE_256_OUT) ? l_out_item->header.value : l_out_item_ext->header.value; if(s_debug_more) - log_it (L_DEBUG,"GOT %"DAP_UINT64_FORMAT_U" to addr: %s", l_value, l_wallet_balance_key); + log_it (L_DEBUG,"GOT %s to addr: %s", dap_chain_u256tostr(l_value_256), l_wallet_balance_key); pthread_rwlock_rdlock(&l_ledger_priv->balance_accounts_rwlock); HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, wallet_balance); pthread_rwlock_unlock(&l_ledger_priv->balance_accounts_rwlock); if (wallet_balance) { if(s_debug_more) log_it(L_DEBUG, "Balance item is present in cache"); - uint128_t l_add = dap_chain_uint128_from(l_value); - wallet_balance->balance = dap_uint128_add(wallet_balance->balance, l_add); + + SUM_256_256(wallet_balance->balance, l_value_256, &wallet_balance->balance); DAP_DELETE (l_wallet_balance_key); // Update the cache s_balance_cache_update(a_ledger, wallet_balance); @@ -2349,8 +2578,9 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, wallet_balance = DAP_NEW_Z(dap_ledger_wallet_balance_t); wallet_balance->key = l_wallet_balance_key; strcpy(wallet_balance->token_ticker, l_token_ticker); - uint128_t l_add = dap_chain_uint128_from(l_value); - wallet_balance->balance = dap_uint128_add(wallet_balance->balance, l_add); + + SUM_256_256(wallet_balance->balance, l_value_256, &wallet_balance->balance); + if(s_debug_more) log_it(L_DEBUG,"!!! Create new balance item: %s %s", l_addr_str, l_token_ticker); pthread_rwlock_wrlock(&l_ledger_priv->balance_accounts_rwlock); @@ -2396,9 +2626,13 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, //if ( l_tokens_count>0 ){ //dap_chain_tx_token_t * l_token = (dap_chain_tx_token_t*) l_tokens_list->data; dap_chain_tx_token_t *l_token = (dap_chain_tx_token_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_TOKEN, NULL); + // 256 + dap_chain_tx_token_t *l_token_256 = (dap_chain_tx_token_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_256_TOKEN, NULL); l_ticker_trl = l_token ? dap_stpcpy(l_token_ticker, l_token->header.ticker) - : NULL; + : ( l_token_256 // 256 + ? dap_stpcpy(l_token_ticker, l_token_256->header.ticker) + : NULL ); //dap_list_free(l_tokens_list); //} } @@ -2637,14 +2871,17 @@ bool dap_chain_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain * Calculate balance of addr * */ -uint128_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, +uint256_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, const char *a_token_ticker) { -#ifdef DAP_GLOBAL_IS_INT128 - uint128_t l_ret = 0; -#else - uint128_t l_ret = {}; -#endif +// #ifdef DAP_GLOBAL_IS_INT128 +// uint128_t l_ret = 0; +// #else +// uint128_t l_ret = {}; +// #endif + //uint128_t l_ret = uint128_0; + uint256_t l_ret = uint256_0; + dap_ledger_wallet_balance_t *l_balance_item = NULL;// ,* l_balance_item_tmp = NULL; char *l_addr = dap_chain_addr_to_str(a_addr); char *l_wallet_balance_key = dap_strjoin(" ", l_addr, a_token_ticker, (char*)NULL); @@ -2653,8 +2890,8 @@ uint128_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_ pthread_rwlock_unlock(&PVT(a_ledger)->balance_accounts_rwlock); if (l_balance_item) { if(s_debug_more) - log_it (L_INFO,"Found address in cache with balance %"DAP_UINT64_FORMAT_U"", - dap_chain_uint128_to(l_balance_item->balance)); + log_it (L_INFO,"Found address in cache with balance %s", + dap_chain_u256tostr(l_balance_item->balance)); l_ret = l_balance_item->balance; } else { if (s_debug_more) @@ -2665,14 +2902,17 @@ uint128_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_ return l_ret; } -uint128_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, +uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, const char *a_token_ticker) { -#ifdef DAP_GLOBAL_IS_INT128 - uint128_t balance = 0; -#else - uint128_t balance = {0}; -#endif +// #ifdef DAP_GLOBAL_IS_INT128 +// uint128_t balance = 0; +// #else +// uint128_t balance = {0}; +// #endif + //uint128_t balance = uint128_0; + uint256_t balance = uint256_0; + if(!a_addr || !dap_chain_addr_check_sum(a_addr)) return balance; /* proto @@ -2701,7 +2941,8 @@ uint128_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c if(s_debug_more) log_it(L_ERROR, "Too many 'out' items=%d in transaction (max=%d)", l_out_item_count, MAX_OUT_ITEMS); if (l_out_item_count >= MAX_OUT_ITEMS){ - uint128_t l_ret; + // uint128_t l_ret; + uint256_t l_ret = uint256_0; memset(&l_ret,0,sizeof(l_ret)); return l_ret; } @@ -2722,9 +2963,25 @@ uint128_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c // if 'out' item not used & transaction is valid if(!dap_chain_ledger_item_is_used_out(l_iter_current, l_out_idx_tmp) && dap_chain_datum_tx_verify_sign(l_cur_tx)) { - - uint128_t l_add = dap_chain_uint128_from(l_tx_out->header.value); - balance = dap_uint128_add(balance, l_add); + // uint128_t l_add = dap_chain_uint128_from(l_tx_out->header.value); + // balance = dap_uint128_add(balance, l_add); + uint256_t l_add = dap_chain_uint256_from(l_tx_out->header.value); + SUM_256_256(balance, l_add, &balance); + } + } + } + } + if (l_type == TX_ITEM_TYPE_256_OUT) { // 256 + //const dap_chain_256_tx_out_t *l_tx_out = (const dap_chain_256_tx_out_t*) l_list_tmp->data; + const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data; + // Check for token name + if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_tiker)) + { // if transaction has the out item with requested addr + if (!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) { + // if 'out' item not used & transaction is valid + if(!dap_chain_ledger_item_is_used_out(l_iter_current, l_out_idx_tmp) && + dap_chain_datum_tx_verify_sign(l_cur_tx)) { + SUM_256_256(balance, l_tx_out->header.value_256, &balance); } } } @@ -2738,8 +2995,23 @@ uint128_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c // if 'out' item not used & transaction is valid if(!dap_chain_ledger_item_is_used_out(l_iter_current, l_out_idx_tmp) && dap_chain_datum_tx_verify_sign(l_cur_tx)) { - uint128_t l_add = dap_chain_uint128_from(l_tx_out->header.value); - balance = dap_uint128_add(balance, l_add); + uint256_t l_add = dap_chain_uint256_from(l_tx_out->header.value); + SUM_256_256(balance, l_add, &balance); + } + } + } + } + if (l_type == TX_ITEM_TYPE_256_OUT_EXT) { // 256 + // const dap_chain_256_tx_out_ext_t *l_tx_out = (const dap_chain_256_tx_out_ext_t*) l_list_tmp->data; + const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) l_list_tmp->data; + // Check for token name + if (!strcmp(a_token_ticker, l_tx_out->token)) + { // if transaction has the out item with requested addr + if (!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) { + // if 'out' item not used & transaction is valid + if(!dap_chain_ledger_item_is_used_out(l_iter_current, l_out_idx_tmp) && + dap_chain_datum_tx_verify_sign(l_cur_tx)) { + SUM_256_256(balance, l_tx_out->header.value_256, &balance); } } } @@ -3001,6 +3273,7 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items dap_chain_hash_fast_t l_tx_cur_hash = { 0 }; uint64_t l_value_transfer = 0; + //uint256_t l_value_transfer = uint256_0; while(l_value_transfer < a_value_need) { // Get the transaction in the cache by the addr in out item @@ -3014,34 +3287,70 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c uint32_t l_out_idx_tmp = 0; // current index of 'out' item for (dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_out_idx_tmp++) { dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data; - if (l_type == TX_ITEM_TYPE_OUT_COND) { + if (l_type == TX_ITEM_TYPE_OUT_COND || l_type == TX_ITEM_TYPE_256_OUT_COND) { continue; } - uint64_t l_value; - if (l_type == TX_ITEM_TYPE_OUT) { - dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t *)l_list_tmp->data; - if (!l_out->header.value || memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t))) { - continue; - } - l_value = l_out->header.value; - } else { // TX_ITEM_TYPE_OUT_EXT - dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)l_list_tmp->data; - if (!l_out_ext->header.value || memcmp(a_addr_from, &l_out_ext->addr, sizeof(dap_chain_addr_t)) || - strcmp((char *)a_token_ticker, l_out_ext->token)) { - continue; - } - l_value = l_out_ext->header.value; + // uint64_t l_value; + uint256_t l_value = uint256_0; + switch (l_type) { + case TX_ITEM_TYPE_OUT: { + dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t *)l_list_tmp->data; + if (!l_out->header.value || memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t))) { + continue; + } + l_value = GET_256_FROM_64(l_out->header.value); + } break; + case TX_ITEM_TYPE_256_OUT: { + dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t *)l_list_tmp->data; + if ( IS_ZERO_256(l_out->header.value_256) || memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t))) { + continue; + } + l_value = l_out->header.value_256; + } break; + case TX_ITEM_TYPE_OUT_EXT: { + dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)l_list_tmp->data; + if (!l_out_ext->header.value || memcmp(a_addr_from, &l_out_ext->addr, sizeof(dap_chain_addr_t)) || + strcmp((char *)a_token_ticker, l_out_ext->token)) { + continue; + } + l_value = GET_256_FROM_64(l_out_ext->header.value); + } break; + case TX_ITEM_TYPE_256_OUT_EXT: { + dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)l_list_tmp->data; + if ( IS_ZERO_256(l_out_ext->header.value_256) || memcmp(a_addr_from, &l_out_ext->addr, sizeof(dap_chain_addr_t)) || + strcmp((char *)a_token_ticker, l_out_ext->token)) { + continue; + } + l_value = l_out_ext->header.value_256; + } break; } + // if (l_type == TX_ITEM_TYPE_OUT) { + // dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t *)l_list_tmp->data; + // if (!l_out->header.value || memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t))) { + // continue; + // } + // l_value = l_out->header.value; + // } else { // TX_ITEM_TYPE_OUT_EXT + // dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)l_list_tmp->data; + // if (!l_out_ext->header.value || memcmp(a_addr_from, &l_out_ext->addr, sizeof(dap_chain_addr_t)) || + // strcmp((char *)a_token_ticker, l_out_ext->token)) { + // continue; + // } + // l_value = l_out_ext->header.value; + // } // Check whether used 'out' items + if (!dap_chain_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp)) { list_used_item_t *item = DAP_NEW(list_used_item_t); memcpy(&item->tx_hash_fast, &l_tx_cur_hash, sizeof(dap_chain_hash_fast_t)); item->num_idx_out = l_out_idx_tmp; - item->value = l_value; + item->value = dap_chain_uint256_to(l_value); // this is temporary for compatibility :-) l_list_used_out = dap_list_append(l_list_used_out, item); l_value_transfer += item->value; + //SUM_256_256(l_value_transfer, item->value, &l_value_transfer); // already accumulated the required value, finish the search for 'out' items if (l_value_transfer >= a_value_need) { + //if (compare256(l_value_transfer, a_value_need) >= 0) { break; } } @@ -3051,6 +3360,7 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c // nothing to tranfer (not enough funds) if(!l_list_used_out || l_value_transfer < a_value_need) { + // if(!l_list_used_out || compare256(l_value_transfer, a_value_need) < 0) { dap_list_free_full(l_list_used_out, free); return NULL; } diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index 5d6de24f6666dfe727b6770e097da2ac02b0669a..30fd91383f72c16923d2f203eaf856c740a61514 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -92,7 +92,9 @@ typedef enum dap_chain_type CHAIN_TYPE_FIRST, CHAIN_TYPE_TOKEN, CHAIN_TYPE_EMISSION, + CHAIN_TYPE_256_EMISSION, // 256 CHAIN_TYPE_TX, + CHAIN_TYPE_256_TX, // 256 CHAIN_TYPE_CA, CHAIN_TYPE_LAST } dap_chain_type_t; diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h index 524d3bc49bb722df1817799653c5e871bb6c55b3..aa8fc05e8c91ed891fd549652f3caf7af90f4998 100644 --- a/modules/chain/include/dap_chain_ledger.h +++ b/modules/chain/include/dap_chain_ledger.h @@ -127,6 +127,7 @@ dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger); /** * Add token emission datum */ + int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size); int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size); @@ -177,10 +178,10 @@ bool dap_chain_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain * Calculate balance of addr * */ -uint128_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, +uint256_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, const char *a_token_ticker); -uint128_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, +uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, const char *a_token_ticker); /** diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c index 3189c9ec51e390b3fe0ae5c596c51b256626d4df..8b6c329fa58bc9e1af94ac13dfb6ee1364ca94d8 100644 --- a/modules/common/dap_chain_common.c +++ b/modules/common/dap_chain_common.c @@ -282,6 +282,15 @@ int dap_chain_addr_check_sum(const dap_chain_addr_t *a_addr) return -1; } +// 256 +uint128_t dap_chain_uint128_from_uint256(uint256_t a_from) +{ + if ( !( EQUAL_128(a_from.hi, uint128_0) ) ) { + log_it(L_ERROR, "Can't convert to uint128_t. It's too big."); + } + return a_from.lo; +} + uint64_t dap_chain_uint128_to(uint128_t a_from) { #ifdef DAP_GLOBAL_IS_INT128 @@ -297,6 +306,20 @@ uint64_t dap_chain_uint128_to(uint128_t a_from) #endif } +// 256 +uint64_t dap_chain_uint256_to(uint256_t a_from) +{ + return dap_chain_uint128_to(a_from.lo); +} + +// for tests +char *dap_chain_u256tostr(uint256_t v_256) +{ + char *dest = malloc(130 * sizeof(char)); + return strcpy(dest, dap_utoa128((char[130]){}, dap_chain_uint128_from_uint256(v_256), 10)); +} + + char *dap_chain_balance_print(uint128_t a_balance) { char *l_buf = DAP_NEW_Z_SIZE(char, DATOSHI_POW + 3); @@ -421,25 +444,29 @@ uint128_t dap_chain_balance_scan(char *a_balance) return l_nul; } l_tmp = (l_tmp << 64) + c_pow10[i].u64[1] * l_digit; - l_ret = dap_uint128_add(l_ret, l_tmp); + // l_ret = dap_uint128_add(l_ret, l_tmp); + SUM_128_128(l_ret, l_tmp, &l_ret); if (l_ret == l_nul) return l_nul; #else uint128_t l_tmp; l_tmp.u64[0] = 0; l_tmp.u64[1] = c_pow10[i].u32[2] * l_digit; - l_ret = dap_uint128_add(l_ret, l_tmp); + // l_ret = dap_uint128_add(l_ret, l_tmp); + SUM_128_128(l_ret, l_tmp, &l_ret); if (l_ret.u64[0] == 0 && l_ret.u64[1] == 0) return l_nul; uint64_t l_mul = c_pow10[i].u32[3] * l_digit; l_tmp.u64[1] = l_mul << 32; l_tmp.u64[0] = l_mul >> 32; - l_ret = dap_uint128_add(l_ret, l_tmp); + // l_ret = dap_uint128_add(l_ret, l_tmp); + SUM_128_128(l_ret, l_tmp, &l_ret); if (l_ret.u64[0] == 0 && l_ret.u64[1] == 0) return l_nul; l_tmp.u64[1] = 0; l_tmp.u64[0] = c_pow10[i].u32[0] * l_digit; - l_ret = dap_uint128_add(l_ret, l_tmp); + //l_ret = dap_uint128_add(l_ret, l_tmp); + SUM_128_128(l_ret, l_tmp, &l_ret); if (l_ret.u64[0] == 0 && l_ret.u64[1] == 0) return l_nul; l_mul = c_pow10[i].u32[1] * l_digit; @@ -448,7 +475,8 @@ uint128_t dap_chain_balance_scan(char *a_balance) return l_nul; } l_tmp.u64[0] = l_mul << 32; - l_ret = dap_uint128_add(l_ret, l_tmp); + //l_ret = dap_uint128_add(l_ret, l_tmp); + SUM_128_128(l_ret, l_tmp, &l_ret); if (l_ret.u64[0] == 0 && l_ret.u64[1] == 0) return l_nul; #endif diff --git a/modules/common/dap_chain_datum_tx.c b/modules/common/dap_chain_datum_tx.c index 6f48ec58ed6d1381985539588f87b58674f7a536..7c91336dfcea560008144827508c0f777504426c 100644 --- a/modules/common/dap_chain_datum_tx.c +++ b/modules/common/dap_chain_datum_tx.c @@ -118,6 +118,27 @@ uint64_t dap_chain_datum_tx_add_in_item_list(dap_chain_datum_tx_t **a_tx, dap_li return l_value_to_items; } +// 256 +uint256_t dap_chain_datum_256_tx_add_in_item_list(dap_chain_datum_tx_t **a_tx, dap_list_t *a_list_used_out) +{ + dap_list_t *l_list_tmp = a_list_used_out; + uint256_t l_value_to_items = uint256_0; // how many datoshi to transfer + while (l_list_tmp) { + list_used_item_256_t *item = l_list_tmp->data; + if (dap_chain_datum_tx_add_in_item(a_tx, &item->tx_hash_fast, item->num_idx_out) == 1) { + //l_value_to_items += item->value; + int overflow_flag = SUM_256_256(l_value_to_items, item->value, &l_value_to_items); + if ( overflow_flag > 0 ) { + log_it(L_ERROR,"overflow sum 256 256"); + } + + } + l_list_tmp = dap_list_next(l_list_tmp); + } + return l_value_to_items; +} + + /** * @brief dap_chain_datum_tx_add_in_cond_item @@ -158,6 +179,18 @@ int dap_chain_datum_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain return -1; } +// 256 +int dap_chain_datum_256_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint256_t a_value) +{ + dap_chain_tx_out_t *l_tx_out = dap_chain_datum_tx_item_256_out_create(a_addr, a_value); + if(l_tx_out) { + dap_chain_datum_tx_add_item(a_tx, (const uint8_t *)l_tx_out); + DAP_DELETE(l_tx_out); + return 1; + } + return -1; +} + /** * Create 'out_ext' item and insert to transaction * @@ -174,6 +207,17 @@ int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_c return -1; } +// 256 +int dap_chain_datum_256_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint256_t a_value, const char *a_token) +{ + dap_chain_tx_out_ext_t *l_tx_out = dap_chain_datum_tx_item_256_out_ext_create(a_addr, a_value, a_token); + if(l_tx_out) { + dap_chain_datum_tx_add_item(a_tx, (const uint8_t *)l_tx_out); + DAP_DELETE(l_tx_out); + return 1; + } + return -1; +} /** * Create 'out_cond' item and insert to transaction * @@ -192,6 +236,21 @@ int dap_chain_datum_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_enc_ke return -1; } +// 256 +int dap_chain_datum_256_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid, + uint256_t a_value, uint256_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, const void *a_cond, size_t a_cond_size) +{ + dap_chain_tx_out_cond_t *l_tx_out = dap_chain_datum_tx_item_256_out_cond_create_srv_pay( + a_key, a_srv_uid,a_value, a_value_max_per_unit, a_unit, a_cond, a_cond_size ); + if(l_tx_out) { + dap_chain_datum_tx_add_item(a_tx, (const uint8_t *) l_tx_out); + DAP_DELETE(l_tx_out); + return 1; + } + return -1; +} + + /** * Sign a transaction (Add sign item to transaction) * diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c index 38cde942ce07b84b0891e1316f7e2965674507eb..5648eb92cff4a4b2c54ff49e6c0865487e5f812d 100644 --- a/modules/common/dap_chain_datum_tx_items.c +++ b/modules/common/dap_chain_datum_tx_items.c @@ -58,6 +58,7 @@ static size_t dap_chain_tx_out_get_size(const dap_chain_tx_out_t *a_item) return size; } + static size_t dap_chain_tx_out_ext_get_size(const dap_chain_tx_out_ext_t *a_item) { (void) a_item; @@ -65,6 +66,7 @@ static size_t dap_chain_tx_out_ext_get_size(const dap_chain_tx_out_ext_t *a_item return size; } + static size_t dap_chain_tx_out_cond_get_size(const dap_chain_tx_out_cond_t *a_item) { return sizeof(dap_chain_tx_out_cond_t) + a_item->params_size; @@ -117,17 +119,30 @@ size_t dap_chain_datum_item_tx_get_size(const uint8_t *a_item) case TX_ITEM_TYPE_OUT: // Transaction outputs size = dap_chain_tx_out_get_size((const dap_chain_tx_out_t*) a_item); break; + case TX_ITEM_TYPE_256_OUT: // 256 + size = dap_chain_tx_out_get_size((const dap_chain_tx_out_t*) a_item); + break; case TX_ITEM_TYPE_OUT_EXT: size = dap_chain_tx_out_ext_get_size((const dap_chain_tx_out_ext_t*) a_item); break; + case TX_ITEM_TYPE_256_OUT_EXT: // 256 + size = dap_chain_tx_out_ext_get_size((const dap_chain_tx_out_ext_t*) a_item); + break; case TX_ITEM_TYPE_RECEIPT: // Receipt size = dap_chain_datum_tx_receipt_get_size((const dap_chain_datum_tx_receipt_t*) a_item); + break; + case TX_ITEM_TYPE_256_RECEIPT: // 256 + size = dap_chain_datum_tx_receipt_get_size((const dap_chain_datum_tx_receipt_t*) a_item); + break; case TX_ITEM_TYPE_IN_COND: // Transaction inputs with condition size = dap_chain_tx_in_cond_get_size((const dap_chain_tx_in_cond_t*) a_item); break; case TX_ITEM_TYPE_OUT_COND: // Transaction output with condition size = dap_chain_tx_out_cond_get_size((const dap_chain_tx_out_cond_t*) a_item); break; + case TX_ITEM_TYPE_256_OUT_COND: // 256 + size = dap_chain_tx_out_cond_get_size((const dap_chain_tx_out_cond_t*) a_item); + break; case TX_ITEM_TYPE_PKEY: // Transaction public keys size = dap_chain_tx_pkey_get_size((const dap_chain_tx_pkey_t*) a_item); break; @@ -137,6 +152,9 @@ size_t dap_chain_datum_item_tx_get_size(const uint8_t *a_item) case TX_ITEM_TYPE_TOKEN: // token item size = dap_chain_tx_token_get_size((const dap_chain_tx_token_t*) a_item); break; + case TX_ITEM_TYPE_256_TOKEN: // token item + size = dap_chain_tx_token_get_size((const dap_chain_tx_token_t*) a_item); + break; default: return 0; } @@ -158,6 +176,17 @@ dap_chain_tx_token_t* dap_chain_datum_tx_item_token_create(dap_chain_hash_fast_t strncpy(l_item->header.ticker, a_ticker, sizeof(l_item->header.ticker) - 1); return l_item; } +// 256 +dap_chain_tx_token_t* dap_chain_datum_tx_item_256_token_create(dap_chain_hash_fast_t * a_datum_token_hash,const char * a_ticker) +{ + if(!a_ticker) + return NULL; + dap_chain_tx_token_t *l_item = DAP_NEW_Z(dap_chain_tx_token_t); + l_item->header.type = TX_ITEM_TYPE_256_TOKEN; + memcpy (& l_item->header.token_emission_hash, a_datum_token_hash, sizeof ( *a_datum_token_hash ) ); + strncpy(l_item->header.ticker, a_ticker, sizeof(l_item->header.ticker) - 1); + return l_item; +} /** * Create item dap_chain_tx_out_t @@ -211,6 +240,18 @@ dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a return l_item; } +//256 +dap_chain_tx_out_t* dap_chain_datum_tx_item_256_out_create(const dap_chain_addr_t *a_addr, uint256_t a_value) +{ + if(!a_addr) + return NULL; + dap_chain_tx_out_t *l_item = DAP_NEW_Z(dap_chain_tx_out_t); + l_item->header.type = TX_ITEM_TYPE_256_OUT; + l_item->header.value_256 = a_value; + memcpy(&l_item->addr, a_addr, sizeof(dap_chain_addr_t)); + return l_item; +} + dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_addr_t *a_addr, uint64_t a_value, const char *a_token) { if (!a_addr || !a_token) @@ -223,6 +264,20 @@ dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_a return l_item; } +//256 +dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_256_out_ext_create(const dap_chain_addr_t *a_addr, uint256_t a_value, const char *a_token) +{ + if (!a_addr || !a_token) + return NULL; + dap_chain_tx_out_ext_t *l_item = DAP_NEW_Z(dap_chain_tx_out_ext_t); + l_item->header.type = TX_ITEM_TYPE_256_OUT_EXT; + l_item->header.value_256 = a_value; + memcpy(&l_item->addr, a_addr, sizeof(dap_chain_addr_t)); + strcpy(l_item->token, a_token); + return l_item; +} + + /** * Create item dap_chain_tx_out_cond_t * @@ -254,6 +309,34 @@ dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_pay(dap_enc return l_item; } +// 256 +dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_256_out_cond_create_srv_pay(dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid, + uint256_t a_value,uint256_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, + const void *a_params, size_t a_params_size) +{ + if(!a_key || !a_params) + return NULL; + size_t l_pub_key_size = 0; + uint8_t *l_pub_key = dap_enc_key_serealize_pub_key(a_key, &l_pub_key_size); + + + dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE(dap_chain_tx_out_cond_t, sizeof(dap_chain_tx_out_cond_t) + a_params_size); + if(l_item == NULL) + return NULL; + + l_item->header.item_type = TX_ITEM_TYPE_256_OUT_COND; + l_item->header.value_256 = a_value; + l_item->header.subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY; // By default creatre cond for service pay. Rework with smth more flexible + l_item->subtype.srv_pay.srv_uid = a_srv_uid; + l_item->subtype.srv_pay.unit = a_unit; + l_item->subtype.srv_pay.unit_price_max_datoshi_256 = a_value_max_per_unit; + dap_hash_fast( l_pub_key, l_pub_key_size, & l_item->subtype.srv_pay.pkey_hash); + l_item->params_size = (uint32_t)a_params_size; + memcpy(l_item->params, a_params, a_params_size); + return l_item; +} + + dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap_chain_net_srv_uid_t a_srv_uid, dap_chain_net_id_t a_net_id, const char *a_token, uint64_t a_value, @@ -276,6 +359,28 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap return l_item; } +// 256 +dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_256_out_cond_create_srv_xchange(dap_chain_net_srv_uid_t a_srv_uid, dap_chain_net_id_t a_net_id, + const char *a_token, uint256_t a_value, + const void *a_params, uint32_t a_params_size) +{ + if (!a_token) { + return NULL; + } + dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE(dap_chain_tx_out_cond_t, sizeof(dap_chain_tx_out_cond_t) + a_params_size); + l_item->header.item_type = TX_ITEM_TYPE_256_OUT_COND; + l_item->header.value_256 = a_value; + l_item->header.subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE; + l_item->subtype.srv_xchange.srv_uid = a_srv_uid; + l_item->subtype.srv_xchange.net_id = a_net_id; + strcpy(l_item->subtype.srv_xchange.token, a_token); + l_item->params_size = a_params_size; + if (a_params_size) { + memcpy(l_item->params, a_params, a_params_size); + } + return l_item; +} + dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint64_t a_value, long double a_fee_value, dap_chain_addr_t *a_fee_addr, dap_chain_addr_t *a_hldr_addr, const void *a_params, uint32_t a_params_size) @@ -295,6 +400,27 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_c return l_item; } +// 256 +dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_256_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value, long double a_fee_value, + dap_chain_addr_t *a_fee_addr, dap_chain_addr_t *a_hldr_addr, + const void *a_params, uint32_t a_params_size) +{ + dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE(dap_chain_tx_out_cond_t, sizeof(dap_chain_tx_out_cond_t) + a_params_size); + l_item->header.item_type = TX_ITEM_TYPE_256_OUT_COND; + l_item->header.value_256 = a_value; + l_item->header.subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE; + l_item->subtype.srv_stake.srv_uid = a_srv_uid; + l_item->subtype.srv_stake.fee_value = a_fee_value; + memcpy(&l_item->subtype.srv_stake.fee_addr, a_fee_addr, sizeof(dap_chain_addr_t)); + memcpy(&l_item->subtype.srv_stake.hldr_addr, a_hldr_addr, sizeof(dap_chain_addr_t)); + l_item->params_size = a_params_size; + if (a_params_size) { + memcpy(l_item->params, a_params, a_params_size); + } + return l_item; +} + + /** * Create item dap_chain_tx_sig_t * @@ -358,7 +484,11 @@ uint8_t* dap_chain_datum_tx_item_get( dap_chain_datum_tx_t *a_tx, int *a_item_id if (a_type == TX_ITEM_TYPE_ANY || a_type == l_type || (a_type == TX_ITEM_TYPE_OUT_ALL && l_type == TX_ITEM_TYPE_OUT) || (a_type == TX_ITEM_TYPE_OUT_ALL && l_type == TX_ITEM_TYPE_OUT_COND) || - (a_type == TX_ITEM_TYPE_OUT_ALL && l_type == TX_ITEM_TYPE_OUT_EXT)) { + (a_type == TX_ITEM_TYPE_OUT_ALL && l_type == TX_ITEM_TYPE_OUT_EXT) || + (a_type == TX_ITEM_TYPE_OUT_ALL && l_type == TX_ITEM_TYPE_256_OUT) || + (a_type == TX_ITEM_TYPE_OUT_ALL && l_type == TX_ITEM_TYPE_256_OUT_COND) || + (a_type == TX_ITEM_TYPE_OUT_ALL && l_type == TX_ITEM_TYPE_256_OUT_EXT) + ) { if(a_item_idx_start) *a_item_idx_start = l_item_idx; if(a_item_out_size) @@ -416,3 +546,24 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_out_cond_get(dap_chain_datum_tx_t *a } return l_res; } + +// 256 +dap_chain_tx_out_cond_t *dap_chain_datum_256_tx_out_cond_get(dap_chain_datum_tx_t *a_tx, int *a_out_num) +{ + dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, NULL); + int l_prev_cond_idx = l_list_out_items ? 0 : -1; + dap_chain_tx_out_cond_t *l_res = NULL; + for (dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_prev_cond_idx++) { + if (*(uint8_t *)l_list_tmp->data == TX_ITEM_TYPE_256_OUT_COND) { + l_res = l_list_tmp->data; + break; + } + } + dap_list_free(l_list_out_items); + if (a_out_num) { + *a_out_num = l_prev_cond_idx; + } + return l_res; +} + + diff --git a/modules/common/dap_chain_datum_tx_receipt.c b/modules/common/dap_chain_datum_tx_receipt.c index d4428f85e57f2032c1b434fb6e0ffae6fafe14b1..66a4712322fd4b8f769fde168e5bcc57ae2dc96e 100644 --- a/modules/common/dap_chain_datum_tx_receipt.c +++ b/modules/common/dap_chain_datum_tx_receipt.c @@ -60,6 +60,27 @@ dap_chain_datum_tx_receipt_t * dap_chain_datum_tx_receipt_create( dap_chain_net_ return l_ret; } +// 256 +dap_chain_datum_tx_receipt_t * dap_chain_datum_256_tx_receipt_create( dap_chain_net_srv_uid_t a_srv_uid, + dap_chain_net_srv_price_unit_uid_t a_units_type, + uint64_t a_units, uint256_t a_value_datoshi, + const void * a_ext, size_t a_ext_size) +{ + dap_chain_datum_tx_receipt_t * l_ret = DAP_NEW_Z_SIZE(dap_chain_datum_tx_receipt_t, dap_chain_datum_tx_receipt_get_size_hdr() +a_ext_size ); + l_ret->type = TX_ITEM_TYPE_256_RECEIPT; + l_ret->receipt_info.units_type = a_units_type; + l_ret->receipt_info.srv_uid = a_srv_uid; + l_ret->receipt_info.units = a_units; + l_ret->receipt_info.value_datoshi_256 = a_value_datoshi; + l_ret->size = dap_chain_datum_tx_receipt_get_size_hdr()+a_ext_size; + + if( a_ext_size && a_ext){ + l_ret->exts_size = a_ext_size; + memcpy(l_ret->exts_n_signs, a_ext, a_ext_size); + } + return l_ret; +} + size_t dap_chain_datum_tx_receipt_sign_add(dap_chain_datum_tx_receipt_t ** a_receipt, size_t a_receipt_size, dap_enc_key_t *a_key ) { dap_chain_datum_tx_receipt_t *l_receipt = *a_receipt; @@ -83,6 +104,7 @@ size_t dap_chain_datum_tx_receipt_sign_add(dap_chain_datum_tx_receipt_t ** a_rec return a_receipt_size; } + /** * @brief dap_chain_datum_tx_receipt_sign_get * @param l_receipt @@ -106,6 +128,7 @@ dap_sign_t* dap_chain_datum_tx_receipt_sign_get(dap_chain_datum_tx_receipt_t * l return l_sign; } + /** * @brief dap_chain_datum_tx_receipt_signs_count * @param a_receipt diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h index 807079680d020d03bfe04f03c0a750c25e7ef697..35804fe06bbd42bbb584630708e2d2f0bee58bfb 100644 --- a/modules/common/include/dap_chain_common.h +++ b/modules/common/include/dap_chain_common.h @@ -191,15 +191,27 @@ typedef union { typedef enum dap_chain_tx_item_type { TX_ITEM_TYPE_IN = 0x00, /// @brief Transaction: inputs + TX_ITEM_TYPE_OUT = 0x10, /// @brief Transaction: outputs TX_ITEM_TYPE_OUT_EXT = 0x11, + TX_ITEM_TYPE_256_OUT = 0x12, // 256 + TX_ITEM_TYPE_256_OUT_EXT = 0x13, // 256 + TX_ITEM_TYPE_PKEY = 0x20, TX_ITEM_TYPE_SIG = 0x30, TX_ITEM_TYPE_TOKEN = 0x40, TX_ITEM_TYPE_TOKEN_EXT = 0x41, + + TX_ITEM_TYPE_256_TOKEN = 0x42, + TX_ITEM_TYPE_256_TOKEN_EXT = 0x43, + TX_ITEM_TYPE_IN_COND = 0x50, /// @brief Transaction: conditon inputs + TX_ITEM_TYPE_OUT_COND = 0x60, /// @brief Transaction: conditon outputs + TX_ITEM_TYPE_256_OUT_COND = 0x61, // 256 + TX_ITEM_TYPE_RECEIPT = 0x70, + TX_ITEM_TYPE_256_RECEIPT = 0x71, TX_ITEM_TYPE_OUT_ALL = 0xfe, TX_ITEM_TYPE_ANY = 0xff @@ -210,9 +222,19 @@ typedef struct dap_chain_receipt{ dap_chain_net_srv_uid_t srv_uid; // Service UID dap_chain_net_srv_price_unit_uid_t units_type; uint64_t units; // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT - uint64_t value_datoshi; // Receipt value + union { + uint64_t value_datoshi; // Receipt value + uint256_t value_datoshi_256; + }; } dap_chain_receipt_info_t; +// 256 +// typedef struct dap_chain_256_receipt{ +// dap_chain_net_srv_uid_t srv_uid; // Service UID +// dap_chain_net_srv_price_unit_uid_t units_type; +// uint64_t units; // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT +// uint256_t value_datoshi; // Receipt value +// } dap_chain_256_receipt_info_t; #ifdef __cplusplus extern "C" { @@ -243,15 +265,36 @@ DAP_STATIC_INLINE uint64_t dap_chain_coins_to_datoshi(long double a_count) DAP_STATIC_INLINE uint128_t dap_chain_uint128_from(uint64_t a_from) { -#ifdef DAP_GLOBAL_IS_INT128 - return (uint128_t)a_from; -#else - uint128_t l_ret = {{ .0, a_from}}; +// #ifdef DAP_GLOBAL_IS_INT128 +// return (uint128_t)a_from; +// #else +// uint128_t l_ret = {{ .0, a_from}}; +// return l_ret; +// #endif + uint128_t l_ret = uint128_0; + ADD_64_INTO_128(a_from, &l_ret ); return l_ret; -#endif +} + +// 256 +uint128_t dap_chain_uint128_from_uint256(uint256_t a_from); + +// 256 +DAP_STATIC_INLINE uint256_t dap_chain_uint256_from(uint64_t a_from) +{ + uint128_t l_temp_128 = uint128_0; + uint256_t l_ret_256 = uint256_0; + ADD_64_INTO_128(a_from, &l_temp_128); + ADD_128_INTO_256(l_temp_128, &l_ret_256); + return l_ret_256; } uint64_t dap_chain_uint128_to(uint128_t a_from); +// 256 +uint64_t dap_chain_uint256_to(uint256_t a_from); + +char *dap_chain_u256tostr(uint256_t v); + char *dap_chain_balance_print(uint128_t a_balance); char *dap_chain_balance_to_coins(uint128_t a_balance); diff --git a/modules/common/include/dap_chain_datum.h b/modules/common/include/dap_chain_datum.h index e01ac5de87884e3c7a58f5d73f084058537411e3..8723dda037d328b86487321e48b054934919786d 100644 --- a/modules/common/include/dap_chain_datum.h +++ b/modules/common/include/dap_chain_datum.h @@ -38,6 +38,9 @@ /// Transaction header section #define DAP_CHAIN_DATUM_TX 0x0100 +// 256 +#define DAP_CHAIN_DATUM_256_TX 0x0101 + /// Transaction request section #define DAP_CHAIN_DATUM_TX_REQUEST 0x0300 @@ -59,6 +62,7 @@ /// Simple token decl #define DAP_CHAIN_DATUM_TOKEN_DECL 0xf000 #define DAP_CHAIN_DATUM_TOKEN_EMISSION 0xf100 +#define DAP_CHAIN_DATUM_256_TOKEN_EMISSION 0xf101 // 256 #define DAP_CHAIN_DATUM_TOKEN_DISMISSAL 0xf200 #define DAP_CHAIN_DATUM_CUSTOM 0xffff @@ -67,6 +71,8 @@ switch (t) { \ case DAP_CHAIN_DATUM_TX: \ s = "DATUM_TX"; break; \ + case DAP_CHAIN_DATUM_256_TX: \ + s = "DATUM_256_TX"; break; \ case DAP_CHAIN_DATUM_TX_REQUEST: \ s = "DATUM_WASM_CODE"; break; \ case DAP_CHAIN_DATUM_WASM_CODE: \ @@ -85,6 +91,8 @@ s = "DATUM_TOKEN_DECL"; break; \ case DAP_CHAIN_DATUM_TOKEN_EMISSION:\ s = "DATUM_TOKEN_EMISSION"; break;\ + case DAP_CHAIN_DATUM_256_TOKEN_EMISSION:\ + s = "DATUM_256_TOKEN_EMISSION"; break;\ default: \ s = "DATUM_UNKNOWN"; break; \ } diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index 78f1792d2e9acda44dd233f16e52e6c8618b113c..20a75ba505103de2803f510f891aab6254136deb 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -210,11 +210,12 @@ typedef struct dap_chain_datum_token_emission{ struct { uint8_t version; uint8_t type; // Emission Type + bool type_value_256; char ticker[DAP_CHAIN_TICKER_SIZE_MAX]; dap_chain_addr_t address; // Emission holder's address union { uint64_t value; - uint256_t value256; + uint256_t value_256; }; uint8_t nonce[DAP_CHAIN_DATUM_NONCE_SIZE]; } DAP_ALIGN_PACKED hdr; @@ -225,7 +226,10 @@ typedef struct dap_chain_datum_token_emission{ uint64_t lock_time; } DAP_ALIGN_PACKED type_presale; struct { - uint64_t value_start;// Default value. Static if nothing else is defined + union { + uint64_t value_start;// Default value. Static if nothing else is defined + uint256_t value_start_256; + }; char value_change_algo_codename[32]; } DAP_ALIGN_PACKED type_atom_owner; struct { diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h index 54885c4863ecfe326112fc46141c54141ac66043..8c569f03caadd77a89d5a11184bba765af8ac22d 100644 --- a/modules/common/include/dap_chain_datum_tx.h +++ b/modules/common/include/dap_chain_datum_tx.h @@ -81,6 +81,10 @@ int dap_chain_datum_tx_add_item(dap_chain_datum_tx_t **a_tx, const uint8_t *a_it */ uint64_t dap_chain_datum_tx_add_in_item_list(dap_chain_datum_tx_t **a_tx, dap_list_t *a_list_used_out); +// 256 +uint256_t dap_chain_datum_256_tx_add_in_item_list(dap_chain_datum_tx_t **a_tx, dap_list_t *a_list_used_out); + + /** * Create 'in' item and insert to transaction * @@ -106,6 +110,9 @@ int dap_chain_datum_tx_add_in_cond_item(dap_chain_datum_tx_t **a_tx, dap_chain_h */ int dap_chain_datum_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint64_t a_value); +// 256 +int dap_chain_datum_256_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint256_t a_value); + /** * Create 'out'_ext item and insert to transaction * @@ -114,6 +121,10 @@ int dap_chain_datum_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint64_t a_value, const char *a_token); +// 256 +int dap_chain_datum_256_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, + uint256_t a_value, const char *a_token); + /** * Create 'out_cond' item and insert to transaction * @@ -122,6 +133,10 @@ int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_c int dap_chain_datum_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid, uint64_t a_value, uint64_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, const void *a_cond, size_t a_cond_size); +//256 +int dap_chain_datum_256_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid, + uint256_t a_value, uint256_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, const void *a_cond, size_t a_cond_size); + /** * Sign a transaction (Create sign item and insert to transaction) * diff --git a/modules/common/include/dap_chain_datum_tx_in.h b/modules/common/include/dap_chain_datum_tx_in.h index d52c76aac74bbb030412d864e881d6e1ead281b4..aabdc298bbaee6eab61d81d83f380e7a4ee1378b 100644 --- a/modules/common/include/dap_chain_datum_tx_in.h +++ b/modules/common/include/dap_chain_datum_tx_in.h @@ -51,3 +51,12 @@ typedef struct list_used_item { uint64_t value; //dap_chain_tx_out_t *tx_out; } list_used_item_t; + +// 256 +typedef struct list_used_item_256 { + dap_chain_hash_fast_t tx_hash_fast; + uint32_t num_idx_out; + uint8_t padding[4]; + uint256_t value; +//dap_chain_tx_out_t *tx_out; +} list_used_item_256_t; diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h index 3b891bc45ca90e6ad24e0f375563c698a2de70cb..d5425f70b3085f4b5ef00f5f2bf99f8e65ff15ab 100644 --- a/modules/common/include/dap_chain_datum_tx_items.h +++ b/modules/common/include/dap_chain_datum_tx_items.h @@ -53,14 +53,18 @@ DAP_STATIC_INLINE const char * dap_chain_datum_tx_item_type_to_str(dap_chain_tx_ switch(a_item_type){ case TX_ITEM_TYPE_IN: return "TX_ITEM_TYPE_IN"; case TX_ITEM_TYPE_OUT: return "TX_ITEM_TYPE_OUT"; + case TX_ITEM_TYPE_256_OUT: return "TX_ITEM_TYPE_256_OUT"; // 256 case TX_ITEM_TYPE_OUT_EXT: return "TX_ITEM_TYPE_OUT_EXT"; + case TX_ITEM_TYPE_256_OUT_EXT: return "TX_ITEM_TYPE_256_OUT_EXT"; // 256 case TX_ITEM_TYPE_PKEY: return "TX_ITEM_TYPE_PKEY"; case TX_ITEM_TYPE_SIG: return "TX_ITEM_TYPE_SIG"; case TX_ITEM_TYPE_TOKEN: return "TX_ITEM_TYPE_TOKEN"; case TX_ITEM_TYPE_TOKEN_EXT: return "TX_ITEM_TYPE_TOKEN_EXT"; case TX_ITEM_TYPE_IN_COND: return "TX_ITEM_TYPE_IN_COND"; case TX_ITEM_TYPE_OUT_COND: return "TX_ITEM_TYPE_OUT_COND"; + case TX_ITEM_TYPE_256_OUT_COND: return "TX_ITEM_TYPE_256_OUT_COND"; // 256 case TX_ITEM_TYPE_RECEIPT: return "TX_ITEM_TYPE_RECEIPT"; + case TX_ITEM_TYPE_256_RECEIPT: return "TX_ITEM_TYPE_256_RECEIPT"; // 256 case TX_ITEM_TYPE_OUT_ALL: return "TX_ITEM_TYPE_OUT_ALL"; case TX_ITEM_TYPE_ANY: return "TX_ITEM_TYPE_ANY"; default: return "UNDEFINED"; @@ -82,6 +86,9 @@ size_t dap_chain_datum_item_tx_get_size(const uint8_t *a_item); */ dap_chain_tx_token_t* dap_chain_datum_tx_item_token_create(dap_chain_hash_fast_t * a_datum_token_hash,const char * a_ticker); +//256 +dap_chain_tx_token_t* dap_chain_datum_tx_item_256_token_create(dap_chain_hash_fast_t * a_datum_token_hash,const char * a_ticker); + /** * Create item dap_chain_tx_out_t * @@ -99,6 +106,9 @@ dap_chain_tx_in_cond_t* dap_chain_datum_tx_item_in_cond_create(dap_chain_hash_fa */ dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a_addr, uint64_t a_value); +// 256 +dap_chain_tx_out_t* dap_chain_datum_tx_item_256_out_create(const dap_chain_addr_t *a_addr, uint256_t a_value); + /** * Create item dap_chain_tx_out_ext_t * @@ -106,6 +116,9 @@ dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a */ dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_addr_t *a_addr, uint64_t a_value, const char *a_token); +// 256 +dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_256_out_ext_create(const dap_chain_addr_t *a_addr, uint256_t a_value, const char *a_token); + /** * Create item dap_chain_tx_out_cond_t * @@ -114,6 +127,10 @@ dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_a dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_pay(dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid, uint64_t a_value, uint64_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, const void *a_cond, size_t a_cond_size); +// 256 +dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_256_out_cond_create_srv_pay(dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid, + uint256_t a_value, uint256_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, + const void *a_cond, size_t a_cond_size); /** * Create item dap_chain_tx_out_cond_t for eXchange service * @@ -122,6 +139,11 @@ dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_pay(dap_enc dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap_chain_net_srv_uid_t a_srv_uid, dap_chain_net_id_t a_net_id, const char *a_token, uint64_t a_value, const void *a_params, uint32_t a_params_size); +//256 +dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_256_out_cond_create_srv_xchange(dap_chain_net_srv_uid_t a_srv_uid, + dap_chain_net_id_t a_net_id, const char *a_token, uint256_t a_value, + const void *a_params, uint32_t a_params_size); + /** * Create item dap_chain_tx_out_cond_t for stake service @@ -129,8 +151,12 @@ dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap * return item, NULL Error */ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint64_t a_value, long double a_fee_value, - dap_chain_addr_t *a_fee_addr, dap_chain_addr_t *a_hldr_addr, - const void *a_params, uint32_t a_params_size); + dap_chain_addr_t *a_fee_addr, dap_chain_addr_t *a_hldr_addr, + const void *a_params, uint32_t a_params_size); +// 256 +dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_256_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value, long double a_fee_value, + dap_chain_addr_t *a_fee_addr, dap_chain_addr_t *a_hldr_addr, + const void *a_params, uint32_t a_params_size); /** * Create item dap_chain_tx_sig_t * @@ -161,3 +187,4 @@ uint8_t* dap_chain_datum_tx_item_get( dap_chain_datum_tx_t *a_tx, int *a_item_id dap_list_t* dap_chain_datum_tx_items_get(dap_chain_datum_tx_t *a_tx, dap_chain_tx_item_type_t a_type, int *a_item_count); // Get conditional out item with it's idx dap_chain_tx_out_cond_t *dap_chain_datum_tx_out_cond_get(dap_chain_datum_tx_t *a_tx, int *a_out_num); +dap_chain_tx_out_cond_t *dap_chain_datum_256_tx_out_cond_get(dap_chain_datum_tx_t *a_tx, int *a_out_num); diff --git a/modules/common/include/dap_chain_datum_tx_out.h b/modules/common/include/dap_chain_datum_tx_out.h index 24f8240a6fc37aaf163783b7700dc7d71323e00f..37c18c0e5429e298f8404837594f431d65b24652 100644 --- a/modules/common/include/dap_chain_datum_tx_out.h +++ b/modules/common/include/dap_chain_datum_tx_out.h @@ -35,7 +35,11 @@ typedef struct dap_chain_tx_out{ struct { dap_chain_tx_item_type_t type:8; /// @param type @brief Transaction item type - uint64_t value; /// @param value @brief Number of Datoshis ( DAP/10^9 ) to be transfered + union { + uint64_t value; /// @param value @brief Number of Datoshis ( DAP/10^9 ) to be transfered + uint256_t value_256; + }; } header; /// Only header's hash is used for verification dap_chain_addr_t addr; //// } DAP_ALIGN_PACKED dap_chain_tx_out_t; + diff --git a/modules/common/include/dap_chain_datum_tx_out_cond.h b/modules/common/include/dap_chain_datum_tx_out_cond.h index 3d96e7faf7f764e0020f5808048f57303c527630..e90701767a1172caf75fb9fe86e62908519fa099 100644 --- a/modules/common/include/dap_chain_datum_tx_out_cond.h +++ b/modules/common/include/dap_chain_datum_tx_out_cond.h @@ -57,7 +57,10 @@ typedef struct dap_chain_tx_out_cond { /// Condition subtype dap_chain_tx_out_cond_subtype_t subtype : 8; /// Number of Datoshis ( DAP/10^9 ) to be reserver for service - uint64_t value; + union { + uint64_t value; + uint256_t value_256; + }; /// When time expires this output could be used only by transaction owner dap_chain_time_t ts_expires; } header; @@ -71,7 +74,10 @@ typedef struct dap_chain_tx_out_cond { /// Price unit thats used to check price max dap_chain_net_srv_price_unit_uid_t unit; /// Maximum price per unit - uint64_t unit_price_max_datoshi; + union { + uint64_t unit_price_max_datoshi; + uint256_t unit_price_max_datoshi_256; + }; } srv_pay; struct { // Service uid that only could be used for this outout @@ -81,7 +87,10 @@ typedef struct dap_chain_tx_out_cond { // Chain network to change to dap_chain_net_id_t net_id; // Total amount of datoshi to change to - uint64_t value; + union { + uint64_t value; + uint256_t value_256; + }; } srv_xchange; struct { // Service uid that only could be used for this outout diff --git a/modules/common/include/dap_chain_datum_tx_out_ext.h b/modules/common/include/dap_chain_datum_tx_out_ext.h index 536012bbd6226418cf05fd7dce55aa98dc19564d..400a61f68f9285df84f449c2c592ff80dd769de9 100644 --- a/modules/common/include/dap_chain_datum_tx_out_ext.h +++ b/modules/common/include/dap_chain_datum_tx_out_ext.h @@ -36,7 +36,10 @@ typedef struct dap_chain_tx_out_ext{ struct { dap_chain_tx_item_type_t type : 8; // Transaction item type - should be TX_ITEM_TYPE_OUT_EXT - uint64_t value; // Number of Datoshis ( DAP/10^9 ) to be transfered + union { + uint64_t value; // Number of Datoshis ( DAP/10^9 ) to be transfered + uint256_t value_256; + }; } header; // Only header's hash is used for verification dap_chain_addr_t addr; // Address to transfer to char token[DAP_CHAIN_TICKER_SIZE_MAX]; // Which token is transferred diff --git a/modules/common/include/dap_chain_datum_tx_receipt.h b/modules/common/include/dap_chain_datum_tx_receipt.h index f873a4d92761974639e2c6e8e9e81ce468f51258..b27f0ce374e6b560d0a8255a245fcc2f389c782f 100644 --- a/modules/common/include/dap_chain_datum_tx_receipt.h +++ b/modules/common/include/dap_chain_datum_tx_receipt.h @@ -39,7 +39,6 @@ typedef struct dap_chain_datum_tx_receipt { byte_t exts_n_signs[]; // Signatures, first from provider, second from client }DAP_ALIGN_PACKED dap_chain_datum_tx_receipt_t; - #ifdef __cplusplus extern "C" { #endif @@ -49,9 +48,18 @@ static inline size_t dap_chain_datum_tx_receipt_get_size_hdr(){ return 1+sizeof dap_chain_datum_tx_receipt_t * dap_chain_datum_tx_receipt_create( dap_chain_net_srv_uid_t srv_uid, dap_chain_net_srv_price_unit_uid_t units_type, uint64_t units, uint64_t value_datoshi, const void * a_ext, size_t a_ext_size); + +// 256 +dap_chain_datum_tx_receipt_t * dap_chain_datum_256_tx_receipt_create( dap_chain_net_srv_uid_t srv_uid, + dap_chain_net_srv_price_unit_uid_t units_type, + uint64_t units, uint256_t value_datoshi, const void * a_ext, size_t a_ext_size); + size_t dap_chain_datum_tx_receipt_sign_add(dap_chain_datum_tx_receipt_t ** a_receipt, size_t a_receipt_size, dap_enc_key_t *a_key ); + dap_sign_t* dap_chain_datum_tx_receipt_sign_get(dap_chain_datum_tx_receipt_t * l_receipt, size_t l_receipt_size , uint16_t sign_position); + uint16_t dap_chain_datum_tx_receipt_signs_count(dap_chain_datum_tx_receipt_t * l_receipt, size_t l_receipt_size); + static inline uint16_t dap_chain_datum_tx_receipt_get_size(const dap_chain_datum_tx_receipt_t * l_receipt) { return l_receipt->size; diff --git a/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c b/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c index 367d76b0e52d8c07af9b1d5c4b33fe2c5b9f5e04..5a98adfca649e6f5c3350516aebe572741f40bcb 100644 --- a/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c +++ b/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c @@ -268,6 +268,40 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_ return -6; } } + /* + dap_chain_datum_t *l_datum = dap_chain_cs_dag_event_get_datum(a_dag_event); + // transaction include emission? + bool l_is_emit = false; + if(l_datum && l_datum->header.type_id == DAP_CHAIN_DATUM_TX) { + // transaction + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; + // find Token items + dap_list_t *l_list_tx_token = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN, NULL); + if(l_list_tx_token) + l_is_emit = true; + dap_list_free(l_list_tx_token); + } + // if emission then the wallet can be with zero balance + if(l_is_emit) + return 0;*/ + + // bool l_is_enough_balance = false; + // for (size_t i =0; i <l_pos_pvt->tokens_hold_size; i++){ + // uint256_t l_balance = dap_chain_ledger_calc_balance ( a_dag->chain->ledger , &l_addr, l_pos_pvt->tokens_hold[i] ); + // uint64_t l_value = dap_chain_uint256_to(l_balance); + // if (l_value >= l_pos_pvt->tokens_hold_value[i]) { + // l_verified_num++; + // l_is_enough_balance = true; + // break; + // } + // } + // if (! l_is_enough_balance ){ + // char *l_addr_str = dap_chain_addr_to_str(&l_addr); + // log_it(L_WARNING, "Verify of event is false, because bal is not enough for addr=%s", l_addr_str); + // DAP_DELETE(l_addr_str); + // return -1; + //} + } // Check number if ( l_verified_num >= l_pos_pvt->confirmations_minimum ){ diff --git a/modules/consensus/none/dap_chain_cs_none.c b/modules/consensus/none/dap_chain_cs_none.c index 233377e230b7fd7c4809bfb420d71fbcec8e6d21..99cec6bd6247bb0d9ebd2ff4536bb9d53140d086 100644 --- a/modules/consensus/none/dap_chain_cs_none.c +++ b/modules/consensus/none/dap_chain_cs_none.c @@ -321,10 +321,15 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha if (dap_chain_ledger_token_load(a_chain->ledger,l_token, l_datum->header.data_size)) return ATOM_REJECT; }break; + case DAP_CHAIN_DATUM_256_TOKEN_EMISSION: // 256 case DAP_CHAIN_DATUM_TOKEN_EMISSION: { - if (dap_chain_ledger_token_emission_load(a_chain->ledger, l_datum->data, l_datum->header.data_size)) + dap_chain_datum_token_emission_t *l_token_em = (dap_chain_datum_token_emission_t*) l_datum->data; + l_token_em->hdr.type_value_256 = l_datum->header.type_id == DAP_CHAIN_DATUM_256_TOKEN_EMISSION ? + true : false; + if (dap_chain_ledger_token_emission_load(a_chain->ledger, l_token_em, l_datum->header.data_size)) return ATOM_REJECT; }break; + case DAP_CHAIN_DATUM_256_TX: // 256 case DAP_CHAIN_DATUM_TX:{ dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; // No trashhold herr, don't save bad transactions to base diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index ef56ed93cc3fbcf6ba5dd6f425ae030d0525ab9c..011e0dbfa8b88fdda35379941fae1852ab8356e7 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -2541,12 +2541,22 @@ int dap_chain_net_verify_datum_for_add(dap_chain_net_t *a_net, dap_chain_datum_t return -11; switch ( a_datum->header.type_id) { - case DAP_CHAIN_DATUM_TX: return dap_chain_ledger_tx_add_check( a_net->pub.ledger, - (dap_chain_datum_tx_t*) a_datum->data ); - case DAP_CHAIN_DATUM_TOKEN_DECL: return dap_chain_ledger_token_decl_add_check( a_net->pub.ledger, - (dap_chain_datum_token_t*) a_datum->data ); - case DAP_CHAIN_DATUM_TOKEN_EMISSION : return dap_chain_ledger_token_emission_add_check( a_net->pub.ledger, - a_datum->data, a_datum->header.data_size ); + case DAP_CHAIN_DATUM_256_TX: // 256 + case DAP_CHAIN_DATUM_TX: + return dap_chain_ledger_tx_add_check( a_net->pub.ledger, + (dap_chain_datum_tx_t*) a_datum->data ); + + case DAP_CHAIN_DATUM_TOKEN_DECL: + return dap_chain_ledger_token_decl_add_check( a_net->pub.ledger, + (dap_chain_datum_token_t*) a_datum->data ); + + case DAP_CHAIN_DATUM_256_TOKEN_EMISSION: // 256 + case DAP_CHAIN_DATUM_TOKEN_EMISSION: { + dap_chain_datum_token_emission_t *l_token_em = (dap_chain_datum_token_emission_t*) a_datum->data; + l_token_em->hdr.type_value_256 = a_datum->header.type_id == DAP_CHAIN_DATUM_256_TOKEN_EMISSION ? + true : false; + return dap_chain_ledger_token_emission_add_check( a_net->pub.ledger, l_token_em, a_datum->header.data_size ); + } default: return 0; } } @@ -2782,16 +2792,24 @@ void dap_chain_net_dump_datum(dap_string_t * a_str_out, dap_chain_datum_t * a_da dap_hash_fast_to_str(&l_in->header.tx_prev_hash, l_tx_prev_hash_str, sizeof (l_tx_prev_hash_str)-1); dap_string_append_printf(a_str_out,"\ttx_prev_hash : %s\n", l_tx_prev_hash_str ); } break; + case TX_ITEM_TYPE_256_OUT: // 256 case TX_ITEM_TYPE_OUT:{ dap_chain_tx_out_t * l_out = l_cur->data; - dap_string_append_printf(a_str_out,"\tvalue: %"DAP_UINT64_FORMAT_U"\n", l_out->header.value ); + if ( l_item_type == TX_ITEM_TYPE_256_OUT ) // u256_t value + dap_string_append_printf(a_str_out,"\tvalue: %s\n", dap_chain_u256tostr(l_out->header.value_256) ); + else // u64_t value + dap_string_append_printf(a_str_out,"\tvalue: %"DAP_UINT64_FORMAT_U"\n", l_out->header.value ); char * l_addr_str = dap_chain_addr_to_str(&l_out->addr); dap_string_append_printf(a_str_out,"\taddr : %s\n", l_addr_str ); DAP_DELETE(l_addr_str); } break; + case TX_ITEM_TYPE_256_OUT_EXT: // 256 case TX_ITEM_TYPE_OUT_EXT:{ dap_chain_tx_out_ext_t * l_out_ext = l_cur->data; - dap_string_append_printf(a_str_out,"\tvalue: %"DAP_UINT64_FORMAT_U"\n", l_out_ext->header.value ); + if ( l_item_type == TX_ITEM_TYPE_256_OUT_EXT ) // u256_t value + dap_string_append_printf(a_str_out,"\tvalue: %s\n", dap_chain_u256tostr(l_out_ext->header.value_256) ); + else + dap_string_append_printf(a_str_out,"\tvalue: %"DAP_UINT64_FORMAT_U"\n", l_out_ext->header.value ); char * l_addr_str = dap_chain_addr_to_str(&l_out_ext->addr); dap_string_append_printf(a_str_out,"\taddr : %s\n", l_addr_str ); dap_string_append_printf(a_str_out,"\ttoken : %s\n", l_out_ext->token ); @@ -2808,6 +2826,7 @@ void dap_chain_net_dump_datum(dap_string_t * a_str_out, dap_chain_datum_t * a_da dap_hash_fast_to_str(&l_sign_hash,l_sign_hash_str,sizeof (l_sign_hash_str)-1); dap_string_append_printf(a_str_out,"\tpkey_hash: %s\n", l_sign_hash_str ); } break; + case TX_ITEM_TYPE_256_TOKEN: // 256 case TX_ITEM_TYPE_TOKEN:{ dap_chain_tx_token_t * l_token = l_cur->data; dap_string_append_printf(a_str_out,"\tticker: %s\n", l_token->header.ticker ); @@ -2817,6 +2836,7 @@ void dap_chain_net_dump_datum(dap_string_t * a_str_out, dap_chain_datum_t * a_da sizeof (l_token_emission_hash_str)-1); dap_string_append_printf(a_str_out,"\ttoken_emission_hash: %s", l_token_emission_hash_str ); } break; + case TX_ITEM_TYPE_256_TOKEN_EXT: // 256 case TX_ITEM_TYPE_TOKEN_EXT:{ dap_chain_tx_token_ext_t * l_token = l_cur->data; dap_string_append_printf(a_str_out,"\tversion: %u\n",l_token->header.version ); @@ -2837,9 +2857,13 @@ void dap_chain_net_dump_datum(dap_string_t * a_str_out, dap_chain_datum_t * a_da dap_hash_fast_to_str(&l_in->header.tx_prev_hash, l_tx_prev_hash_str,sizeof (l_tx_prev_hash_str)-1); dap_string_append_printf(a_str_out,"\ttx_prev_hash : %s\n", l_tx_prev_hash_str ); } break; + case TX_ITEM_TYPE_256_OUT_COND: // 256 case TX_ITEM_TYPE_OUT_COND:{ dap_chain_tx_out_cond_t * l_out = l_cur->data; - dap_string_append_printf(a_str_out,"\tvalue: %"DAP_UINT64_FORMAT_U"\n", l_out->header.value ); + if ( l_item_type == TX_ITEM_TYPE_256_OUT_COND ) // u256_t value + dap_string_append_printf(a_str_out,"\tvalue: %s\n", dap_chain_u256tostr(l_out->header.value_256) ); + else + dap_string_append_printf(a_str_out,"\tvalue: %"DAP_UINT64_FORMAT_U"\n", l_out->header.value ); switch ( l_out->header.subtype){ case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY:{ dap_string_append_printf(a_str_out,"\tsubtype: DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY\n"); @@ -2853,7 +2877,11 @@ void dap_chain_net_dump_datum(dap_string_t * a_str_out, dap_chain_datum_t * a_da case SERV_UNIT_B : dap_string_append_printf(a_str_out,"\tunit: SERV_UNIT_B\n"); break; default: dap_string_append_printf(a_str_out,"\tunit: SERV_UNIT_UNKNOWN\n"); break; } - dap_string_append_printf(a_str_out,"\tunit_price_max: %"DAP_UINT64_FORMAT_U"\n", l_out->subtype.srv_pay.unit_price_max_datoshi); + if ( l_item_type == TX_ITEM_TYPE_256_OUT_COND ) // u256_t value + dap_string_append_printf(a_str_out,"\tunit_price_max: %s\n", dap_chain_u256tostr(l_out->subtype.srv_pay.unit_price_max_datoshi_256)); + else + dap_string_append_printf(a_str_out,"\tunit_price_max: %"DAP_UINT64_FORMAT_U"\n", l_out->subtype.srv_pay.unit_price_max_datoshi); + char l_pkey_hash_str[70]={[0]='\0'}; dap_chain_hash_fast_to_str(&l_out->subtype.srv_pay.pkey_hash, l_pkey_hash_str, sizeof (l_pkey_hash_str)-1); dap_string_append_printf(a_str_out,"\tpkey_hash: %s\n", l_pkey_hash_str ); diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 18a5f26afc890236658fe13261e230404aacec45..0ca0fb95cd7a2d6169450e685a9932fcd1ca8669 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -1800,9 +1800,10 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply) dap_string_append_printf(l_string_ret, "balance: 0"); for(size_t i = 0; i < l_addr_tokens_size; i++) { if(l_addr_tokens[i]) { - uint128_t l_balance = dap_chain_ledger_calc_balance(l_ledger, l_addr, l_addr_tokens[i]); - char *l_balance_coins = dap_chain_balance_to_coins(l_balance); - char *l_balance_datoshi = dap_chain_balance_print(l_balance); + // uint128_t l_balance = dap_chain_ledger_calc_balance(l_ledger, l_addr, l_addr_tokens[i]); + uint256_t l_balance = dap_chain_ledger_calc_balance(l_ledger, l_addr, l_addr_tokens[i]); + char *l_balance_coins = dap_chain_balance_to_coins(dap_chain_uint128_from_uint256(l_balance)); + char *l_balance_datoshi = dap_chain_balance_print(dap_chain_uint128_from_uint256(l_balance)); dap_string_append_printf(l_string_ret, "\t%s (%s) %s\n", l_balance_coins, l_balance_datoshi, l_addr_tokens[i]); if(i < l_addr_tokens_size - 1) @@ -3136,16 +3137,23 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) int arg_index = 1; const char *str_tmp = NULL; char *str_reply_tmp = NULL; - uint64_t l_emission_value = 0; + // uint64_t l_emission_value = 0; + uint256_t l_emission_value = uint256_0; + const char * l_ticker = NULL; const char * l_addr_str = NULL; const char * l_emission_hash_str = NULL; + const char * l_type_256 = NULL; + char * l_emission_hash_str_new = NULL; dap_chain_hash_fast_t l_emission_hash={0}; + dap_chain_datum_token_emission_t * l_emission = NULL; + //dap_chain_datum_256_token_emission_t * l_emission_256 = NULL; // 256 + char * l_emission_hash_str_base58 = NULL; const char * l_certs_str = NULL; @@ -3165,6 +3173,7 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); if(!l_hash_out_type) l_hash_out_type = "hex"; + if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) { dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>"); return -1; @@ -3180,6 +3189,9 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) // Token emission dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-emission", &l_emission_hash_str); + // 256 + dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-256", &l_type_256); + // Emission certs dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-certs", &l_certs_str); @@ -3191,10 +3203,11 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) // Emission value if(dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-emission_value", &str_tmp)) { - l_emission_value = strtoull(str_tmp, NULL, 10); + // l_emission_value = strtoull(str_tmp, NULL, 10); + l_emission_value = GET_256_FROM_128(dap_strtou128(str_tmp, NULL, 10)); } - if(!l_emission_value) { + if( EQUAL_256(l_emission_value, uint256_0) ) { dap_chain_node_cli_set_reply_text(a_str_reply, "token_emit requires parameter '-emission_value'"); return -1; } @@ -3214,7 +3227,6 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) return -4; } - if (l_emission_hash_str){// Load emission l_emission_hash_str_base58 = dap_enc_base58_encode_hash_to_str(&l_emission_hash); if (dap_chain_hash_fast_from_str( l_emission_hash_str,&l_emission_hash) == 0 ){ @@ -3247,8 +3259,6 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) } } - - dap_chain_addr_t * l_addr = dap_chain_addr_from_str(l_addr_str); if(!l_addr) { @@ -3292,16 +3302,30 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) size_t l_emission_size = sizeof(l_emission->hdr) + sizeof(l_emission->data.type_auth.signs_count); + // size_t l_emission_256_size = sizeof(l_emission_256->hdr) + + // sizeof(l_emission_256->data.type_auth.signs_count); + l_emission = DAP_NEW_Z_SIZE(dap_chain_datum_token_emission_t, l_emission_size); + + if ( !l_type_256 ) { + l_emission->hdr.type_value_256 = false; + l_emission->hdr.value = dap_chain_uint256_to(l_emission_value); + } else { // 256 + l_emission->hdr.type_value_256 = true; + l_emission->hdr.value_256 = l_emission_value; + } + l_emission->hdr.version = 1; + strncpy(l_emission->hdr.ticker, l_ticker, sizeof(l_emission->hdr.ticker) - 1); - l_emission->hdr.value = l_emission_value; l_emission->hdr.type = DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH; memcpy(&l_emission->hdr.address, l_addr, sizeof(l_emission->hdr.address)); + time_t l_time = time(NULL); memcpy(&l_emission->hdr.nonce, &l_time, sizeof(time_t)); // Then add signs size_t l_offset = 0; + for(size_t i = 0; i < l_certs_size; i++) { dap_sign_t * l_sign = dap_cert_sign(l_certs[i], &l_emission->hdr, sizeof(l_emission->hdr), 0); @@ -3313,20 +3337,31 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) DAP_DELETE(l_sign); } + dap_chain_datum_t * l_datum_emission; + // Produce datum - dap_chain_datum_t * l_datum_emission = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN_EMISSION, - l_emission, - l_emission_size); + if ( !l_type_256 ) + l_datum_emission = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN_EMISSION, + l_emission, + l_emission_size); + else // 256 + l_datum_emission = dap_chain_datum_create(DAP_CHAIN_DATUM_256_TOKEN_EMISSION, + l_emission, + l_emission_size); + size_t l_datum_emission_size = sizeof(l_datum_emission->header) + l_datum_emission->header.data_size; // Calc token's hash //dap_chain_hash_fast_t l_emission_hash; dap_hash_fast(l_emission, l_emission_size, &l_emission_hash); + l_emission_hash_str = l_emission_hash_str_new = dap_chain_hash_fast_to_str_new(&l_emission_hash); l_emission_hash_str_base58 = dap_enc_base58_encode_hash_to_str(&l_emission_hash); // Delete token emission DAP_DEL_Z(l_emission); + //DAP_DEL_Z(l_emission_256); // 256 + // // Calc datum's hash // dap_chain_hash_fast_t l_datum_emission_hash; // dap_hash_fast(l_datum_emission, l_datum_emission_size, (uint8_t*) &l_datum_emission_hash); @@ -3358,15 +3393,29 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) // create first transaction (with tx_token) dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); dap_chain_hash_fast_t l_tx_prev_hash = { 0 }; + dap_chain_tx_token_t *l_tx_token; + dap_chain_tx_out_t *l_out; + //dap_chain_256_tx_out_t *l_out_256; + // create items - dap_chain_tx_token_t *l_tx_token = dap_chain_datum_tx_item_token_create(&l_emission_hash, l_ticker); + if ( !l_type_256 ) { + l_tx_token = dap_chain_datum_tx_item_token_create(&l_emission_hash, l_ticker); + l_out = dap_chain_datum_tx_item_out_create(l_addr, dap_chain_uint256_to(l_emission_value)); + } else { // 256 + l_tx_token = dap_chain_datum_tx_item_256_token_create(&l_emission_hash, l_ticker); + l_out = dap_chain_datum_tx_item_256_out_create(l_addr, l_emission_value); + } dap_chain_tx_in_t *l_in = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, 0); - dap_chain_tx_out_t *l_out = dap_chain_datum_tx_item_out_create(l_addr, l_emission_value); // pack items to transaction dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_tx_token); dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_in); + + //if ( !l_type_256 ) { dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_out); + // } else { //256 + // dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_out_256); + // } // Base tx don't need signature items but let it be if (l_certs){ @@ -3386,16 +3435,22 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) DAP_DEL_Z(l_tx_token); DAP_DEL_Z(l_in); - DAP_DEL_Z(l_out); + // DAP_DEL_Z(l_out); + // DAP_DEL_Z(l_out_256); DAP_DEL_Z(l_emission_hash_str_new); l_emission_hash_str = NULL; DAP_DEL_Z(l_emission_hash_str_base58); size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); + dap_chain_datum_t * l_datum_tx; // Pack transaction into the datum - dap_chain_datum_t * l_datum_tx = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size); + if ( !l_type_256 ) { + l_datum_tx = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size); + } else { + l_datum_tx = dap_chain_datum_create(DAP_CHAIN_DATUM_256_TX, l_tx, l_tx_size); + } size_t l_datum_tx_size = dap_chain_datum_size(l_datum_tx); // use l_tx hash for compatible with utho hash @@ -3829,6 +3884,10 @@ int com_tx_create(int argc, char ** argv, char **str_reply) uint64_t value = 0; uint64_t value_fee = 0; + + // uint256_t value = uint256_0; + // uint256_t value_fee = uint256_0; + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-from_wallet", &l_from_wallet_name); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-to_addr", &addr_base58_to); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-token", &l_token_ticker); diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 6fb5949d8145b3539ccf262ccea35654d832c591..bd40a3fb9e47e53fe5074d5a2a7893020a48bd79 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -116,7 +116,10 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, l_tx_hash_user_str = dap_strdup(l_tx_hash_str); else l_tx_hash_user_str = dap_enc_base58_from_hex_str_to_str(l_tx_hash_str); - dap_list_t *l_list_tx_any = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_TOKEN, NULL); + dap_list_t *l_list_tx_any = dap_list_concat( + dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_256_TOKEN, NULL), + dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_TOKEN, NULL) + ); if(a_ledger == NULL){ dap_string_append_printf(a_str_out, "transaction: %s hash: %s\n Items:\n", l_list_tx_any ? "(emit)" : "", l_tx_hash_user_str); } else { @@ -137,7 +140,9 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, while(l_tx_items_count < l_tx_items_size){ uint8_t *item = a_datum->tx_items + l_tx_items_count; size_t l_item_tx_size = dap_chain_datum_item_tx_get_size(item); - switch(dap_chain_datum_tx_item_get_type(item)){ + + dap_chain_tx_item_type_t l_type = dap_chain_datum_tx_item_get_type(item); + switch(l_type){ case TX_ITEM_TYPE_IN: l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_in_t*)item)->header.tx_prev_hash); dap_string_append_printf(a_str_out, "\t IN:\nTx_prev_hash: %s\n" @@ -156,15 +161,32 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, ((dap_chain_tx_out_t*)item)->header.value, dap_chain_addr_to_str(&((dap_chain_tx_out_t*)item)->addr)); break; + case TX_ITEM_TYPE_256_OUT: { // 256 + dap_string_append_printf(a_str_out, "\t OUT 256_t:\n" + "\t\t Value: %s (%s)\n" + "\t\t Address: %s\n", + dap_chain_balance_to_coins(dap_chain_uint128_from_uint256( + ((dap_chain_tx_out_t*)item)->header.value_256) + ), + dap_chain_u256tostr(((dap_chain_tx_out_t*)item)->header.value_256), + dap_chain_addr_to_str(&((dap_chain_tx_out_t*)item)->addr)); + break; + } + case TX_ITEM_TYPE_256_TOKEN: case TX_ITEM_TYPE_TOKEN: l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_token_t*)item)->header.token_emission_hash); - dap_string_append_printf(a_str_out, "\t TOKEN:\n" + dap_string_append_printf(a_str_out, "\t TOKEN%s:\n" "\t\t ticker: %s \n" "\t\t token_emission_hash: %s\n" - "\t\t token_emission_chain_id: 0x%016"DAP_UINT64_FORMAT_x"\n", ((dap_chain_tx_token_t*)item)->header.ticker, l_hash_str_tmp, - ((dap_chain_tx_token_t*)item)->header.token_emission_chain_id.uint64); + "\t\t token_emission_chain_id: 0x%016"DAP_UINT64_FORMAT_x"\n", + TX_ITEM_TYPE_256_TOKEN == l_type ? " 256_t " : "", + ((dap_chain_tx_token_t*)item)->header.ticker, + l_hash_str_tmp, + ((dap_chain_tx_token_t*)item)->header.token_emission_chain_id.uint64 + ); DAP_DELETE(l_hash_str_tmp); break; + case TX_ITEM_TYPE_256_TOKEN_EXT: case TX_ITEM_TYPE_TOKEN_EXT: l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_token_ext_t*)item)->header.ext_tx_hash); dap_string_append_printf(a_str_out, "\t TOKEN EXT:\n" @@ -188,28 +210,55 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, "\t sig_size: %u\n", ((dap_chain_tx_sig_t*)item)->header.sig_size); dap_sign_get_information(l_sign_tmp, a_str_out); break; + case TX_ITEM_TYPE_256_RECEIPT: case TX_ITEM_TYPE_RECEIPT: - dap_string_append_printf(a_str_out, "\t Receipt:\n" - "\t\t size: %u\n" - "\t\t ext size:%u\n" - "\t\t Info:" - "\t\t\t units: 0x%016"DAP_UINT64_FORMAT_x"\n" - "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" - "\t\t\t units type: %s \n" - "\t\t\t value: %s (%"DAP_UINT64_FORMAT_U")\n", - ((dap_chain_datum_tx_receipt_t*)item)->size, - ((dap_chain_datum_tx_receipt_t*)item)->exts_size, - ((dap_chain_datum_tx_receipt_t*)item)->receipt_info.units, - ((dap_chain_datum_tx_receipt_t*)item)->receipt_info.srv_uid.uint64, - serv_unit_enum_to_str( - &((dap_chain_datum_tx_receipt_t*)item)->receipt_info.units_type.enm - ), - dap_chain_balance_to_coins( - dap_chain_uint128_from( - ((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi - ) - ), - ((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi); + if ( l_type == TX_ITEM_TYPE_256_RECEIPT) // u256_t value_datoshi + dap_string_append_printf(a_str_out, "\t Receipt:\n" + "\t\t size: %u\n" + "\t\t ext size:%u\n" + "\t\t Info:" + "\t\t\t units: 0x%016"DAP_UINT64_FORMAT_x"\n" + "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" + "\t\t\t units type: %s \n" + "\t\t\t value: %s (%"DAP_UINT64_FORMAT_U")\n", + ((dap_chain_datum_tx_receipt_t*)item)->size, + ((dap_chain_datum_tx_receipt_t*)item)->exts_size, + ((dap_chain_datum_tx_receipt_t*)item)->receipt_info.units, + ((dap_chain_datum_tx_receipt_t*)item)->receipt_info.srv_uid.uint64, + serv_unit_enum_to_str( + &((dap_chain_datum_tx_receipt_t*)item)->receipt_info.units_type.enm + ), + dap_chain_balance_to_coins( + dap_chain_uint128_from_uint256( + ((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi_256 + ) + ), + dap_chain_u256tostr(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi_256) + ); + else // u64_t value_datoshi + dap_string_append_printf(a_str_out, "\t Receipt:\n" + "\t\t size: %u\n" + "\t\t ext size:%u\n" + "\t\t Info:" + "\t\t\t units: 0x%016"DAP_UINT64_FORMAT_x"\n" + "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" + "\t\t\t units type: %s \n" + "\t\t\t value: %s (%"DAP_UINT64_FORMAT_U")\n", + ((dap_chain_datum_tx_receipt_t*)item)->size, + ((dap_chain_datum_tx_receipt_t*)item)->exts_size, + ((dap_chain_datum_tx_receipt_t*)item)->receipt_info.units, + ((dap_chain_datum_tx_receipt_t*)item)->receipt_info.srv_uid.uint64, + serv_unit_enum_to_str( + &((dap_chain_datum_tx_receipt_t*)item)->receipt_info.units_type.enm + ), + dap_chain_balance_to_coins( + dap_chain_uint128_from( + ((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi + ) + ), + ((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi + ); + if (((dap_chain_datum_tx_receipt_t*)item)->exts_size == sizeof(dap_sign_t) + sizeof(dap_sign_t)){ dap_sign_t *l_provider = DAP_NEW_Z(dap_sign_t); memcpy(l_provider, ((dap_chain_datum_tx_receipt_t*)item)->exts_n_signs, sizeof(dap_sign_t)); @@ -317,6 +366,66 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, default: break; } break; + case TX_ITEM_TYPE_256_OUT_COND: // 256 + dap_string_append_printf(a_str_out, "\t OUT 256_t COND:\n" + "\t Header:\n" + "\t\t\t ts_expires: %s\t" + "\t\t\t value: %s (%s)\n" + "\t\t\t subtype: %s\n" + "\t\t SubType:\n", + dap_ctime_r((time_t*)((dap_chain_tx_out_cond_t*)item)->header.ts_expires, l_tmp_buf), + dap_chain_balance_to_coins( + dap_chain_uint128_from_uint256(((dap_chain_tx_out_cond_t*)item)->header.value_256) + ), + dap_chain_u256tostr(((dap_chain_tx_out_cond_t*)item)->header.value_256), + dap_chain_tx_out_cond_subtype_to_str(((dap_chain_tx_out_cond_t*)item)->header.subtype) + ); + switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) { + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: + l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash); + dap_string_append_printf(a_str_out, "\t\t\t unit: 0x%08x\n" + "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" + "\t\t\t pkey: %s\n" + "\t\t\t max price: %s (%s) \n", + ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit.uint32, + ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.srv_uid.uint64, + l_hash_str_tmp, + dap_chain_balance_to_coins(dap_chain_uint128_from_uint256( + ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi_256) + ), + dap_chain_u256tostr(((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi_256) + ); + DAP_FREE(l_hash_str_tmp); + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE: + dap_string_append_printf(a_str_out, "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" + "\t\t\t addr: %s\n" + "\t\t\t value: %Lf", + ((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake.srv_uid.uint64, + dap_chain_addr_to_str( + &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake.fee_addr + ), + ((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake.fee_value + ); + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: + dap_string_append_printf(a_str_out, "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" + "\t\t\t net id: 0x%016"DAP_UINT64_FORMAT_x"\n" + "\t\t\t token: %s\n" + "\t\t\t value: %s (%s)\n", + ((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.srv_uid.uint64, + ((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.net_id.uint64, + ((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.token, + dap_chain_balance_to_coins( + dap_chain_uint128_from_uint256( + ((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.value_256 + ) + ), + dap_chain_u256tostr(((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.value_256) + ); + break; + } + break; case TX_ITEM_TYPE_OUT_EXT: dap_string_append_printf(a_str_out, "\t OUT EXT:\n" "\t\t Addr: %s\n" @@ -327,7 +436,21 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, dap_chain_balance_to_coins(dap_chain_uint128_from( ((dap_chain_tx_out_ext_t*)item)->header.value) ), - ((dap_chain_tx_out_ext_t*)item)->header.value); + ((dap_chain_tx_out_ext_t*)item)->header.value + ); + break; + case TX_ITEM_TYPE_256_OUT_EXT: // 256 + dap_string_append_printf(a_str_out, "\t OUT 256_t EXT:\n" + "\t\t Addr: %s\n" + "\t\t Token: %s\n" + "\t\t Value: %s (%s)\n", + dap_chain_addr_to_str(&((dap_chain_tx_out_ext_t*)item)->addr), + ((dap_chain_tx_out_ext_t*)item)->token, + dap_chain_balance_to_coins(dap_chain_uint128_from_uint256( + ((dap_chain_tx_out_ext_t*)item)->header.value_256) + ), + dap_chain_u256tostr(((dap_chain_tx_out_ext_t*)item)->header.value_256) + ); break; default: dap_string_append_printf(a_str_out, " This transaction have unknown item type \n"); @@ -392,24 +515,46 @@ char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain, while(l_atom && l_atom_size) { dap_chain_datum_t *l_datum = (dap_chain_datum_t*) l_atom; - if(!l_datum && l_datum->header.type_id != DAP_CHAIN_DATUM_TX) { + if(!l_datum && (l_datum->header.type_id != DAP_CHAIN_DATUM_TX && l_datum->header.type_id != DAP_CHAIN_DATUM_256_TX ) ) { // go to next transaction l_atom = a_chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size); continue; } + + bool l_type_256 = false; + + if ( l_datum->header.type_id == DAP_CHAIN_DATUM_256_TX ) + l_type_256 = true; + dap_tx_data_t *l_tx_data = NULL; // transaction dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; // find Token items - present in emit transaction - dap_list_t *l_list_tx_token = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN, NULL); + // dap_list_t *l_list_tx_token = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN, NULL); + + dap_list_t *l_list_tx_token; + if ( l_type_256 ) // 256 + l_list_tx_token = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_256_TOKEN, NULL); + else + l_list_tx_token = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN, NULL); // find OUT items - dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL); + // dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL); + + dap_list_t *l_list_out_items; + if ( l_type_256 ) // 256 + l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_256_OUT, NULL); + else + l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL); + dap_list_t *l_list_tmp = l_list_out_items; while(l_list_tmp) { + + // const dap_chain_256_tx_out_t *l_tx_out_256 = (const dap_chain_256_tx_out_t*) l_list_tmp->data; const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data; + // save OUT item l_tx_out - only for first OUT item if(!l_tx_data) { @@ -418,7 +563,11 @@ char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain, dap_chain_hash_fast_t l_tx_hash; dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); memcpy(&l_tx_data->tx_hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t)); + // if ( l_type_256 ) // 256 + // memcpy(&l_tx_data->addr, &l_tx_out->addr, sizeof(dap_chain_addr_t)); + // else memcpy(&l_tx_data->addr, &l_tx_out->addr, sizeof(dap_chain_addr_t)); + dap_chain_hash_fast_to_str(&l_tx_data->tx_hash, l_tx_data->tx_hash_str, sizeof(l_tx_data->tx_hash_str)); //l_tx_data->pos_num = l_count; @@ -487,9 +636,13 @@ char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain, } // find all OUT items in transaction - l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL); + if ( l_type_256 ) + l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_256_OUT, NULL); + else + l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL); l_list_tmp = l_list_out_items; while(l_list_tmp) { + // const dap_chain_256_tx_out_t *l_tx_out_256 = (const dap_chain_256_tx_out_t*) l_list_tmp->data; const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data; //dap_tx_data_t *l_tx_data_prev = NULL; @@ -497,14 +650,22 @@ char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain, if(l_tx_data) l_token_str = l_tx_data->token_ticker; char *l_dst_to_str = - (l_tx_out) ? dap_chain_addr_to_str(&l_tx_out->addr) : - NULL; - if(l_tx_out) - dap_string_append_printf(l_str_out, " OUT item %"DAP_UINT64_FORMAT_U" %s to %s\n", - l_tx_out->header.value, - dap_strlen(l_token_str) > 0 ? l_token_str : "?", - l_dst_to_str ? l_dst_to_str : "?" - ); + (l_tx_out) ? dap_chain_addr_to_str(&l_tx_out->addr) : NULL; + + if(l_tx_out) { + if ( l_type_256 ) // 256 + dap_string_append_printf(l_str_out, " OUT 256_t item %s %s to %s\n", + dap_chain_u256tostr(l_tx_out->header.value_256), + dap_strlen(l_token_str) > 0 ? l_token_str : "?", + l_dst_to_str ? l_dst_to_str : "?" + ); + else + dap_string_append_printf(l_str_out, " OUT item %"DAP_UINT64_FORMAT_U" %s to %s\n", + l_tx_out->header.value, + dap_strlen(l_token_str) > 0 ? l_token_str : "?", + l_dst_to_str ? l_dst_to_str : "?" + ); + } DAP_DELETE(l_dst_to_str); l_list_tmp = dap_list_next(l_list_tmp); } @@ -540,19 +701,30 @@ char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain, dap_chain_datum_tx_t *l_tx_prev = l_datum_prev ? (dap_chain_datum_tx_t*) l_datum_prev->data : NULL; - // find OUT items in prev datum - dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev, - TX_ITEM_TYPE_OUT, NULL); - // find OUT item for IN item; - dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items, - l_tx_in->header.tx_out_prev_idx); - dap_chain_tx_out_t *l_tx_prev_out = - l_list_out_prev_item ? - (dap_chain_tx_out_t*) l_list_out_prev_item->data : - NULL; - // print value from prev out item - dap_string_append_printf(l_str_out, " prev OUT item value=%"DAP_UINT64_FORMAT_U, - l_tx_prev_out ? l_tx_prev_out->header.value : 0); + if ( l_type_256 ) { // 256 + // find OUT items in prev datum + dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev, + TX_ITEM_TYPE_256_OUT, NULL); + // find OUT item for IN item; + dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items, + l_tx_in->header.tx_out_prev_idx); + dap_chain_tx_out_t *l_tx_prev_out = + l_list_out_prev_item ? (dap_chain_tx_out_t*)l_list_out_prev_item->data : + NULL; + // print value from prev out item + dap_string_append_printf(l_str_out, " prev OUT 256_t item value=%s", + l_tx_prev_out ? dap_chain_u256tostr(l_tx_prev_out->header.value_256) : "0"); + } else { + dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev, + TX_ITEM_TYPE_OUT, NULL); + dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items, + l_tx_in->header.tx_out_prev_idx); + dap_chain_tx_out_t *l_tx_prev_out = + l_list_out_prev_item ? (dap_chain_tx_out_t*)l_list_out_prev_item->data : + NULL; + dap_string_append_printf(l_str_out, " prev OUT item value=%"DAP_UINT64_FORMAT_U, + l_tx_prev_out ? l_tx_prev_out->header.value : 0); + } } dap_string_append_printf(l_str_out, "\n"); l_list_tmp = dap_list_next(l_list_tmp); @@ -1030,7 +1202,7 @@ static char* dap_db_history_token_list(dap_chain_t * a_chain, const char *a_toke // Simple private token decl case DAP_CHAIN_DATUM_TOKEN_TYPE_SIMPLE: dap_string_append_printf(l_str_out, " total_supply: %.0Lf(%"DAP_UINT64_FORMAT_U"), signs: valid/total %02d/%02d \n", - l_token->header_private.total_supply / DATOSHI_LD, + dap_chain_datoshi_to_coins(l_token->header_private.total_supply), l_token->header_private.total_supply, l_token->header_private.signs_valid, l_token->header_private.signs_total); break; @@ -1049,7 +1221,7 @@ static char* dap_db_history_token_list(dap_chain_t * a_chain, const char *a_toke char * l_balance = dap_chain_balance_to_coins(l_token->header_public.total_supply); dap_string_append_printf(l_str_out, " total_supply: %.0Lf(%s), flags: 0x%x\n, premine_supply: %s, premine_address '%s'\n", - l_token->header_public.total_supply / DATOSHI_LD, + dap_chain_datoshi_to_coins(l_token->header_public.total_supply), dap_chain_balance_print(l_token->header_public.total_supply), l_token->header_public.flags, dap_chain_balance_print(l_token->header_public.premine_supply), @@ -1093,7 +1265,6 @@ static char* dap_db_history_token_list(dap_chain_t * a_chain, const char *a_toke static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger, const char *a_filter_token_name, const char *a_filtr_addr_base58, const char *a_hash_out_type, long a_datum_start, long a_datum_end, long *a_total_datums, dap_chain_tx_hash_processed_ht_t *a_tx_hash_processed) { dap_string_t *l_str_out = dap_string_new(NULL); - bool l_tx_hash_found = false; // list all transactions dap_tx_data_t *l_tx_data_hash = NULL; @@ -1113,7 +1284,6 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger return NULL ; } for(size_t l_datum_n = 0; l_datum_n < l_datums_count; l_datum_n++) { - dap_chain_datum_t *l_datum = l_datums[l_datum_n]; if(!l_datum) { // || l_datum->header.type_id != DAP_CHAIN_DATUM_TX) { // go to next atom @@ -1144,7 +1314,6 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger // token case DAP_CHAIN_DATUM_TOKEN_DECL: { - // no token necessary for addr if(a_filtr_addr_base58) { break; @@ -1163,7 +1332,7 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger // Simple private token decl case DAP_CHAIN_DATUM_TOKEN_TYPE_SIMPLE: dap_string_append_printf(l_str_out, " total_supply: %.0Lf(%"DAP_UINT64_FORMAT_U"), signs: valid/total %02d/%02d \n", - l_token->header_private.total_supply / DATOSHI_LD, + dap_chain_datoshi_to_coins(l_token->header_private.total_supply), l_token->header_private.total_supply, l_token->header_private.signs_valid, l_token->header_private.signs_total); break; @@ -1182,7 +1351,7 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger char * l_balance = dap_chain_balance_to_coins(l_token->header_public.total_supply); dap_string_append_printf(l_str_out, " total_supply: %.0Lf(%s), flags: 0x%x\n, premine_supply: %s, premine_address '%s'\n", - l_token->header_public.total_supply / DATOSHI_LD, + dap_chain_datoshi_to_coins(l_token->header_public.total_supply), dap_chain_balance_print(l_token->header_public.total_supply), l_token->header_public.flags, dap_chain_balance_print(l_token->header_public.premine_supply), @@ -1202,7 +1371,8 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger } break; - // emission + // emission + case DAP_CHAIN_DATUM_256_TOKEN_EMISSION: case DAP_CHAIN_DATUM_TOKEN_EMISSION: { // datum out of page if(a_datum_start >= 0 && (l_datum_num+l_datum_num_global < (size_t)a_datum_start || l_datum_num+l_datum_num_global >= (size_t)a_datum_end)) { @@ -1218,10 +1388,21 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger break; } - dap_string_append_printf(l_str_out, "emission: %.0Lf(%"DAP_UINT64_FORMAT_U") %s, type: %s, version: %d\n", - l_token_em->hdr.value / DATOSHI_LD, l_token_em->hdr.value, l_token_em->hdr.ticker, + if ( l_token_em->hdr.type_value_256 ) { // 256 + dap_string_append_printf(l_str_out, "emission 256: %.0Lf(%s) %s, type: %s, version: %d\n", + dap_chain_balance_to_coins(dap_chain_uint128_from_uint256(l_token_em->hdr.value_256)), + dap_chain_u256tostr(l_token_em->hdr.value_256), + l_token_em->hdr.ticker, + c_dap_chain_datum_token_emission_type_str[l_token_em->hdr.type], + l_token_em->hdr.version); + } else + dap_string_append_printf(l_str_out, "emission: %.0Lf(%"DAP_UINT64_FORMAT_U") %s, type: %s, version: %d\n", + dap_chain_datoshi_to_coins(l_token_em->hdr.value), + l_token_em->hdr.value, + l_token_em->hdr.ticker, c_dap_chain_datum_token_emission_type_str[l_token_em->hdr.type], l_token_em->hdr.version); + dap_string_append_printf(l_str_out, " to addr: %s\n", l_token_emission_address_str); DAP_DELETE(l_token_emission_address_str); @@ -1235,11 +1416,20 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger dap_string_append_printf(l_str_out, " codename: %s\n", l_token_em->data.type_algo.codename); break; case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER: - dap_string_append_printf(l_str_out, " value_start: %.0Lf(%"DAP_UINT64_FORMAT_U"), codename: %s\n", - l_token_em->data.type_atom_owner.value_start / DATOSHI_LD, + if ( l_token_em->hdr.type_value_256 ) { // 256 + dap_string_append_printf(l_str_out, " value_start: %s(%s), codename: %s\n", + dap_chain_datoshi_to_coins(dap_chain_uint128_from_uint256(l_token_em->data.type_atom_owner.value_start_256)), + dap_chain_u256tostr(l_token_em->data.type_atom_owner.value_start_256), + l_token_em->data.type_atom_owner.value_change_algo_codename + ); + } else { + dap_string_append_printf(l_str_out, " value_start: %.0Lf(%"DAP_UINT64_FORMAT_U"), codename: %s\n", + dap_chain_datoshi_to_coins(l_token_em->data.type_atom_owner.value_start), l_token_em->data.type_atom_owner.value_start, - l_token_em->data.type_atom_owner.value_change_algo_codename); - break; + l_token_em->data.type_atom_owner.value_change_algo_codename + ); + } + break; case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT: { char *l_addr = dap_chain_addr_to_str(&l_token_em->data.type_presale.addr); // get time of create datum @@ -1265,11 +1455,26 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger l_tx_num++; break; } + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datum->data; //calc tx hash s_dap_chain_datum_tx_out_data(l_tx, a_ledger, l_str_out, a_hash_out_type, true, &a_tx_hash_processed, &l_tx_num); } break; + + // transaction + case DAP_CHAIN_DATUM_256_TX:{ + + // datum out of page + if(a_datum_start >= 0 && (l_datum_num+l_datum_num_global < (size_t)a_datum_start || l_datum_num+l_datum_num_global >= (size_t)a_datum_end)) { + l_tx_num++; + break; + } + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datum->data; + s_dap_chain_datum_tx_out_data(l_tx, a_ledger, l_str_out, a_hash_out_type, true, &a_tx_hash_processed, &l_tx_num); + } + break; + default: dap_string_append_printf(l_str_out, "unknown datum type=%d\n", l_datum->header.type_id); break; @@ -1339,7 +1544,6 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>"); return -1; } - int l_cmd = CMD_NONE; if (dap_chain_node_cli_find_option_val(a_argv, 1, 2, "list", NULL)){ l_cmd = CMD_LIST; @@ -1348,6 +1552,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) if (dap_chain_node_cli_find_option_val(a_argv, 2, 3, "info", NULL)) l_cmd = CMD_TX_INFO; } + // command tx_history if(l_cmd == CMD_TX_HISTORY) { bool l_is_all = dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-all", NULL); @@ -1374,6 +1579,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) return -3; } } + //Select chain emission if(!l_chain_str) { // chain may be null -> then all chain use //dap_chain_node_cli_set_reply_text(a_str_reply, "command requires parameter '-chain'"); @@ -1400,6 +1606,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) // dap_chain_hash_fast_to_str(&l_tx_hash, hash_str,99); // int gsdgsd=523; } + dap_chain_addr_t *l_addr = NULL; // if need addr if(l_wallet_name || l_addr_base58) { @@ -1433,7 +1640,9 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) // all chain else l_chain_cur = dap_chain_enum(&l_chain_tmp); + while(l_chain_cur) { + // only selected net if(l_net->pub.id.uint64 == l_chain_cur->net_id.uint64) { // separator between chains @@ -1443,12 +1652,14 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) char *l_str_out = NULL; dap_string_append_printf(l_str_ret, "chain: %s\n", l_chain_cur->name); dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str); + if(l_is_all) { // without filters l_str_out = dap_db_history_filter(l_chain_cur, l_ledger, NULL, NULL, l_hash_out_type, -1, 0, NULL, l_list_tx_hash_processd); dap_string_append_printf(l_str_ret, "all history:\n%s\n", l_str_out ? l_str_out : " empty"); } else { + l_str_out = l_tx_hash_str ? dap_db_history_tx(&l_tx_hash, l_chain_cur, l_hash_out_type) : dap_db_history_addr(l_addr, l_chain_cur, l_hash_out_type); @@ -1473,6 +1684,8 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) dap_chain_enum_unlock(); l_chain_cur = dap_chain_enum(&l_chain_tmp); } + + DAP_DELETE(l_addr); _dap_chain_tx_hash_processed_ht_free(l_list_tx_hash_processd); // all chain @@ -1483,6 +1696,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) return 0; } else if(l_cmd == CMD_LIST){ + enum {SUBCMD_NONE, SUBCMD_LIST_COIN}; int l_sub_cmd = SUBCMD_NONE; if (dap_chain_node_cli_find_option_val(a_argv, 2, 3, "coins", NULL )) @@ -1508,6 +1722,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) dap_string_free(l_str_ret, true); return 0; } else if (l_cmd == CMD_TX_INFO){ + //GET hash dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-hash", &l_tx_hash_str); //get net diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c index 21dcd4d34b4f260c8dcd8789f126596593b4ea79..56cdef9d0ebdbfaf3be0e9342f8573e6e9dfae25 100644 --- a/modules/net/srv/dap_chain_net_srv_order.c +++ b/modules/net/srv/dap_chain_net_srv_order.c @@ -546,8 +546,9 @@ static void s_srv_order_callback_notify(void *a_arg, const char a_op_code, const } dap_chain_addr_t l_addr = {}; dap_chain_addr_fill(&l_addr, l_sign->header.type, &l_pkey_hash, l_net->pub.id); - uint128_t l_balance = dap_chain_ledger_calc_balance(l_net->pub.ledger, &l_addr, l_order->price_ticker); - uint64_t l_solvency = dap_chain_uint128_to(l_balance); + // uint128_t l_balance = dap_chain_ledger_calc_balance(l_net->pub.ledger, &l_addr, l_order->price_ticker); + uint256_t l_balance = dap_chain_ledger_calc_balance(l_net->pub.ledger, &l_addr, l_order->price_ticker); + uint64_t l_solvency = dap_chain_uint256_to(l_balance); if (l_solvency < l_order->price && !dap_chain_net_srv_stake_key_delegated(&l_addr)) { dap_chain_global_db_gr_del(dap_strdup(a_key), a_group); }*/ diff --git a/modules/service/stake/dap_chain_net_srv_stake.c b/modules/service/stake/dap_chain_net_srv_stake.c index ea3594eff8f126b8fa926597f550813b5053d332..62f1e2522a39545a5ea08ddf00ad37c73f195e56 100644 --- a/modules/service/stake/dap_chain_net_srv_stake.c +++ b/modules/service/stake/dap_chain_net_srv_stake.c @@ -719,7 +719,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha dap_chain_node_cli_set_reply_text(a_str_reply, "Format -fee_percent <long double>(%)"); return -12; } - uint64_t l_balance = dap_chain_uint128_to(dap_chain_wallet_get_balance(l_wallet, l_net->pub.id, l_token_str)); + uint64_t l_balance = dap_chain_uint256_to(dap_chain_wallet_get_balance(l_wallet, l_net->pub.id, l_token_str)); if (l_balance < l_value) { dap_chain_node_cli_set_reply_text(a_str_reply, "Insufficient coins for token %s in wallet '%s'", l_token_str, l_wallet_str); return -13; @@ -892,7 +892,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha dap_chain_node_cli_set_reply_text(a_str_reply, "Specified wallet not found"); return -18; } - uint64_t l_balance = dap_chain_uint128_to(dap_chain_wallet_get_balance(l_wallet, l_net->pub.id, l_stake->token)); + uint64_t l_balance = dap_chain_uint256_to(dap_chain_wallet_get_balance(l_wallet, l_net->pub.id, l_stake->token)); if (l_balance < l_stake->value) { dap_chain_node_cli_set_reply_text(a_str_reply, "Insufficient coins for token %s in wallet '%s'", l_token_str, l_wallet_str); return -11; diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index df904b6701f4432326172ca942dc695649498fbf..e38168e51a839f904d87819a86c4899d8bc28dff 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -571,8 +571,8 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c dap_chain_node_cli_set_reply_text(a_str_reply, "Specified wallet not found"); return -11; } - uint128_t l_balance = dap_chain_wallet_get_balance(l_wallet, l_net_sell->pub.id, l_token_sell_str); - uint64_t l_value = dap_chain_uint128_to(l_balance); + uint256_t l_balance = dap_chain_wallet_get_balance(l_wallet, l_net_sell->pub.id, l_token_sell_str); + uint64_t l_value = dap_chain_uint256_to(l_balance); if (l_value < l_datoshi_sell) { dap_chain_node_cli_set_reply_text(a_str_reply, "Not enough cash in specified wallet"); dap_chain_wallet_close(l_wallet); @@ -695,8 +695,8 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c dap_chain_node_cli_set_reply_text(a_str_reply, "At least one of updating parameters is mandatory"); return -13; } - uint128_t l_balance = dap_chain_wallet_get_balance(l_wallet, l_net_sell->pub.id, l_token_sell_str); - uint64_t l_value = dap_chain_uint128_to(l_balance); + uint256_t l_balance = dap_chain_wallet_get_balance(l_wallet, l_net_sell->pub.id, l_token_sell_str); + uint64_t l_value = dap_chain_uint256_to(l_balance); if (l_datoshi_sell && l_value < l_datoshi_sell) { dap_chain_node_cli_set_reply_text(a_str_reply, "Not enough cash in specified wallet"); dap_chain_wallet_close(l_wallet); diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 7d2b74322d88836c07dda4166053f20fb7b8a80b..618969208652eee19363d1b5f9352ca44b76809c 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -622,8 +622,12 @@ static int s_add_atom_to_ledger(dap_chain_cs_blocks_t * a_blocks, dap_ledger_t dap_chain_datum_token_t *l_token = (dap_chain_datum_token_t*) l_datum->data; l_ret=dap_chain_ledger_token_load(a_ledger, l_token, l_datum->header.data_size); } break; + case DAP_CHAIN_DATUM_256_TOKEN_EMISSION: // 256 case DAP_CHAIN_DATUM_TOKEN_EMISSION: { - l_ret=dap_chain_ledger_token_emission_load(a_ledger, l_datum->data, l_datum->header.data_size); + dap_chain_datum_token_emission_t *l_token_em = (dap_chain_datum_token_emission_t*) l_datum->data; + l_token_em->hdr.type_value_256 = l_datum->header.type_id == DAP_CHAIN_DATUM_256_TOKEN_EMISSION ? + true : false; + l_ret=dap_chain_ledger_token_emission_load(a_ledger, l_token_em, l_datum->header.data_size); } break; case DAP_CHAIN_DATUM_TX: { dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 837281f0b6dbbd42dcfc8a64ad9f7d93e9f7f864..9434252e15801975b59a977971da968163a505a7 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -303,10 +303,15 @@ static int s_dap_chain_add_atom_to_ledger(dap_chain_cs_dag_t * a_dag, dap_ledger return dap_chain_ledger_token_load(a_ledger, l_token, l_datum->header.data_size); } break; + case DAP_CHAIN_DATUM_256_TOKEN_EMISSION: // 256 case DAP_CHAIN_DATUM_TOKEN_EMISSION: { - return dap_chain_ledger_token_emission_load(a_ledger, l_datum->data, l_datum->header.data_size); + dap_chain_datum_token_emission_t *l_token_em = (dap_chain_datum_token_emission_t*) l_datum->data; + l_token_em->hdr.type_value_256 = l_datum->header.type_id == DAP_CHAIN_DATUM_256_TOKEN_EMISSION ? + true : false; + return dap_chain_ledger_token_emission_load(a_ledger, l_token_em, l_datum->header.data_size); } break; + case DAP_CHAIN_DATUM_256_TX: // 256 case DAP_CHAIN_DATUM_TX: { dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; // don't save bad transactions to base diff --git a/modules/wallet/dap_chain_wallet.c b/modules/wallet/dap_chain_wallet.c index aca3c351158194545b7512780b5b9913b728ea28..cd71a2ceff67e4d164b37a981f206167082efa5a 100644 --- a/modules/wallet/dap_chain_wallet.c +++ b/modules/wallet/dap_chain_wallet.c @@ -423,15 +423,16 @@ dap_chain_wallet_t * dap_chain_wallet_open(const char * a_wallet_name, const cha * @param a_net_id * @return */ -uint128_t dap_chain_wallet_get_balance(dap_chain_wallet_t *a_wallet, dap_chain_net_id_t a_net_id, const char *a_token_ticker) +uint256_t dap_chain_wallet_get_balance(dap_chain_wallet_t *a_wallet, dap_chain_net_id_t a_net_id, const char *a_token_ticker) { dap_chain_net_t *l_net = dap_chain_net_by_id(a_net_id); dap_chain_addr_t *l_addr =dap_chain_wallet_get_addr(a_wallet, a_net_id); -#ifdef DAP_GLOBAL_IS_INT128 - uint128_t l_balance = 0; -#else - uint128_t l_balance = {}; -#endif +// #ifdef DAP_GLOBAL_IS_INT128 +// uint128_t l_balance = 0; +// #else +// uint128_t l_balance = {}; +// #endif + uint256_t l_balance = uint256_0; if (l_net) { dap_ledger_t *l_ledger = l_net->pub.ledger; diff --git a/modules/wallet/include/dap_chain_wallet.h b/modules/wallet/include/dap_chain_wallet.h index f1b3e81e59162a3c0c2156e2e5f5baffb0f2bbc4..51ffd4c91ba18f5af2488f0d9855736e30211c31 100644 --- a/modules/wallet/include/dap_chain_wallet.h +++ b/modules/wallet/include/dap_chain_wallet.h @@ -58,6 +58,6 @@ size_t dap_chain_wallet_get_certs_number( dap_chain_wallet_t * a_wallet); dap_pkey_t * dap_chain_wallet_get_pkey( dap_chain_wallet_t * a_wallet,uint32_t a_key_idx); dap_enc_key_t * dap_chain_wallet_get_key( dap_chain_wallet_t * a_wallet,uint32_t a_key_idx); -uint128_t dap_chain_wallet_get_balance(dap_chain_wallet_t *a_wallet, dap_chain_net_id_t a_net_id, const char *a_token_ticker); +uint256_t dap_chain_wallet_get_balance(dap_chain_wallet_t *a_wallet, dap_chain_net_id_t a_net_id, const char *a_token_ticker); int dap_chain_wallet_save_file( dap_chain_wallet_t * a_wallet);