diff --git a/README.md b/README.md index c785a3baf..ef3d637a6 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Dependencies ``` #The following packages are needed: -sudo apt-get install build-essential pkg-config libcurl-gnutls-dev libc6-dev libevent-dev m4 g++-multilib autoconf libtool ncurses-dev unzip git python zlib1g-dev wget bsdmainutils automake libboost-all-dev libssl-dev libprotobuf-dev protobuf-compiler libqt4-dev libqrencode-dev libdb++-dev ntp ntpdate +sudo apt-get install build-essential pkg-config libcurl3-gnutls-dev libc6-dev libevent-dev m4 g++-multilib autoconf libtool ncurses-dev unzip git python zlib1g-dev wget bsdmainutils automake libboost-all-dev libssl-dev libprotobuf-dev protobuf-compiler libqt4-dev libqrencode-dev libdb++-dev ntp ntpdate ``` Komodo @@ -180,4 +180,44 @@ mv ~/.komodo ~/.komodo.old && mkdir ~/.komodo && cp ~/.komodo.old/komodo.conf ~/ ./komodod -exchange -exportdir=/tmp & ./komodo-cli importwallet /tmp/example +############## JUMBLR + +komodod now has jumblr_deposit and jumblr_secret RPC calls. + +Jumblr works like described previously where all the nodes with jumblr active synchronize their tx activity during the same block to maximize the mixing effect. However, unlike all other mixers/tumblers, you never give up control of your coins to anybody else. JUMBLR uses a one to many allocation of funds, ie. one deposit address and many secret addresses. You can always run multiple komodod daemons to get multiple active deposit addresses. + +JUMBLR implements t -> z, z -> z and z -> t transactions to maximize privacy of the destination t (transparent) address. So while it is transparent, its first activity is funds coming from an untracable z address. + +Which of the three stages is done is randomly selected at each turn. Also when there are more than one possible transaction at the selected stage, a random one is selected. This randomization prevents analyzing incoming z ->t transactions by its size to correlate it to the originating address. + +jumblr_deposit designates the deposit address as the jumblr deposit address for that session. You can select an address that already has funds in it and it will immediately start jumblr process. If there are no funds, it will wait until you send funds to it. + +There are three sizes of a jumblr transaction: 10 KMD, 100 KMD and 1000 KMD. There is also a fixed interval of blocks where all jumblr nodes are active. Currently it is set to be 10, but this is subject to change. Only during every 10*10 blocks are the largest 1000 KMD transactions processed, so this concentrates all the large transactions every N*N blocks. + +jumblr_secret notifies JUMBLR where to send the final z -> t transactions. In order to allow larger accounts to obtain privacy, up to 777 secret addresses are supported. Whenever a z -> t stage is activated, a random secret address from the list of the then active secret addresses is selected. + +Practical Advice: +Obtaining privacy used to be very difficult. JUMBLR makes it as simple as issuing two command line calls. Higher level layers can be added to help manage the addresses, ie. linking them at the passphrase level. Such things are left to each implementation. + +Once obtained, it is very easy to lose all the privacy. With a single errant transaction that combines some previously used address and the secretaddress, well, the secretaddress is no longer so private. + +The advice is to setup a totally separate node! + +This might seem a bit drastic, but if you want to maintain privacy, it is best to make it look like all the transactions are coming from a different node. The easiest way for most people to do this is to actually have a different node. + +It can be a dedicated laptop (recommended) or a VPS (for not so big amounts) with a totally fresh komodod wallet. Generate an address on this wallet and use that as the jumblr_secret address on your main node. As the JUMBLR operates funds will teleport into your secret node's address. If you are careful and never use the same IP address for both your nodes, you will be able to maintain very good privacy. + +Of course, dont be sending emails that link the two accounts together! Dont use secret address funds for home delivery purchases!! Etc. There are many ways to lose the privacy, just think about what linkages can be dont at the IP and blockchain level and that should be a useful preparation. + +What if you have 100,000 KMD and you dont want others to know you are such a whale? + +Instead of generating 1 secret address, generate 100 and make a script file with: + +./komodo-cli jumblr_secret +./komodo-cli jumblr_secret +... +./komodo-cli jumblr_secret + +And make sure to delete all traces of this when the JUMBLR is finished. You will end up with 100 addresses that have an average of 1000 KMD each. So as long as you are careful and dont do a 10,000 KMD transaction (that will link 10 of your secret addresses together), you can appear as 100 different people each with 1000 KMD. + diff --git a/src/assetchains b/src/assetchains index a85cdbe38..4fcc83fac 100755 --- a/src/assetchains +++ b/src/assetchains @@ -1,87 +1,79 @@ -#!/bin/bash -set -x -delay=10 +#!/bin/bash source pubkey.txt -echo $pubkey +args=("$@") +seed_ip='78.47.196.146' +komodo_binary='./komodod' +delay=20 -./komodod -pubkey=$pubkey -ac_name=REVS -ac_supply=1300000 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=SUPERNET -ac_supply=816061 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=DEX -ac_supply=999999 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=PANGEA -ac_supply=999999 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=JUMBLR -ac_supply=999999 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=BET -ac_supply=999999 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=CRYPTO -ac_supply=999999 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=HODL -ac_supply=9999999 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=SHARK -ac_supply=1401 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=BOTS -ac_supply=999999 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=MGW -ac_supply=999999 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=MVP -ac_supply=1000000 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=WLC -ac_supply=210000000 -addnode=148.251.190.89 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=KV -ac_supply=1000000 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=CEAL -ac_supply=366666666 -addnode=78.47.196.146 $1 -gen & -./komodod -pubkey=$pubkey -ac_name=MESH -ac_supply=1000007 -addnode=78.47.196.146 $1 -gen & -sleep $delay +function komodo_asset () +{ + if [ $[RANDOM % 10] == 1 ] + then + gen=" -gen" + else + gen="" + fi -./komodod -pubkey=$pubkey -ac_name=USD -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=EUR -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=JPY -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=GBP -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=AUD -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=CAD -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=CHF -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=NZD -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=CNY -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=RUB -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=MXN -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=BRL -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=INR -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=HKD -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=TRY -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=ZAR -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=PLN -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=NOK -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=SEK -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=DKK -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=CZK -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=HUF -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=ILS -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=KRW -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=MYR -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=PHP -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=RON -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=SGD -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=THB -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=BGN -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=IDR -addnode=78.47.196.146 $1 & -sleep $delay -./komodod -pubkey=$pubkey -ac_name=HRK -addnode=78.47.196.146 $1 & + if [ -n "$2" ] + then + supply=" -ac_supply=$2" + else + supply=" " + fi + + $komodo_binary -pubkey=$pubkey -ac_name=$1 $supply -addnode=$seed_ip $gen $args & + sleep $delay +} + +#set -x + +komodo_asset REVS 1300000 +komodo_asset SUPERNET 816061 +komodo_asset DEX 999999 +komodo_asset PANGEA 999999 +komodo_asset JUMBLR 999999 +komodo_asset BET 999999 +komodo_asset CRYPTO 999999 +komodo_asset HODL 9999999 +komodo_asset SHARK 1401 +komodo_asset BOTS 999999 +komodo_asset MGW 999999 +#komodo_asset MVP 1000000 +komodo_asset COQUI 72000000 +komodo_asset WLC 210000000 +komodo_asset KV 1000000 +komodo_asset CEAL 366666666 +komodo_asset MESH 1000007 + +komodo_asset USD +komodo_asset EUR +komodo_asset JPY +komodo_asset GBP +komodo_asset AUD +komodo_asset CAD +komodo_asset CHF +komodo_asset NZD +komodo_asset CNY +komodo_asset RUB +komodo_asset MXN +komodo_asset BRL +komodo_asset INR +komodo_asset HKD +komodo_asset TRY +komodo_asset ZAR +komodo_asset PLN +komodo_asset NOK +komodo_asset SEK +komodo_asset DKK +komodo_asset CZK +komodo_asset HUF +komodo_asset ILS +komodo_asset KRW +komodo_asset MYR +komodo_asset PHP +komodo_asset RON +komodo_asset SGD +komodo_asset THB +komodo_asset BGN +komodo_asset IDR +komodo_asset HRK diff --git a/src/assetchains.old b/src/assetchains.old new file mode 100755 index 000000000..13cb7f29b --- /dev/null +++ b/src/assetchains.old @@ -0,0 +1,88 @@ +#!/bin/bash +set -x +delay=10 +source pubkey.txt +echo $pubkey + +./komodod -pubkey=$pubkey -ac_name=REVS -ac_supply=1300000 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=SUPERNET -ac_supply=816061 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=DEX -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=PANGEA -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=JUMBLR -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=BET -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=CRYPTO -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=HODL -ac_supply=9999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=SHARK -ac_supply=1401 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=BOTS -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=MGW -ac_supply=999999 -addnode=78.47.196.146 $1 & +#./komodod -pubkey=$pubkey -ac_name=MVP -ac_supply=1000000 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=COQUI -ac_supply=72000000 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=WLC -ac_supply=210000000 -addnode=148.251.190.89 $1 & +./komodod -pubkey=$pubkey -ac_name=KV -ac_supply=1000000 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=CEAL -ac_supply=366666666 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=MESH -ac_supply=1000007 -addnode=78.47.196.146 $1 & +sleep $delay + +./komodod -pubkey=$pubkey -ac_name=USD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=EUR -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=JPY -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=GBP -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=AUD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=CAD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=CHF -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=NZD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=CNY -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=RUB -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=MXN -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=BRL -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=INR -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=HKD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=TRY -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=ZAR -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=PLN -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=NOK -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=SEK -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=DKK -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=CZK -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=HUF -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=ILS -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=KRW -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=MYR -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=PHP -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=RON -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=SGD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=THB -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=BGN -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=IDR -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=HRK -addnode=78.47.196.146 $1 & diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index ccdf93d9b..7679fa961 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -50,7 +50,7 @@ void WaitForShutdown(boost::thread_group* threadGroup) if ( ASSETCHAINS_SYMBOL[0] == 0 ) { komodo_passport_iteration(); - MilliSleep(10000); + MilliSleep(1000); } else MilliSleep(1000); fShutdown = ShutdownRequested(); } diff --git a/src/dpowassets b/src/dpowassets index 8115fdd27..aaca8bcfb 100755 --- a/src/dpowassets +++ b/src/dpowassets @@ -16,7 +16,8 @@ curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dp curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"SHARK\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"BOTS\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MGW\",\"pubkey\":\"$pubkey\"}" -curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MVP\",\"pubkey\":\"$pubkey\"}" +#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MVP\",\"pubkey\":\"$pubkey\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"COQUI\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"WLC\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KV\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CEAL\",\"pubkey\":\"$pubkey\"}" diff --git a/src/fiat-cli b/src/fiat-cli index aa29a3095..119f25c6d 100755 --- a/src/fiat-cli +++ b/src/fiat-cli @@ -43,7 +43,8 @@ echo hodl; fiat/hodl $1 $2 $3 $4 echo shark; fiat/shark $1 $2 $3 $4 echo bots; fiat/bots $1 $2 $3 $4 echo mgw; fiat/mgw $1 $2 $3 $4 -echo mvp; fiat/mvp $1 $2 $3 $4 +#echo mvp; fiat/mvp $1 $2 $3 $4 +echo coqui; fiat/coqui $1 $2 $3 $4 echo wlc; fiat/wlc $1 $2 $3 $4 echo kv; fiat/kv $1 $2 $3 $4 echo ceal; fiat/ceal $1 $2 $3 $4 diff --git a/src/fiat/coqui b/src/fiat/coqui new file mode 100755 index 000000000..d4fcb63d5 --- /dev/null +++ b/src/fiat/coqui @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=COQUI $1 $2 $3 $4 $5 $6 diff --git a/src/komodo.h b/src/komodo.h index 663edb1e2..e81522eb5 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -46,6 +46,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block); int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char *dest); #include "komodo_kv.h" +#include "komodo_jumblr.h" #include "komodo_gateway.h" #include "komodo_events.h" diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 7d4923608..088e8d415 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -270,7 +270,7 @@ int32_t komodo_paxcmp(char *symbol,int32_t kmdheight,uint64_t value,uint64_t che if ( seed == 0 && checkvalue != 0 ) { ratio = ((value << 6) / checkvalue); - if ( ratio >= 62 && ratio <= 66 ) + if ( ratio >= 60 && ratio <= 67 ) return(0); else { @@ -652,7 +652,7 @@ void komodo_passport_iteration(); int32_t komodo_check_deposit(int32_t height,const CBlock& block) // verify above block is valid pax pricing { static uint256 array[64]; static int32_t numbanned,indallvouts; - int32_t i,j,k,n,ht,baseid,txn_count,activation,num,opretlen,offset=1,errs=0,matched=0,kmdheights[64],otherheights[64]; uint256 hash,txids[64]; char symbol[16],base[16]; uint16_t vouts[64]; int8_t baseids[64]; uint8_t *script,opcode,rmd160s[64*20]; uint64_t total,available,deposited,issued,withdrawn,approved,redeemed,checktoshis,seed; int64_t values[64],srcvalues[64]; struct pax_transaction *pax; struct komodo_state *sp; + int32_t i,j,k,n,ht,baseid,txn_count,activation,num,opretlen,offset=1,errs=0,matched=0,kmdheights[256],otherheights[256]; uint256 hash,txids[256]; char symbol[16],base[16]; uint16_t vouts[256]; int8_t baseids[256]; uint8_t *script,opcode,rmd160s[256*20]; uint64_t total,available,deposited,issued,withdrawn,approved,redeemed,checktoshis,seed; int64_t values[256],srcvalues[256]; struct pax_transaction *pax; struct komodo_state *sp; activation = 235300; if ( *(int32_t *)&array[0] == 0 ) numbanned = komodo_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array))); @@ -745,6 +745,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block) // verify above } while ( KOMODO_PASSPORT_INITDONE == 0 ) komodo_passport_iteration(); + komodo_passport_iteration(); // grandfathering preexisting if ( height < 777 ) return(0); @@ -845,7 +846,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block) // verify above } else if ( baseid == CZK ) { - if ( height == 1084 || height == 1085 || height == 1086 || height == 778 || height == 1079 || height == 1054 || height == 1032 || height == 121 || height == 1030 || height == 182 || height == 876 || height == 873 || height == 871 || height == 184 || height == 862 || height == 185 || height == 861 || height == 186 || height == 838 || height == 238 || height == 242 || height == 246 || height == 248 || height == 250 || height == 251 || height == 256 || height == 282 || height == 322 || height == 343 || height == 433 || height == 323 || height == 276 ) + if ( height < 1000 || height == 1084 || height == 1085 || height == 1086 || height == 778 || height == 1079 || height == 1054 || height == 1032 || height == 121 || height == 1030 || height == 182 || height == 876 || height == 873 || height == 871 || height == 184 || height == 862 || height == 185 || height == 861 || height == 186 || height == 838 || height == 238 || height == 242 || height == 246 || height == 248 || height == 250 || height == 251 || height == 256 || height == 282 || height == 322 || height == 343 || height == 433 || height == 323 || height == 276 ) return(0); } else if ( baseid == HUF ) @@ -915,11 +916,20 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block) // verify above { for (i=1; iRTmask & (1LL << baseids[i-1])) == 0 ) + if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 && (sp= komodo_stateptrget(ASSETCHAINS_SYMBOL)) != 0 && strcmp(CURRENCIES[baseids[i-1]],ASSETCHAINS_SYMBOL) == 0 ) { - /*printf("skip checkdeposit.%s not RT %llx\n",CURRENCIES[baseids[i-1]],(long long)sp->RTmask); - matched++; - continue;*/ + int32_t rtflag = 0; + while ( (sp->RTmask & (1LL << 32)) == 0 ) + { + if ( rtflag == 0 ) + printf("[%s] skip checkdeposit.%s not RT %llx\n",ASSETCHAINS_SYMBOL,CURRENCIES[baseids[i-1]],(long long)sp->RTmask); + sleep(60); + rtflag = 1; + //matched++; + //continue; + } + if ( rtflag != 0 ) + printf("[%s] %s reached RT\n",ASSETCHAINS_SYMBOL,CURRENCIES[baseids[i-1]]); } if ( (pax= komodo_paxfinds(txids[i-1],vouts[i-1])) != 0 ) // finds... make sure right one { @@ -968,8 +978,8 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block) // verify above printf("%.8f ",dstr(block.vtx[0].vout[j].nValue)); printf("vout values\n"); for (j=0; j<32; j++) - printf("%02x",((uint8_t *)&hash)[j]); - printf(" kht.%d ht.%d %.8f %.8f blockhash couldnt find vout.[%d of %d] ht.%d %s for [%s]\n",kmdheights[i-1],otherheights[i-1],dstr(values[i-1]),dstr(srcvalues[i]),i,n,height,ASSETCHAINS_SYMBOL,CURRENCIES[baseids[i-1]]); + printf("%02x",((uint8_t *)&txids[i-1])[j]); + printf(" kht.%d ht.%d %.8f %.8f couldnt find vout.[%d of %d] ht.%d %s for [%s]\n",kmdheights[i-1],otherheights[i-1],dstr(values[i-1]),dstr(srcvalues[i]),i,n,height,ASSETCHAINS_SYMBOL,CURRENCIES[baseids[i-1]]); if ( ASSETCHAINS_SYMBOL[0] != 0 || height >= activation ) return(-1); } @@ -1049,20 +1059,23 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 PAX_pubkey(0,&opretbuf[1],&addrtype,rmd160,base,&shortflag,&fiatoshis); bitcoin_address(coinaddr,addrtype,rmd160,20); checktoshis = PAX_fiatdest(&seed,tokomodo,destaddr,pubkey33,coinaddr,kmdheight,base,fiatoshis); + if ( komodo_paxcmp(base,kmdheight,value,checktoshis,kmdheight < 225000 ? seed : 0) != 0 ) + checktoshis = PAX_fiatdest(&seed,tokomodo,destaddr,pubkey33,coinaddr,height,base,fiatoshis); typestr = "deposit"; + if ( 0 && strcmp("NOK",base) == 0 ) + { + printf("[%s] %s paxdeposit height.%d vs kmdheight.%d\n",ASSETCHAINS_SYMBOL,base,height,kmdheight); + printf("(%s) (%s) kmdheight.%d vs height.%d check %.8f vs %.8f tokomodo.%d %d seed.%llx\n",ASSETCHAINS_SYMBOL,base,kmdheight,height,dstr(checktoshis),dstr(value),komodo_is_issuer(),strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0,(long long)seed); + for (i=0; i<32; i++) + printf("%02x",((uint8_t *)&txid)[i]); + printf(" <- txid.v%u ",vout); + for (i=0; i<33; i++) + printf("%02x",pubkey33[i]); + printf(" checkpubkey check %.8f v %.8f dest.(%s) kmdheight.%d height.%d\n",dstr(checktoshis),dstr(value),destaddr,kmdheight,height); + } if ( strcmp(base,ASSETCHAINS_SYMBOL) == 0 && (kmdheight > 195000 || kmdheight <= height) ) { didstats = 0; - if ( 0 && kmdheight > 214700 && strcmp(base,ASSETCHAINS_SYMBOL) == 0 ) - { - printf("(%s) (%s) kmdheight.%d vs height.%d check %.8f vs %.8f tokomodo.%d %d seed.%llx\n",ASSETCHAINS_SYMBOL,base,kmdheight,height,dstr(checktoshis),dstr(value),komodo_is_issuer(),strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0,(long long)seed); - for (i=0; i<32; i++) - printf("%02x",((uint8_t *)&txid)[i]); - printf(" <- txid.v%u ",vout); - for (i=0; i<33; i++) - printf("%02x",pubkey33[i]); - printf(" checkpubkey check %.8f v %.8f dest.(%s) kmdheight.%d height.%d\n",dstr(checktoshis),dstr(value),destaddr,kmdheight,height); - } if ( komodo_paxcmp(base,kmdheight,value,checktoshis,kmdheight < 225000 ? seed : 0) == 0 ) { if ( (pax= komodo_paxfind(txid,vout,'D')) == 0 ) @@ -1120,8 +1133,8 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 if ( kmdheight > 238000 && (kmdheight > 214700 || strcmp(base,ASSETCHAINS_SYMBOL) == 0) ) //seed != 0 && printf("pax %s deposit %.8f rejected kmdheight.%d %.8f KMD check %.8f seed.%llu\n",base,dstr(fiatoshis),kmdheight,dstr(value),dstr(checktoshis),(long long)seed); } - } //else printf("paxdeposit height.%d vs kmdheight.%d\n",height,kmdheight); - } + } //else printf("[%s] %s paxdeposit height.%d vs kmdheight.%d\n",ASSETCHAINS_SYMBOL,base,height,kmdheight); + } //else printf("unsupported size.%d for opreturn D\n",opretlen); } else if ( opretbuf[0] == 'I' ) { @@ -1350,7 +1363,10 @@ void komodo_passport_iteration() } refsp = komodo_stateptr(symbol,dest); if ( ASSETCHAINS_SYMBOL[0] == 0 ) + { refid = 33; + jumblr_iteration(); + } else { refid = komodo_baseid(ASSETCHAINS_SYMBOL)+1; // illegal base -> baseid.-1 -> 0 @@ -1384,6 +1400,7 @@ void komodo_passport_iteration() { if ( baseid == 32 || ASSETCHAINS_SYMBOL[0] == 0 ) { + refsp->RTmask &= ~(1LL << baseid); komodo_statefname(fname,baseid<32?base:(char *)"",(char *)"komodostate"); komodo_nameset(symbol,dest,base); sp = komodo_stateptrget(symbol); @@ -1422,12 +1439,13 @@ void komodo_passport_iteration() if ( fread(buf,1,sizeof(buf),fp) == sizeof(buf) ) { sp->CURRENT_HEIGHT = buf[0]; - if ( buf[0] != 0 && buf[0] >= buf[1] && buf[2] > time(NULL)-300 ) + if ( buf[0] != 0 && buf[0] >= buf[1] && buf[2] > time(NULL)-60 ) { isrealtime = 1; RTmask |= (1LL << baseid); memcpy(refsp->RTbufs[baseid+1],buf,sizeof(refsp->RTbufs[baseid+1])); - } else if ( KOMODO_PAX != 0 && (time(NULL)-buf[2]) > 1800 && ASSETCHAINS_SYMBOL[0] != 0 ) + } + else if ( KOMODO_PAX != 0 && (time(NULL)-buf[2]) > 60 && ASSETCHAINS_SYMBOL[0] != 0 ) fprintf(stderr,"[%s]: %s not RT %u %u %d\n",ASSETCHAINS_SYMBOL,base,buf[0],buf[1],(int32_t)(time(NULL)-buf[2])); } //else fprintf(stderr,"%s size error RT\n",base); fclose(fp); @@ -1436,6 +1454,7 @@ void komodo_passport_iteration() } else { + refsp->RTmask &= ~(1LL << baseid); komodo_statefname(fname,baseid<32?base:(char *)"",(char *)"realtime"); if ( (fp= fopen(fname,"wb")) != 0 ) { @@ -1458,7 +1477,7 @@ void komodo_passport_iteration() refsp->RTbufs[0][2] = 0; } komodo_paxtotal(); - refsp->RTmask = RTmask; + refsp->RTmask |= RTmask; if ( expired == 0 && KOMODO_PASSPORT_INITDONE == 0 ) { KOMODO_PASSPORT_INITDONE = 1; diff --git a/src/komodo_jumblr.h b/src/komodo_jumblr.h new file mode 100755 index 000000000..7f31e18e4 --- /dev/null +++ b/src/komodo_jumblr.h @@ -0,0 +1,772 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +/* + z_exportkey "zaddr" + z_exportwallet "filename" + z_getoperationstatus (["operationid", ... ]) + z_gettotalbalance ( minconf ) + z_importkey "zkey" ( rescan ) + z_importwallet "filename" + z_listaddresses + z_sendmany "fromaddress" [{"address":... ,"amount":..., "memo":""},...] ( minconf ) ( fee ) + */ + +#define JUMBLR_ADDR "RGhxXpXSSBTBm9EvNsXnTQczthMCxHX91t" +#define JUMBLR_BTCADDR "18RmTJe9qMech8siuhYfMtHo8RtcN1obC6" +#define JUMBLR_MAXSECRETADDRS 777 +#define JUMBLR_SYNCHRONIZED_BLOCKS 10 +#define JUMBLR_INCR 9.965 +#define JUMBLR_FEE 0.001 +#define JUMBLR_TXFEE 0.01 +#define SMALLVAL 0.000000000000001 + +#define JUMBLR_ERROR_DUPLICATEDEPOSIT -1 +#define JUMBLR_ERROR_SECRETCANTBEDEPOSIT -2 +#define JUMBLR_ERROR_TOOMANYSECRETS -3 +#define JUMBLR_ERROR_NOTINWALLET -4 + +struct jumblr_item +{ + UT_hash_handle hh; + int64_t amount,fee,txfee; // fee and txfee not really used (yet) + uint32_t spent,pad; + char opid[66],src[128],dest[128],status; +} *Jumblrs; + +char Jumblr_secretaddrs[JUMBLR_MAXSECRETADDRS][64],Jumblr_deposit[64]; +int32_t Jumblr_numsecretaddrs; // if 0 -> run silent mode + +char *jumblr_issuemethod(char *userpass,char *method,char *params,uint16_t port) +{ + cJSON *retjson,*resjson = 0; char *retstr; + if ( (retstr= komodo_issuemethod(userpass,method,params,port)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,(char *)"result") != 0 ) + resjson = jduplicate(jobj(retjson,(char *)"result")); + else if ( jobj(retjson,(char *)"error") != 0 ) + resjson = jduplicate(jobj(retjson,(char *)"error")); + else + { + resjson = cJSON_CreateObject(); + jaddstr(resjson,(char *)"error",(char *)"cant parse return"); + } + free_json(retjson); + } + free(retstr); + } + if ( resjson != 0 ) + return(jprint(resjson,1)); + else return(clonestr((char *)"{\"error\":\"unknown error\"}")); +} + +char *jumblr_importaddress(char *address) +{ + char params[1024]; + sprintf(params,"[\"%s\", \"%s\", false]",address,address); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"importaddress",params,7771)); +} + +char *jumblr_validateaddress(char *addr) +{ + char params[1024]; + sprintf(params,"[\"%s\"]",addr); + printf("validateaddress.%s\n",params); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"validateaddress",params,7771)); +} + +int32_t Jumblr_secretaddrfind(char *searchaddr) +{ + int32_t i; + for (i=0; i 0 ) + { + OS_randombytes((uint8_t *)&r,sizeof(r)); + r %= Jumblr_numsecretaddrs; + safecopy(secretaddr,Jumblr_secretaddrs[r],64); + } + return(r); +} + +int32_t jumblr_addresstype(char *addr) +{ + if ( addr[0] == '"' && addr[strlen(addr)-1] == '"' ) + { + addr[strlen(addr)-1] = 0; + addr++; + } + if ( addr[0] == 'z' && addr[1] == 'c' && strlen(addr) >= 40 ) + return('z'); + else if ( strlen(addr) < 40 ) + return('t'); + printf("strange.(%s)\n",addr); + return(-1); +} + +struct jumblr_item *jumblr_opidfind(char *opid) +{ + struct jumblr_item *ptr; + HASH_FIND(hh,Jumblrs,opid,(int32_t)strlen(opid),ptr); + return(ptr); +} + +struct jumblr_item *jumblr_opidadd(char *opid) +{ + struct jumblr_item *ptr = 0; + if ( opid != 0 && (ptr= jumblr_opidfind(opid)) == 0 ) + { + ptr = (struct jumblr_item *)calloc(1,sizeof(*ptr)); + safecopy(ptr->opid,opid,sizeof(ptr->opid)); + HASH_ADD_KEYPTR(hh,Jumblrs,ptr->opid,(int32_t)strlen(ptr->opid),ptr); + if ( ptr != jumblr_opidfind(opid) ) + printf("jumblr_opidadd.(%s) ERROR, couldnt find after add\n",opid); + } + return(ptr); +} + +char *jumblr_zgetnewaddress() +{ + char params[1024]; + sprintf(params,"[]"); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getnewaddress",params,7771)); +} + +char *jumblr_zlistoperationids() +{ + char params[1024]; + sprintf(params,"[]"); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listoperationids",params,7771)); +} + +char *jumblr_zgetoperationresult(char *opid) +{ + char params[1024]; + sprintf(params,"[[\"%s\"]]",opid); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationresult",params,7771)); +} + +char *jumblr_zgetoperationstatus(char *opid) +{ + char params[1024]; + sprintf(params,"[[\"%s\"]]",opid); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationstatus",params,7771)); +} + +char *jumblr_sendt_to_z(char *taddr,char *zaddr,double amount) +{ + char params[1024]; double fee = ((amount-3*JUMBLR_TXFEE) * JUMBLR_FEE) * 1.5; + if ( jumblr_addresstype(zaddr) != 'z' || jumblr_addresstype(taddr) != 't' ) + return(clonestr((char *)"{\"error\":\"illegal address in t to z\"}")); + sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",taddr,zaddr,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); + printf("t -> z: %s\n",params); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,7771)); +} + +char *jumblr_sendz_to_z(char *zaddrS,char *zaddrD,double amount) +{ + char params[1024]; double fee = (amount-2*JUMBLR_TXFEE) * JUMBLR_FEE; + if ( jumblr_addresstype(zaddrS) != 'z' || jumblr_addresstype(zaddrD) != 'z' ) + return(clonestr((char *)"{\"error\":\"illegal address in z to z\"}")); + //sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddrS,zaddrD,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); + sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddrS,zaddrD,amount-fee-JUMBLR_TXFEE,JUMBLR_TXFEE); + printf("z -> z: %s\n",params); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,7771)); +} + +char *jumblr_sendz_to_t(char *zaddr,char *taddr,double amount) +{ + char params[1024]; double fee = ((amount-JUMBLR_TXFEE) * JUMBLR_FEE) * 1.5; + if ( jumblr_addresstype(zaddr) != 'z' || jumblr_addresstype(taddr) != 't' ) + return(clonestr((char *)"{\"error\":\"illegal address in z to t\"}")); + sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddr,taddr,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); + printf("z -> t: %s\n",params); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,7771)); +} + +char *jumblr_zlistaddresses() +{ + char params[1024]; + sprintf(params,"[]"); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listaddresses",params,7771)); +} + +char *jumblr_zlistreceivedbyaddress(char *addr) +{ + char params[1024]; + sprintf(params,"[\"%s\", 1]",addr); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listreceivedbyaddress",params,7771)); +} + +char *jumblr_getreceivedbyaddress(char *addr) +{ + char params[1024]; + sprintf(params,"[\"%s\", 1]",addr); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"getreceivedbyaddress",params,7771)); +} + +char *jumblr_importprivkey(char *wifstr) +{ + char params[1024]; + sprintf(params,"[\"%s\", \"\", false]",wifstr); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"importprivkey",params,7771)); +} + +char *jumblr_zgetbalance(char *addr) +{ + char params[1024]; + sprintf(params,"[\"%s\", 1]",addr); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getbalance",params,7771)); +} + +char *jumblr_listunspent(char *coinaddr) +{ + char params[1024]; + sprintf(params,"[1, 99999999, [\"%s\"]]",coinaddr); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"listunspent",params,7771)); +} + +char *jumblr_gettransaction(char *txidstr) +{ + char params[1024]; + sprintf(params,"[\"%s\", 1]",txidstr); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"getrawtransaction",params,7771)); +} + +int32_t jumblr_numvins(bits256 txid) +{ + char txidstr[65],params[1024],*retstr; cJSON *retjson,*vins; int32_t n,numvins = -1; + bits256_str(txidstr,txid); + if ( (retstr= jumblr_gettransaction(txidstr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,(char *)"vin") != 0 && ((vins= jarray(&n,retjson,(char *)"vin")) == 0 || n == 0) ) + { + numvins = n; + //printf("numvins.%d\n",n); + } //else printf("no vin.(%s)\n",retstr); + free_json(retjson); + } + free(retstr); + } + return(numvins); +} + +int64_t jumblr_receivedby(char *addr) +{ + char *retstr; int64_t total = 0; + if ( (retstr= jumblr_getreceivedbyaddress(addr)) != 0 ) + { + total = atof(retstr) * SATOSHIDEN; + free(retstr); + } + return(total); +} + +int64_t jumblr_balance(char *addr) +{ + char *retstr; double val; int64_t balance = 0; //cJSON *retjson; int32_t i,n; + /*if ( jumblr_addresstype(addr) == 't' ) + { + if ( (retstr= jumblr_listunspent(addr)) != 0 ) + { + //printf("jumblr.[%s].(%s)\n","KMD",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(retjson)) > 0 && is_cJSON_Array(retjson) != 0 ) + for (i=0; i SMALLVAL ) + balance = val * SATOSHIDEN; + free(retstr); + } + return(balance); +} + +int32_t jumblr_itemset(struct jumblr_item *ptr,cJSON *item,char *status) +{ + cJSON *params,*amounts,*dest; char *from,*addr; int32_t i,n; int64_t amount; + /*"params" : { + "fromaddress" : "RDhEGYScNQYetCyG75Kf8Fg61UWPdwc1C5", + "amounts" : [ + { + "address" : "zc9s3UdkDFTnnwHrMCr1vYy2WmkjhmTxXNiqC42s7BjeKBVUwk766TTSsrRPKfnX31Bbu8wbrTqnjDqskYGwx48FZMPHvft", + "amount" : 3.00000000 + } + ], + "minconf" : 1, + "fee" : 0.00010000 + }*/ + if ( (params= jobj(item,(char *)"params")) != 0 ) + { + //printf("params.(%s)\n",jprint(params,0)); + if ( (from= jstr(params,(char *)"fromaddress")) != 0 ) + { + safecopy(ptr->src,from,sizeof(ptr->src)); + } + if ( (amounts= jarray(&n,params,(char *)"amounts")) != 0 ) + { + for (i=0; i 0 ) + { + if ( strcmp(addr,JUMBLR_ADDR) == 0 ) + ptr->fee = amount; + else + { + ptr->amount = amount; + safecopy(ptr->dest,addr,sizeof(ptr->dest)); + } + } + } + } + ptr->txfee = jdouble(params,(char *)"fee") * SATOSHIDEN; + } + return(1); +} + +void jumblr_opidupdate(struct jumblr_item *ptr) +{ + char *retstr,*status; cJSON *retjson,*item; + if ( ptr->status == 0 ) + { + if ( (retstr= jumblr_zgetoperationstatus(ptr->opid)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( cJSON_GetArraySize(retjson) == 1 && is_cJSON_Array(retjson) != 0 ) + { + item = jitem(retjson,0); + //printf("%s\n",jprint(item,0)); + if ( (status= jstr(item,(char *)"status")) != 0 ) + { + if ( strcmp(status,(char *)"success") == 0 ) + { + ptr->status = jumblr_itemset(ptr,item,status); + if ( (jumblr_addresstype(ptr->src) == 't' && jumblr_addresstype(ptr->src) == 'z' && strcmp(ptr->src,Jumblr_deposit) != 0) || (jumblr_addresstype(ptr->src) == 'z' && jumblr_addresstype(ptr->src) == 't' && Jumblr_secretaddrfind(ptr->dest) < 0) ) + { + printf("a non-jumblr t->z pruned\n"); + free(jumblr_zgetoperationresult(ptr->opid)); + ptr->status = -1; + } + + } + else if ( strcmp(status,(char *)"failed") == 0 ) + { + printf("jumblr_opidupdate %s failed\n",ptr->opid); + free(jumblr_zgetoperationresult(ptr->opid)); + ptr->status = -1; + } + } + } + free_json(retjson); + } + free(retstr); + } + } +} + +void jumblr_prune(struct jumblr_item *ptr) +{ + struct jumblr_item *tmp; char oldsrc[128]; int32_t flag = 1; + if ( is_hexstr(ptr->opid,0) == 64 ) + return; + printf("jumblr_prune %s\n",ptr->opid); + strcpy(oldsrc,ptr->src); + free(jumblr_zgetoperationresult(ptr->opid)); + while ( flag != 0 ) + { + flag = 0; + HASH_ITER(hh,Jumblrs,ptr,tmp) + { + if ( strcmp(oldsrc,ptr->dest) == 0 ) + { + if ( is_hexstr(ptr->opid,0) != 64 ) + { + printf("jumblr_prune %s (%s -> %s) matched oldsrc\n",ptr->opid,ptr->src,ptr->dest); + free(jumblr_zgetoperationresult(ptr->opid)); + strcpy(oldsrc,ptr->src); + flag = 1; + break; + } + } + } + } +} + +void jumblr_zaddrinit(char *zaddr) +{ + struct jumblr_item *ptr; char *retstr,*totalstr; cJSON *item,*array; double total; bits256 txid; char txidstr[65],t_z,z_z; + if ( (totalstr= jumblr_zgetbalance(zaddr)) != 0 ) + { + if ( (total= atof(totalstr)) > SMALLVAL ) + { + if ( (retstr= jumblr_zlistreceivedbyaddress(zaddr)) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + t_z = z_z = 0; + if ( cJSON_GetArraySize(array) == 1 && is_cJSON_Array(array) != 0 ) + { + item = jitem(array,0); + if ( (uint64_t)((total+0.0000000049) * SATOSHIDEN) == (uint64_t)((jdouble(item,(char *)"amount")+0.0000000049) * SATOSHIDEN) ) + { + txid = jbits256(item,(char *)"txid"); + bits256_str(txidstr,txid); + if ( (ptr= jumblr_opidadd(txidstr)) != 0 ) + { + ptr->amount = (total * SATOSHIDEN); + ptr->status = 1; + strcpy(ptr->dest,zaddr); + if ( jumblr_addresstype(ptr->dest) != 'z' ) + printf("error setting dest type to Z: %s\n",jprint(item,0)); + if ( jumblr_numvins(txid) == 0 ) + { + z_z = 1; + strcpy(ptr->src,zaddr); + ptr->src[3] = '0'; + ptr->src[4] = '0'; + ptr->src[5] = '0'; + if ( jumblr_addresstype(ptr->src) != 'z' ) + printf("error setting address type to Z: %s\n",jprint(item,0)); + } + else + { + t_z = 1; + strcpy(ptr->src,"taddr"); + if ( jumblr_addresstype(ptr->src) != 't' ) + printf("error setting address type to T: %s\n",jprint(item,0)); + } + printf("%s %s %.8f t_z.%d z_z.%d\n",zaddr,txidstr,total,t_z,z_z); // cant be z->t from spend + } + } else printf("mismatched %s %s total %.8f vs %.8f -> %lld\n",zaddr,totalstr,dstr(SATOSHIDEN * total),dstr(SATOSHIDEN * jdouble(item,(char *)"amount")),(long long)((uint64_t)(total * SATOSHIDEN) - (uint64_t)(jdouble(item,(char *)"amount") * SATOSHIDEN))); + } + free_json(array); + } + free(retstr); + } + } + free(totalstr); + } +} + +void jumblr_opidsupdate() +{ + char *retstr; cJSON *array; int32_t i,n; struct jumblr_item *ptr; + if ( (retstr= jumblr_zlistoperationids()) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 ) + { + //printf("%s -> n%d\n",retstr,n); + for (i=0; istatus == 0 ) + jumblr_opidupdate(ptr); + //printf("%d: %s -> %s %.8f\n",ptr->status,ptr->src,ptr->dest,dstr(ptr->amount)); + if ( jumblr_addresstype(ptr->src) == 'z' && jumblr_addresstype(ptr->dest) == 't' ) + jumblr_prune(ptr); + } + } + } + free_json(array); + } + free(retstr); + } +} + +uint64_t jumblr_increment(uint8_t r,int32_t height,uint64_t total,uint64_t biggest,uint64_t medium, uint64_t smallest) +{ + int32_t i,n; uint64_t incrs[1000],remains = total; + height /= JUMBLR_SYNCHRONIZED_BLOCKS; + if ( (height % JUMBLR_SYNCHRONIZED_BLOCKS) == 0 || total >= 100*biggest ) + { + if ( total >= biggest ) + return(biggest); + else if ( total >= medium ) + return(medium); + else if ( total >= smallest ) + return(smallest); + else return(0); + } + else + { + n = 0; + while ( remains > smallest && n < sizeof(incrs)/sizeof(*incrs) ) + { + if ( remains >= biggest ) + incrs[n] = biggest; + else if ( remains >= medium ) + incrs[n] = medium; + else if ( remains >= smallest ) + incrs[n] = smallest; + else break; + remains -= incrs[n]; + n++; + } + if ( n > 0 ) + { + r %= n; + for (i=0; i %.8f\n",n,r,dstr(incrs[r])); + return(incrs[r]); + } + } + return(0); +} + +void jumblr_iteration() +{ + static int32_t lastheight; static uint32_t lasttime; + char *zaddr,*addr,*retstr,secretaddr[64]; cJSON *array; int32_t i,iter,height,counter,chosen_one,n; uint64_t smallest,medium,biggest,amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint16_t r,s; + if ( lasttime == 0 ) + { + if ( (retstr= jumblr_zlistaddresses()) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 ) + { + for (i=0; inHeight; + if ( time(NULL) < lasttime+40 ) + return; + lasttime = (uint32_t)time(NULL); + if ( lastheight == height ) + return; + lastheight = height; + if ( (height % JUMBLR_SYNCHRONIZED_BLOCKS) != JUMBLR_SYNCHRONIZED_BLOCKS-3 ) + return; + fee = JUMBLR_INCR * JUMBLR_FEE; + smallest = SATOSHIDEN * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE); + medium = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE); + biggest = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*777 + 3*JUMBLR_TXFEE); + OS_randombytes((uint8_t *)&r,sizeof(r)); + s = (r % 3); + printf("jumblr_iteration r.%u s.%u\n",r,s); + switch ( s ) + { + case 0: // t -> z + default: + if ( Jumblr_deposit[0] != 0 && (total= jumblr_balance(Jumblr_deposit)) >= smallest ) + { + if ( (zaddr= jumblr_zgetnewaddress()) != 0 ) + { + if ( zaddr[0] == '"' && zaddr[strlen(zaddr)-1] == '"' ) + { + zaddr[strlen(zaddr)-1] = 0; + addr = zaddr+1; + } else addr = zaddr; + amount = jumblr_increment(r/3,height,total,biggest,medium,smallest); + /* + amount = 0; + if ( (height % (JUMBLR_SYNCHRONIZED_BLOCKS*JUMBLR_SYNCHRONIZED_BLOCKS)) == 0 && total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE) ) + amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE); + else if ( (r & 3) == 0 && total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE) ) + amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE); + else amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE);*/ + if ( amount > 0 && (retstr= jumblr_sendt_to_z(Jumblr_deposit,addr,dstr(amount))) != 0 ) + { + printf("sendt_to_z.(%s)\n",retstr); + free(retstr); + } + free(zaddr); + } else printf("no zaddr from jumblr_zgetnewaddress\n"); + } + else if ( Jumblr_deposit[0] != 0 ) + printf("%s total %.8f vs %.8f\n",Jumblr_deposit,dstr(total),(JUMBLR_INCR + 3*(fee+JUMBLR_TXFEE))); + break; + case 1: // z -> z + jumblr_opidsupdate(); + chosen_one = -1; + for (iter=counter=0; iter<2; iter++) + { + counter = n = 0; + HASH_ITER(hh,Jumblrs,ptr,tmp) + { + if ( ptr->spent == 0 && ptr->status > 0 && jumblr_addresstype(ptr->src) == 't' && jumblr_addresstype(ptr->dest) == 'z' ) + { + if ( (total= jumblr_balance(ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) + { + if ( iter == 1 && counter == chosen_one ) + { + if ( (zaddr= jumblr_zgetnewaddress()) != 0 ) + { + if ( zaddr[0] == '"' && zaddr[strlen(zaddr)-1] == '"' ) + { + zaddr[strlen(zaddr)-1] = 0; + addr = zaddr+1; + } else addr = zaddr; + if ( (retstr= jumblr_sendz_to_z(ptr->dest,addr,dstr(total))) != 0 ) + { + printf("n.%d counter.%d chosen_one.%d send z_to_z.(%s)\n",n,counter,chosen_one,retstr); + free(retstr); + } + ptr->spent = (uint32_t)time(NULL); + free(zaddr); + break; + } + } + counter++; + } + } + n++; + } + if ( counter == 0 ) + break; + if ( iter == 0 ) + { + OS_randombytes((uint8_t *)&chosen_one,sizeof(chosen_one)); + if ( chosen_one < 0 ) + chosen_one = -chosen_one; + chosen_one %= counter; + printf("jumblr z->z chosen_one.%d of %d, from %d\n",chosen_one,counter,n); + } + } + break; + case 2: // z -> t + if ( Jumblr_numsecretaddrs > 0 ) + { + jumblr_opidsupdate(); + chosen_one = -1; + for (iter=0; iter<2; iter++) + { + counter = n = 0; + HASH_ITER(hh,Jumblrs,ptr,tmp) + { + //printf("status.%d %c %c %.8f\n",ptr->status,jumblr_addresstype(ptr->src),jumblr_addresstype(ptr->dest),dstr(ptr->amount)); + if ( ptr->spent == 0 && ptr->status > 0 && jumblr_addresstype(ptr->src) == 'z' && jumblr_addresstype(ptr->dest) == 'z' ) + { + if ( (total= jumblr_balance(ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) + { + if ( iter == 1 && counter == chosen_one ) + { + Jumblr_secretaddr(secretaddr); + if ( (retstr= jumblr_sendz_to_t(ptr->dest,secretaddr,dstr(total))) != 0 ) + { + printf("%s send z_to_t.(%s)\n",secretaddr,retstr); + free(retstr); + } else printf("null return from jumblr_sendz_to_t\n"); + ptr->spent = (uint32_t)time(NULL); + break; + } + counter++; + } //else printf("z->t spent.%u total %.8f error\n",ptr->spent,dstr(total)); + } + n++; + } + if ( counter == 0 ) + break; + if ( iter == 0 ) + { + OS_randombytes((uint8_t *)&chosen_one,sizeof(chosen_one)); + if ( chosen_one < 0 ) + chosen_one = -chosen_one; + chosen_one %= counter; + printf("jumblr z->t chosen_one.%d of %d, from %d\n",chosen_one,counter,n); + } //else printf("n.%d counter.%d chosen.%d\n",n,counter,chosen_one); + } + } + break; + } +} + diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 81543a064..7cf081638 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -281,6 +281,7 @@ bits256 bits256_doublesha256(char *deprecated,uint8_t *data,int32_t datalen) return(hash); } + // rmd160: the five basic functions F(), G() and H() #define F(x, y, z) ((x) ^ (y) ^ (z)) #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) @@ -657,6 +658,22 @@ void calc_rmd160(char deprecated[41],uint8_t buf[20],uint8_t *msg,int32_t len) rmd160_vprocess(&md,msg,len); rmd160_vdone(&md, buf); } +#undef F +#undef G +#undef H +#undef I +#undef J +#undef ROLc +#undef FF +#undef GG +#undef HH +#undef II +#undef JJ +#undef FFF +#undef GGG +#undef HHH +#undef III +#undef JJJ static const uint32_t crc32_tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, diff --git a/src/miner.cpp b/src/miner.cpp index 3de85e5cf..1b5722316 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -798,7 +798,9 @@ void static BitcoinMiner() if ( gpucount > j/2 ) { double delta; - i = ((Mining_height + notaryid) % 64); + if ( notaryid < 0 ) + i = (rand() % 64); + else i = ((Mining_height + notaryid) % 64); delta = sqrt((double)gpucount - j/2) / 2.; roundrobin_delay += ((delta * i) / 64) - delta; //fprintf(stderr,"delta.%f %f %f\n",delta,(double)(gpucount - j/3) / 2,(delta * i) / 64); @@ -860,7 +862,7 @@ void static BitcoinMiner() // fprintf(stderr," missed target\n"); return false; } - if ( ASSETCHAINS_SYMBOL[0] == 0 && Mining_start != 0 && time(NULL) < Mining_start+roundrobin_delay ) + if ( /*ASSETCHAINS_SYMBOL[0] == 0 &&*/ Mining_start != 0 && time(NULL) < Mining_start+roundrobin_delay ) { //printf("Round robin diff sleep %d\n",(int32_t)(Mining_start+roundrobin_delay-time(NULL))); int32_t nseconds = Mining_start+roundrobin_delay-time(NULL); @@ -869,7 +871,9 @@ void static BitcoinMiner() MilliSleep((rand() % 1700) + 1); } else if ( ASSETCHAINS_SYMBOL[0] != 0 ) - sleep(3); + { + sleep(rand() % 30); + } KOMODO_CHOSEN_ONE = 1; // Found a solution SetThreadPriority(THREAD_PRIORITY_NORMAL); diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index 17cac1ce6..d4965a9b5 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -55,11 +55,14 @@ void TxConfirmStats::ClearCurrent(unsigned int nBlockHeight) unsigned int TxConfirmStats::FindBucketIndex(double val) { + extern char ASSETCHAINS_SYMBOL[]; auto it = bucketMap.lower_bound(val); //assert(it != bucketMap.end()); if ( it != bucketMap.end() ) { - fprintf(stderr,"FindBucketIndex violation: from val %f\n",val); + static uint32_t counter; + if ( counter++ < 10 ) + fprintf(stderr,"%s FindBucketIndex violation: from val %f\n",ASSETCHAINS_SYMBOL,val); } return it->second; } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 037479ca4..a2e73a929 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -708,7 +708,7 @@ UniValue paxprice(const UniValue& params, bool fHelp) height = chainActive.Tip()->nHeight; else height = atoi(params[2].get_str().c_str()); //if ( params.size() == 3 || (basevolume= COIN * atof(params[3].get_str().c_str())) == 0 ) - basevolume = 1; + basevolume = 100000; relvolume = komodo_paxprice(&seed,height,(char *)base.c_str(),(char *)rel.c_str(),basevolume); ret.push_back(Pair("base", base)); ret.push_back(Pair("rel", rel)); diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index f6a78ce3d..42307470f 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -41,6 +41,8 @@ using namespace std; * Or alternatively, create a specific query method for the information. **/ +int32_t Jumblr_depositaddradd(char *depositaddr); +int32_t Jumblr_secretaddradd(char *secretaddr); uint64_t komodo_interestsum(); int32_t komodo_longestchain(); int32_t komodo_notarized_height(uint256 *hashp,uint256 *txidp); @@ -48,7 +50,7 @@ int32_t komodo_whoami(char *pubkeystr,int32_t height); extern int32_t KOMODO_LASTMINED; extern char ASSETCHAINS_SYMBOL[]; int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp); -#define KOMODO_VERSION "0.1.0" +#define KOMODO_VERSION "0.1.1" UniValue getinfo(const UniValue& params, bool fHelp) { @@ -188,6 +190,40 @@ public: }; #endif +UniValue jumblr_deposit(const UniValue& params, bool fHelp) +{ + int32_t retval; UniValue result(UniValue::VOBJ); + if (fHelp || params.size() != 1) + throw runtime_error("jumblr_deposit \"depositaddress\"\n"); + CBitcoinAddress address(params[0].get_str()); + bool isValid = address.IsValid(); + if ( isValid != 0 ) + { + string addr = params[0].get_str(); + if ( (retval= Jumblr_depositaddradd((char *)addr.c_str())) >= 0 ) + result.push_back(Pair("result", retval)); + else result.push_back(Pair("error", retval)); + } else result.push_back(Pair("error", "invalid address")); + return(result); +} + +UniValue jumblr_secret(const UniValue& params, bool fHelp) +{ + int32_t retval; UniValue result(UniValue::VOBJ); + if (fHelp || params.size() != 1) + throw runtime_error("jumblr_secret \"secretaddress\"\n"); + CBitcoinAddress address(params[0].get_str()); + bool isValid = address.IsValid(); + if ( isValid != 0 ) + { + string addr = params[0].get_str(); + retval = Jumblr_secretaddradd((char *)addr.c_str()); + result.push_back(Pair("result", "success")); + result.push_back(Pair("num", retval)); + } else result.push_back(Pair("error", "invalid address")); + return(result); +} + UniValue validateaddress(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 4749cfdc4..518ba4693 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -336,6 +336,8 @@ static const CRPCCommand vRPCCommands[] = { "util", "estimatefee", &estimatefee, true }, { "util", "estimatepriority", &estimatepriority, true }, { "util", "z_validateaddress", &z_validateaddress, true }, /* uses wallet if enabled */ + { "util", "jumblr_deposit", &jumblr_deposit, true }, + { "util", "jumblr_secret", &jumblr_secret, true }, /* Not shown in help */ { "hidden", "invalidateblock", &invalidateblock, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index f1eacb7bb..ecf7b0573 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -246,6 +246,9 @@ extern UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp); extern UniValue zc_raw_receive(const UniValue& params, bool fHelp); extern UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp); +extern UniValue jumblr_deposit(const UniValue& params, bool fHelp); +extern UniValue jumblr_secret(const UniValue& params, bool fHelp); + extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rcprawtransaction.cpp extern UniValue listunspent(const UniValue& params, bool fHelp); extern UniValue lockunspent(const UniValue& params, bool fHelp); diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index bbb318b0f..e1fcd8829 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -1048,14 +1048,14 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) BOOST_CHECK(tx.vout.size() == 0); CAmount amount = 123.456; - proxy.add_taddr_change_output_to_tx(amount); + proxy.add_taddr_change_output_to_tx(0,amount); tx = proxy.getTx(); BOOST_CHECK(tx.vout.size() == 1); CTxOut out = tx.vout[0]; BOOST_CHECK_EQUAL(out.nValue, amount); amount = 1.111; - proxy.add_taddr_change_output_to_tx(amount); + proxy.add_taddr_change_output_to_tx(0,amount); tx = proxy.getTx(); BOOST_CHECK(tx.vout.size() == 2); out = tx.vout[1]; diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 18e25bc97..5befe9fb1 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -292,6 +292,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { CTxIn in(COutPoint(txid, vout)); rawTx.vin.push_back(in); } + rawTx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 tx_ = CTransaction(rawTx); } @@ -318,7 +319,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { CAmount change = funds - fundsSpent; if (change > 0) { - add_taddr_change_output_to_tx(change); + add_taddr_change_output_to_tx(0,change); LogPrint("zrpc", "%s: transparent change in transaction output (amount=%s)\n", getId(), @@ -341,6 +342,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { mtx.nVersion = 2; crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_); mtx.joinSplitPubKey = joinSplitPubKey_; + mtx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 tx_ = CTransaction(mtx); // Copy zinputs and zoutputs to more flexible containers @@ -395,7 +397,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { "allow any change as there is currently no way to specify a change address " "in z_sendmany.", FormatMoney(change))); } else { - add_taddr_change_output_to_tx(change); + add_taddr_change_output_to_tx(&fromtaddr_,change); LogPrint("zrpc", "%s: transparent change in transaction output (amount=%s)\n", getId(), FormatMoney(change) @@ -1098,26 +1100,33 @@ void AsyncRPCOperation_sendmany::add_taddr_outputs_to_tx() { CTxOut out(nAmount, scriptPubKey); rawTx.vout.push_back(out); } - + rawTx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 tx_ = CTransaction(rawTx); } -void AsyncRPCOperation_sendmany::add_taddr_change_output_to_tx(CAmount amount) { +void AsyncRPCOperation_sendmany::add_taddr_change_output_to_tx(CBitcoinAddress *fromaddress,CAmount amount) { LOCK2(cs_main, pwalletMain->cs_wallet); EnsureWalletIsUnlocked(); + CScript scriptPubKey; CReserveKey keyChange(pwalletMain); CPubKey vchPubKey; - bool ret = keyChange.GetReservedKey(vchPubKey); - if (!ret) { - throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Could not generate a taddr to use as a change address"); // should never fail, as we just unlocked + if ( fromaddress != 0 ) + scriptPubKey = GetScriptForDestination(fromaddress->Get()); + else + { + bool ret = keyChange.GetReservedKey(vchPubKey); + if (!ret) { + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Could not generate a taddr to use as a change address"); // should never fail, as we just unlocked + } + scriptPubKey = GetScriptForDestination(vchPubKey.GetID()); } - CScript scriptPubKey = GetScriptForDestination(vchPubKey.GetID()); CTxOut out(amount, scriptPubKey); CMutableTransaction rawTx(tx_); rawTx.vout.push_back(out); + rawTx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 tx_ = CTransaction(rawTx); } diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 6fac61160..c69fce4c9 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -92,7 +92,7 @@ private: CTransaction tx_; - void add_taddr_change_output_to_tx(CAmount amount); + void add_taddr_change_output_to_tx(CBitcoinAddress *fromaddress,CAmount amount); void add_taddr_outputs_to_tx(); bool find_unspent_notes(); bool find_utxos(bool fAcceptCoinbase); @@ -134,7 +134,7 @@ public: // Delegated methods void add_taddr_change_output_to_tx(CAmount amount) { - delegate->add_taddr_change_output_to_tx(amount); + delegate->add_taddr_change_output_to_tx(0,amount); } void add_taddr_outputs_to_tx() {