Merge pull request #45 from jl777/dPoW

DPoW block 60000
This commit is contained in:
jl777
2016-11-08 09:05:01 -03:00
committed by GitHub
25 changed files with 1032 additions and 376 deletions

2
.gitignore vendored
View File

@@ -121,3 +121,5 @@ qa/pull-tester/test.*/*
/doc/doxygen/ /doc/doxygen/
libzcashconsensus.pc libzcashconsensus.pc
src/fiat/-usd

View File

@@ -1,32 +1,35 @@
./komodod -ac_name=USD -addnode=78.47.196.146 & source pubkey.txt
./komodod -ac_name=EUR -addnode=78.47.196.146 & echo $pubkey
./komodod -ac_name=JPY -addnode=78.47.196.146 &
./komodod -ac_name=GBP -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=USD -addnode=78.47.196.146 &
./komodod -ac_name=AUD -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=EUR -addnode=78.47.196.146 &
./komodod -ac_name=CAD -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=JPY -addnode=78.47.196.146 &
./komodod -ac_name=CHF -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=GBP -addnode=78.47.196.146 &
./komodod -ac_name=NZD -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=AUD -addnode=78.47.196.146 &
./komodod -ac_name=CNY -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=CAD -addnode=78.47.196.146 &
./komodod -ac_name=RUB -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=CHF -addnode=78.47.196.146 &
./komodod -ac_name=MXN -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=NZD -addnode=78.47.196.146 &
./komodod -ac_name=BRL -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=CNY -addnode=78.47.196.146 &
./komodod -ac_name=INR -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=RUB -addnode=78.47.196.146 &
./komodod -ac_name=HKD -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=MXN -addnode=78.47.196.146 &
./komodod -ac_name=TRY -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=BRL -addnode=78.47.196.146 &
./komodod -ac_name=ZAR -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=INR -addnode=78.47.196.146 &
./komodod -ac_name=PLN -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=HKD -addnode=78.47.196.146 &
./komodod -ac_name=NOK -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=TRY -addnode=78.47.196.146 &
./komodod -ac_name=SEK -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=ZAR -addnode=78.47.196.146 &
./komodod -ac_name=DKK -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=PLN -addnode=78.47.196.146 &
./komodod -ac_name=CZK -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=NOK -addnode=78.47.196.146 &
./komodod -ac_name=HUF -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=SEK -addnode=78.47.196.146 &
./komodod -ac_name=ILS -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=DKK -addnode=78.47.196.146 &
./komodod -ac_name=KRW -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=CZK -addnode=78.47.196.146 &
./komodod -ac_name=MYR -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=HUF -addnode=78.47.196.146 &
./komodod -ac_name=PHP -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=ILS -addnode=78.47.196.146 &
./komodod -ac_name=RON -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=KRW -addnode=78.47.196.146 &
./komodod -ac_name=SGD -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=MYR -addnode=78.47.196.146 &
./komodod -ac_name=THB -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=PHP -addnode=78.47.196.146 &
./komodod -ac_name=BGN -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=RON -addnode=78.47.196.146 &
./komodod -ac_name=IDR -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=SGD -addnode=78.47.196.146 &
./komodod -ac_name=HRK -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=THB -addnode=78.47.196.146 &
./komodod -pubkey=$pubkey -ac_name=BGN -addnode=78.47.196.146 &
./komodod -pubkey=$pubkey -ac_name=IDR -addnode=78.47.196.146 &
./komodod -pubkey=$pubkey -ac_name=HRK -addnode=78.47.196.146 &

View File

@@ -34,6 +34,8 @@
static bool fDaemon; static bool fDaemon;
extern char ASSETCHAINS_SYMBOL[16]; extern char ASSETCHAINS_SYMBOL[16];
void komodo_gateway_iteration(char *symbol); void komodo_gateway_iteration(char *symbol);
void komodo_iteration(char *symbol);
int32_t komodo_is_issuer();
void WaitForShutdown(boost::thread_group* threadGroup) void WaitForShutdown(boost::thread_group* threadGroup)
{ {
@@ -42,8 +44,10 @@ void WaitForShutdown(boost::thread_group* threadGroup)
while (!fShutdown) while (!fShutdown)
{ {
MilliSleep(2000); MilliSleep(2000);
if ( ASSETCHAINS_SYMBOL[0] != 0 ) if ( komodo_is_issuer() != 0 )
komodo_gateway_iteration(ASSETCHAINS_SYMBOL); komodo_gateway_iteration(ASSETCHAINS_SYMBOL);
else komodo_iteration((char *)"EUR");
fShutdown = ShutdownRequested(); fShutdown = ShutdownRequested();
} }
if (threadGroup) if (threadGroup)
@@ -59,6 +63,7 @@ void WaitForShutdown(boost::thread_group* threadGroup)
// //
extern int32_t IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,ASSETCHAIN_INIT; extern int32_t IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,ASSETCHAIN_INIT;
extern std::string NOTARY_PUBKEY; extern std::string NOTARY_PUBKEY;
int32_t komodo_is_issuer();
bool AppInit(int argc, char* argv[]) bool AppInit(int argc, char* argv[])
{ {
@@ -97,10 +102,12 @@ bool AppInit(int argc, char* argv[])
try try
{ {
void komodo_args(); void komodo_args();
fprintf(stderr,"call komodo_args\n");
komodo_args(); komodo_args();
fprintf(stderr,"call komodo_args NOTARY_PUBKEY.(%s)\n",NOTARY_PUBKEY.c_str());
while ( ASSETCHAIN_INIT == 0 ) while ( ASSETCHAIN_INIT == 0 )
{ {
if ( komodo_is_issuer() != 0 )
komodo_gateway_iteration(ASSETCHAINS_SYMBOL);
sleep(1); sleep(1);
} }
if (!boost::filesystem::is_directory(GetDataDir(false))) if (!boost::filesystem::is_directory(GetDataDir(false)))

View File

@@ -137,7 +137,7 @@ void *chainparams_commandline(void *ptr)
{ {
sleep(1); sleep(1);
} }
fprintf(stderr,">>>>>>>> port.%u\n",ASSETCHAINS_PORT); //fprintf(stderr,">>>>>>>> port.%u\n",ASSETCHAINS_PORT);
if ( ASSETCHAINS_SYMBOL[0] != 0 ) if ( ASSETCHAINS_SYMBOL[0] != 0 )
{ {
mainParams.SetDefaultPort(ASSETCHAINS_PORT); mainParams.SetDefaultPort(ASSETCHAINS_PORT);

View File

@@ -384,6 +384,7 @@ const CScript &CCoinsViewCache::GetSpendFor(const CTxIn& input) const
} }
uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
extern char ASSETCHAINS_SYMBOL[16];
CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTransaction& tx,uint32_t tiptime) const CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTransaction& tx,uint32_t tiptime) const
{ {
@@ -398,7 +399,8 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTr
nResult += value; nResult += value;
interest = komodo_interest(nHeight,value,tx.nLockTime,tiptime); interest = komodo_interest(nHeight,value,tx.nLockTime,tiptime);
#ifdef KOMODO_ENABLE_INTEREST #ifdef KOMODO_ENABLE_INTEREST
nResult += interest; if ( ASSETCHAINS_SYMBOL[0] == 0 && nHeight >= 60000 )
nResult += interest;
#endif #endif
(*interestp) += interest; (*interestp) += interest;
} }

3
src/fiat/_usd Executable file
View File

@@ -0,0 +1,3 @@
./komodo-cli -ac_name=-USD $1 $2 $3 $4

View File

@@ -1493,7 +1493,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
// Generate coins in the background // Generate coins in the background
if (pwalletMain) if (pwalletMain)
GenerateBitcoins(GetBoolArg("-gen", true), pwalletMain, GetArg("-genproclimit", 1)); GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1));
#endif #endif
// ********************************************************* Step 11: finished // ********************************************************* Step 11: finished

View File

@@ -17,6 +17,8 @@
#define H_KOMODO_H #define H_KOMODO_H
// Todo: handle reorg: clear all entries above reorged height // Todo: handle reorg: clear all entries above reorged height
// smooth consensus price
//
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@@ -24,14 +26,16 @@
#include <ctype.h> #include <ctype.h>
void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout); void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout);
void komodo_init(); void komodo_init(int32_t height);
int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp); int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp);
char *komodo_issuemethod(char *method,char *params,uint16_t port); char *komodo_issuemethod(char *method,char *params,uint16_t port);
#define GENESIS_NBITS 0x1f00ffff #define GENESIS_NBITS 0x1f00ffff
#define KOMODO_MINRATIFY 7
#include "komodo_globals.h" #include "komodo_globals.h"
#include "komodo_utils.h" #include "komodo_utils.h"
queue_t DepositsQ,PendingsQ; //queue_t DepositsQ,PendingsQ;
#include "cJSON.c" #include "cJSON.c"
#include "komodo_bitcoind.h" #include "komodo_bitcoind.h"
@@ -148,7 +152,7 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar
} }
if ( height <= 0 ) if ( height <= 0 )
{ {
printf("early return: stateupdate height.%d\n",height); //printf("early return: stateupdate height.%d\n",height);
return; return;
} }
if ( fp != 0 ) // write out funcid, height, other fields, call side effect function if ( fp != 0 ) // write out funcid, height, other fields, call side effect function
@@ -300,59 +304,75 @@ int32_t komodo_voutupdate(int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,
opretlen = scriptbuf[len++]; opretlen = scriptbuf[len++];
opretlen = (opretlen << 8) + scriptbuf[len++]; opretlen = (opretlen << 8) + scriptbuf[len++];
} }
//for (k=0; k<scriptlen; k++) if ( j == 1 && opretlen >= 32*2+4 && strcmp(ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 )
// printf("%02x",scriptbuf[k]);
//printf(" <- script ht.%d i.%d j.%d value %.8f\n",height,i,j,dstr(value));
if ( j == 1 && opretlen >= 32*2+4 && strcmp(KOMODO_SOURCE,(char *)&scriptbuf[len+32*2+4]) == 0 )
{ {
len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&kmdtxid); len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&kmdtxid);
len += iguana_rwnum(0,&scriptbuf[len],4,(uint8_t *)notarizedheightp); len += iguana_rwnum(0,&scriptbuf[len],4,(uint8_t *)notarizedheightp);
len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&desttxid); len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&desttxid);
if ( *notarizedheightp > NOTARIZED_HEIGHT && *notarizedheightp < height ) if ( *notarizedheightp > NOTARIZED_HEIGHT && *notarizedheightp < height )
{ {
printf("ht.%d NOTARIZED.%d KMD.%s BTCTXID.%s (%s)\n",height,*notarizedheightp,kmdtxid.ToString().c_str(),desttxid.ToString().c_str(),(char *)&scriptbuf[len]); printf("ht.%d NOTARIZED.%d %s.%s %sTXID.%s (%s)\n",height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,kmdtxid.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),(char *)&scriptbuf[len]);
NOTARIZED_HEIGHT = *notarizedheightp; NOTARIZED_HEIGHT = *notarizedheightp;
NOTARIZED_HASH = kmdtxid; NOTARIZED_HASH = kmdtxid;
NOTARIZED_DESTTXID = desttxid; NOTARIZED_DESTTXID = desttxid;
komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0); komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0);
} else printf("reject ht.%d NOTARIZED.%d %s.%s DESTTXID.%s (%s)\n",height,*notarizedheightp,KOMODO_SOURCE,kmdtxid.ToString().c_str(),desttxid.ToString().c_str(),(char *)&scriptbuf[len]); } else printf("reject ht.%d NOTARIZED.%d %s.%s DESTTXID.%s (%s)\n",height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,kmdtxid.ToString().c_str(),desttxid.ToString().c_str(),(char *)&scriptbuf[len]);
} }
else if ( i == 0 && j == 1 && opretlen == 149 ) else if ( i == 0 && j == 1 && opretlen == 149 )
komodo_paxpricefeed(height,&scriptbuf[len],opretlen); komodo_paxpricefeed(height,&scriptbuf[len],opretlen);
else komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,value,&scriptbuf[len],opretlen,j); else
{
//int32_t k; for (k=0; k<scriptlen; k++)
// printf("%02x",scriptbuf[k]);
//printf(" <- script ht.%d i.%d j.%d value %.8f\n",height,i,j,dstr(value));
komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,value,&scriptbuf[len],opretlen,j);
}
} }
return(notaryid); return(notaryid);
} }
int32_t komodo_isratify(int32_t isspecial,int32_t numvalid) int32_t komodo_isratify(int32_t isspecial,int32_t numvalid)
{ {
if ( isspecial != 0 && numvalid > 13 ) if ( isspecial != 0 && numvalid >= KOMODO_MINRATIFY )
return(1); return(1);
else return(0); else return(0);
} }
// Special tx have vout[0] -> CRYPTO777 // Special tx have vout[0] -> CRYPTO777
// with more than 13 pay2pubkey outputs -> ratify // with more than KOMODO_MINRATIFY pay2pubkey outputs -> ratify
// if all outputs to notary -> notary utxo // if all outputs to notary -> notary utxo
// if txi == 0 && 2 outputs and 2nd OP_RETURN, len == 32*2+4 -> notarized, 1st byte 'P' -> pricefeed // if txi == 0 && 2 outputs and 2nd OP_RETURN, len == 32*2+4 -> notarized, 1st byte 'P' -> pricefeed
// OP_RETURN: 'D' -> deposit, 'W' -> withdraw // OP_RETURN: 'D' -> deposit, 'W' -> withdraw
void komodo_connectblock(CBlockIndex *pindex,CBlock& block) void komodo_connectblock(CBlockIndex *pindex,CBlock& block)
{ {
static int32_t hwmheight;
uint64_t signedmask,voutmask; uint64_t signedmask,voutmask;
uint8_t scriptbuf[4096],pubkeys[64][33]; uint256 kmdtxid,btctxid,txhash; uint8_t scriptbuf[4096],pubkeys[64][33]; uint256 kmdtxid,btctxid,txhash;
int32_t i,j,k,numvalid,specialtx,notarizedheight,notaryid,len,numvouts,numvins,height,txn_count; int32_t i,j,k,numvalid,specialtx,notarizedheight,notaryid,len,numvouts,numvins,height,txn_count;
komodo_init(); komodo_init(pindex->nHeight);
if ( pindex->nHeight > hwmheight )
hwmheight = pindex->nHeight;
else
{
printf("hwmheight.%d vs pindex->nHeight.%d reorg.%d\n",hwmheight,pindex->nHeight,hwmheight-pindex->nHeight);
// reset komodostate
}
if ( ASSETCHAINS_SYMBOL[0] != 0 )
{
while ( KOMODO_REALTIME == 0 || time(NULL) <= KOMODO_REALTIME )
{
fprintf(stderr,"komodo_connect.(%s) waiting for realtime RT.%u now.%u\n",ASSETCHAINS_SYMBOL,KOMODO_REALTIME,(uint32_t)time(NULL));
sleep(3);
}
}
KOMODO_INITDONE = (uint32_t)time(NULL); KOMODO_INITDONE = (uint32_t)time(NULL);
#ifdef KOMODO_ISSUER
komodo_gateway_issuer();
#else
komodo_gateway_redeemer();
#endif
if ( pindex != 0 ) if ( pindex != 0 )
{ {
height = pindex->nHeight; height = pindex->nHeight;
txn_count = block.vtx.size(); txn_count = block.vtx.size();
if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
printf("%s ht.%d connect txn_count.%d\n",ASSETCHAINS_SYMBOL,height,txn_count);
for (i=0; i<txn_count; i++) for (i=0; i<txn_count; i++)
{ {
txhash = block.vtx[i].GetHash(); txhash = block.vtx[i].GetHash();
@@ -419,7 +439,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block)
} }
} }
} }
if ( komodo_isratify(1,numvalid) > 13 ) if ( komodo_isratify(1,numvalid) >= KOMODO_MINRATIFY && numvouts > 13 )
{ {
memset(&txhash,0,sizeof(txhash)); memset(&txhash,0,sizeof(txhash));
komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0); komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0);

View File

@@ -23,6 +23,8 @@
#include <curl/easy.h> #include <curl/easy.h>
#endif #endif
#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"curl",(char *)"http://127.0.0.1:7775",0,(char *)(cmdstr),0)
struct MemoryStruct { char *memory; size_t size; }; struct MemoryStruct { char *memory; size_t size; };
struct return_string { char *ptr; size_t len; }; struct return_string { char *ptr; size_t len; };
@@ -137,7 +139,6 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
* *
************************************************************************/ ************************************************************************/
char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params) char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params)
{ {
static int didinit,count,count2; static double elapsedsum,elapsedsum2; static int didinit,count,count2; static double elapsedsum,elapsedsum2;
@@ -227,7 +228,8 @@ try_again:
free(s.ptr); free(s.ptr);
return(0); return(0);
} }
printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries); if ( (rand() % 1000) == 0 )
printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries);
free(s.ptr); free(s.ptr);
sleep((1<<numretries)); sleep((1<<numretries));
goto try_again; goto try_again;
@@ -239,7 +241,7 @@ try_again:
{ {
count++; count++;
elapsedsum += (OS_milliseconds() - starttime); elapsedsum += (OS_milliseconds() - starttime);
if ( (count % 10000) == 0) if ( (count % 1000000) == 0)
printf("%d: ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,elapsedsum/count,(OS_milliseconds() - starttime),command,url); printf("%d: ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,elapsedsum/count,(OS_milliseconds() - starttime),command,url);
if ( retstrp != 0 ) if ( retstrp != 0 )
{ {
@@ -343,7 +345,6 @@ char *komodo_issuemethod(char *method,char *params,uint16_t port)
} }
return(retstr2); return(retstr2);
} }
//curl --url "http://127.0.0.1:13033" --user "user1557335368:pass111720054" --data "{\"method\":\"getinfo\",\"params\":[]}"
uint32_t komodo_txtime(uint256 hash) uint32_t komodo_txtime(uint256 hash)
{ {
@@ -361,9 +362,25 @@ uint32_t komodo_txtime(uint256 hash)
return(0); return(0);
} }
uint64_t komodo_seed(int32_t height)
{
uint256 hash; uint64_t seed = 0; CBlockIndex *pindex = chainActive[height];
if ( pindex != 0 )
{
hash = pindex->GetBlockHash();
seed = arith_uint256(hash.GetHex()).GetLow64();
}
return(seed);
}
void komodo_disconnect(CBlockIndex *pindex,CBlock& block) void komodo_disconnect(CBlockIndex *pindex,CBlock& block)
{ {
komodo_init(); //int32_t i; uint256 hash;
komodo_init(pindex->nHeight);
//hash = block.GetHash();
//for (i=0; i<32; i++)
// printf("%02x",((uint8_t *)&hash)[i]);
//printf(" <- disconnect block\n");
//uint256 zero; //uint256 zero;
//printf("disconnect ht.%d\n",pindex->nHeight); //printf("disconnect ht.%d\n",pindex->nHeight);
//memset(&zero,0,sizeof(zero)); //memset(&zero,0,sizeof(zero));
@@ -373,7 +390,6 @@ void komodo_disconnect(CBlockIndex *pindex,CBlock& block)
int32_t komodo_block2height(CBlock *block) int32_t komodo_block2height(CBlock *block)
{ {
int32_t i,n,height = 0; uint8_t *ptr; int32_t i,n,height = 0; uint8_t *ptr;
komodo_init();
#ifdef KOMODO_ZCASH #ifdef KOMODO_ZCASH
ptr = (uint8_t *)block->vtx[0].vin[0].scriptSig.data(); ptr = (uint8_t *)block->vtx[0].vin[0].scriptSig.data();
#else #else
@@ -392,6 +408,7 @@ int32_t komodo_block2height(CBlock *block)
} }
//printf(" <- coinbase.%d ht.%d\n",(int32_t)block->vtx[0].vin[0].scriptSig.size(),height); //printf(" <- coinbase.%d ht.%d\n",(int32_t)block->vtx[0].vin[0].scriptSig.size(),height);
} }
komodo_init(height);
return(height); return(height);
} }
@@ -402,14 +419,14 @@ void komodo_block2pubkey33(uint8_t *pubkey33,CBlock& block)
#else #else
uint8_t *ptr = (uint8_t *)&block.vtx[0].vout[0].scriptPubKey[0]; uint8_t *ptr = (uint8_t *)&block.vtx[0].vout[0].scriptPubKey[0];
#endif #endif
komodo_init(); komodo_init(0);
memcpy(pubkey33,ptr+1,33); memcpy(pubkey33,ptr+1,33);
} }
void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height)
{ {
CBlock block; CBlock block;
komodo_init(); komodo_init(height);
memset(pubkey33,0,33); memset(pubkey33,0,33);
if ( pindex != 0 ) if ( pindex != 0 )
{ {

View File

@@ -17,170 +17,349 @@
struct pax_transaction struct pax_transaction
{ {
struct queueitem DL; UT_hash_handle hh;
uint256 txid; uint256 txid;
uint64_t komodoshis,fiatoshis; uint64_t komodoshis,fiatoshis;
int32_t marked,height;
uint16_t vout; uint16_t vout;
char symbol[4]; uint8_t rmd160[20],shortflag; char symbol[16],coinaddr[64]; uint8_t rmd160[20],shortflag;
}; } *PAX;
void komodo_gateway_deposits(CMutableTransaction& txNew) uint64_t komodo_paxtotal()
{ {
struct pax_transaction *ptr; uint8_t *script,opret[10000],data[10000]; int32_t i,len=0,opretlen=0,numvouts=1; struct pax_transaction *pax,*tmp; uint64_t total = 0;
PENDING_KOMODO_TX = 0; /*pthread_mutex_lock(&komodo_mutex);
while ( (ptr= (struct pax_transaction *)queue_dequeue(&DepositsQ)) != 0 ) tmp = 0;
if ( PAX != 0 )
{ {
txNew.vout.resize(numvouts+1); pax = (struct pax_transaction *)PAX->hh.next;
txNew.vout[numvouts].nValue = ptr->fiatoshis; while ( pax != 0 && pax != tmp && n++ < 1000000 )
txNew.vout[numvouts].scriptPubKey.resize(25); {
script = (uint8_t *)&txNew.vout[numvouts].scriptPubKey[0]; printf("PAX.[%p %p] pax.%p marked.%d fiat %.8f KMD %.8f\n",PAX->hh.next,PAX->hh.prev,pax,pax->marked,dstr(pax->fiatoshis),dstr(pax->komodoshis));
if ( pax->marked == 0 )
{
if ( komodo_is_issuer() != 0 )
total += pax->fiatoshis;
else total += pax->komodoshis;
}
tmp = pax;
pax = (struct pax_transaction *)pax->hh.next;
}
}
pthread_mutex_unlock(&komodo_mutex);
if ( n >= 1000000 )
printf("komodo_paxtotal n.%d iterations?\n",n);*/
HASH_ITER(hh,PAX,pax,tmp)
{
if ( pax->marked == 0 )
{
if ( komodo_is_issuer() != 0 )
total += pax->fiatoshis;
else total += pax->komodoshis;
}
}
return(total);
}
struct pax_transaction *komodo_paxfind(struct pax_transaction *space,uint256 txid,uint16_t vout)
{
struct pax_transaction *pax;
pthread_mutex_lock(&komodo_mutex);
HASH_FIND(hh,PAX,&txid,sizeof(txid),pax);
if ( pax != 0 )
memcpy(space,pax,sizeof(*pax));
pthread_mutex_unlock(&komodo_mutex);
return(pax);
}
struct pax_transaction *komodo_paxmark(int32_t height,struct pax_transaction *space,uint256 txid,uint16_t vout,int32_t mark)
{
struct pax_transaction *pax;
pthread_mutex_lock(&komodo_mutex);
HASH_FIND(hh,PAX,&txid,sizeof(txid),pax);
if ( pax == 0 )
{
pax = (struct pax_transaction *)calloc(1,sizeof(*pax));
pax->txid = txid;
pax->vout = vout;
HASH_ADD_KEYPTR(hh,PAX,&pax->txid,sizeof(pax->txid),pax);
//printf("ht.%d create pax.%p mark.%d\n",height,pax,mark);
}
if ( pax != 0 )
{
pax->marked = mark;
//int32_t i; for (i=0; i<32; i++)
// printf("%02x",((uint8_t *)&txid)[i]);
//printf(" paxmark.ht %d vout%d\n",mark,vout);
memcpy(space,pax,sizeof(*pax));
}
pthread_mutex_unlock(&komodo_mutex);
return(pax);
}
void komodo_gateway_deposit(char *coinaddr,uint64_t value,int32_t shortflag,char *symbol,uint64_t fiatoshis,uint8_t *rmd160,uint256 txid,uint16_t vout,int32_t height) // assetchain context
{
struct pax_transaction *pax; int32_t addflag = 0;
pthread_mutex_lock(&komodo_mutex);
HASH_FIND(hh,PAX,&txid,sizeof(txid),pax);
if ( pax == 0 )
{
pax = (struct pax_transaction *)calloc(1,sizeof(*pax));
pax->txid = txid;
pax->vout = vout;
HASH_ADD_KEYPTR(hh,PAX,&pax->txid,sizeof(pax->txid),pax);
//int32_t i; for (i=0; i<32; i++)
// printf("%02x",((uint8_t *)&txid)[i]);
//printf(" v.%d [%s] ht.%d create pax.%p\n",vout,ASSETCHAINS_SYMBOL,height,pax);
}
pthread_mutex_unlock(&komodo_mutex);
if ( coinaddr != 0 )
{
strcpy(pax->coinaddr,coinaddr);
pax->komodoshis = value;
pax->shortflag = shortflag;
strcpy(pax->symbol,symbol);
pax->fiatoshis = fiatoshis;
memcpy(pax->rmd160,rmd160,20);
pax->height = height;
if ( pax->marked == 0 )
printf("[%s] %p ADD DEPOSIT %s %.8f -> %s TO PAX ht.%d total %.8f\n",ASSETCHAINS_SYMBOL,pax,symbol,dstr(fiatoshis),coinaddr,height,dstr(komodo_paxtotal()));
else printf("%p MARKED.%d DEPOSIT %s %.8f -> %s TO PAX ht.%d\n",pax,pax->marked,symbol,dstr(fiatoshis),coinaddr,height);
}
else
{
pax->marked = height;
printf("pax.%p MARK DEPOSIT ht.%d\n",pax,height);
}
}
int32_t komodo_issued_opreturn(uint8_t *shortflagp,char *base,uint256 *txids,uint16_t *vouts,uint8_t *opretbuf,int32_t opretlen)
{
int32_t i,n=0,j,len;
if ( opretbuf[opretlen-5] == '-' )
*shortflagp = 1;
else *shortflagp = 0;
for (i=0; i<4; i++)
base[i] = opretbuf[opretlen-4+i];
if ( (strcmp(base,"KMD") == 0 && ASSETCHAINS_SYMBOL[0] == 0) || strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0 ) // shortflag
{
opretbuf++, opretlen--;
for (n=len=0; n<opretlen/34; n++)
{
for (j=0; j<32; j++)
{
((uint8_t *)&txids[n])[j] = opretbuf[len++];
//printf("%02x",((uint8_t *)&txids[n])[j]);
}
vouts[n] = opretbuf[len++];
vouts[n] = (opretbuf[len++] << 8) | vouts[n];
//printf(" issuedtxid v%d i.%d opretlen.%d\n",vouts[n],n,opretlen);
}
}
return(n);
}
void komodo_gateway_deposits(CMutableTransaction *txNew,int32_t shortflag,char *symbol)
{
struct pax_transaction *pax,*tmp; uint8_t *script,opcode,opret[10000],data[10000]; int32_t i,len=0,opretlen=0,numvouts=1;
PENDING_KOMODO_TX = 0;
if ( strcmp(symbol,"KMD") != 0 )
opcode = 'I';
else opcode = 'X';
HASH_ITER(hh,PAX,pax,tmp)
{
if ( pax->marked != 0 )
continue;
if ( ASSETCHAINS_SYMBOL[0] != 0 )
printf("pax.%p marked.%d %.8f -> %.8f\n",pax,pax->marked,dstr(pax->komodoshis),dstr(pax->fiatoshis));
txNew->vout.resize(numvouts+1);
txNew->vout[numvouts].nValue = pax->fiatoshis;
txNew->vout[numvouts].scriptPubKey.resize(25);
script = (uint8_t *)&txNew->vout[numvouts].scriptPubKey[0];
*script++ = 0x76; *script++ = 0x76;
*script++ = 0xa9; *script++ = 0xa9;
*script++ = 20; *script++ = 20;
memcpy(script,ptr->rmd160,20), script += 20; memcpy(script,pax->rmd160,20), script += 20;
*script++ = 0x88; *script++ = 0x88;
*script++ = 0xac; *script++ = 0xac;
for (i=0; i<32; i++) for (i=0; i<32; i++)
{ {
printf("%02x",((uint8_t *)&ptr->txid)[i]); //printf("%02x",((uint8_t *)&pax->txid)[i]);
data[len++] = ((uint8_t *)&ptr->txid)[i]; data[len++] = ((uint8_t *)&pax->txid)[i];
} }
data[len++] = ptr->vout & 0xff; data[len++] = pax->vout & 0xff;
data[len++] = (ptr->vout >> 8) & 0xff; data[len++] = (pax->vout >> 8) & 0xff;
printf(" vout.%u DEPOSIT %.8f\n",ptr->vout,(double)KOMODO_DEPOSIT/COIN); if ( strcmp(symbol,"KMD") != 0 )
PENDING_KOMODO_TX += ptr->fiatoshis; PENDING_KOMODO_TX += pax->fiatoshis;
numvouts++; else PENDING_KOMODO_TX += pax->komodoshis;
queue_enqueue((char *)"PENDINGS",&PendingsQ,&ptr->DL); //printf(" vout.%u DEPOSIT %.8f <- paxdeposit.%s pending %.8f\n",pax->vout,(double)txNew->vout[numvouts].nValue/COIN,symbol,dstr(PENDING_KOMODO_TX));
if ( numvouts++ >= 64 )
break;
} }
if ( numvouts > 1 ) if ( numvouts > 1 )
{ {
opretlen = komodo_opreturnscript(opret,'I',data,len); if ( shortflag != 0 )
txNew.vout.resize(numvouts+1); data[len++] = '-';
txNew.vout[numvouts].nValue = 0; for (i=0; symbol[i]!=0; i++)
txNew.vout[numvouts].scriptPubKey.resize(opretlen); data[len++] = symbol[i];
script = (uint8_t *)&txNew.vout[numvouts].scriptPubKey[0]; data[len++] = 0;
opretlen = komodo_opreturnscript(opret,opcode,data,len);
txNew->vout.resize(numvouts+1);
txNew->vout[numvouts].nValue = 0;
txNew->vout[numvouts].scriptPubKey.resize(opretlen);
script = (uint8_t *)&txNew->vout[numvouts].scriptPubKey[0];
memcpy(script,opret,opretlen); memcpy(script,opret,opretlen);
printf("total numvouts.%d %.8f opretlen.%d\n",numvouts,dstr(PENDING_KOMODO_TX),opretlen);
} }
printf("total numvouts.%d %.8f\n",numvouts,dstr(PENDING_KOMODO_TX));
} }
int32_t komodo_check_deposit(const CBlock& block) // verify above block is valid pax pricing int32_t komodo_check_deposit(int32_t height,const CBlock& block) // verify above block is valid pax pricing
{ {
// reenable rpc auth int32_t i,j,n,num,opretlen,offset=1,errs=0,matched=0; uint256 hash,txids[64]; uint8_t shortflag; char symbol[16],base[16]; uint16_t vouts[64]; uint8_t *script,opcode; struct pax_transaction *pax,space;
return(0); n = block.vtx[0].vout.size();
} script = (uint8_t *)block.vtx[0].vout[n-1].scriptPubKey.data();
if ( n <= 2 || script[0] != 0x6a )
void komodo_gateway_deposit(uint64_t value,int32_t shortflag,char *symbol,uint64_t fiatoshis,uint8_t *rmd160,uint256 txid,uint16_t vout) // assetchain context return(0);
{ offset += komodo_scriptitemlen(&opretlen,&script[offset]);
struct pax_transaction *ptr; //printf("checkdeposit n.%d [%02x] [%c] %d vs %d\n",n,script[0],script[offset],script[offset],'I');
ptr = (struct pax_transaction *)calloc(1,sizeof(*ptr)); if ( ASSETCHAINS_SYMBOL[0] == 0 )
ptr->komodoshis = value;
ptr->fiatoshis = fiatoshis;
memcpy(ptr->symbol,symbol,3);
memcpy(ptr->rmd160,rmd160,20);
ptr->shortflag = shortflag;
ptr->txid = txid;
ptr->vout = vout;
KOMODO_DEPOSIT += fiatoshis;
queue_enqueue((char *)"DEPOSITS",&DepositsQ,&ptr->DL);
}
int32_t komodo_gateway_depositremove(uint256 txid,uint16_t vout) // assetchain context
{
int32_t iter,n=0; queue_t *Q; struct pax_transaction *ptr; struct queueitem *item;
for (iter=0; iter<2; iter++)
{ {
Q = (iter == 0) ? &DepositsQ : &PendingsQ; opcode = 'X';
portable_mutex_lock(&Q->mutex); strcpy(symbol,"KMD");
if ( Q->list != 0 ) }
else
{
strcpy(symbol,ASSETCHAINS_SYMBOL);
opcode = 'I';
}
if ( script[offset] == opcode && opretlen < block.vtx[0].vout[n-1].scriptPubKey.size() )
{
if ( (num= komodo_issued_opreturn(&shortflag,base,txids,vouts,&script[offset],opretlen)) > 0 )
{ {
item = &ptr->DL; for (i=1; i<n-1; i++)
DL_FOREACH(Q->list,item)
{ {
ptr = (struct pax_transaction *)item; if ( (pax= komodo_paxfind(&space,txids[i-1],vouts[i-1])) != 0 )
if ( memcmp(&ptr->txid,&txid,sizeof(txid)) == 0 && ptr->vout == vout )
{ {
if ( KOMODO_DEPOSIT >= ptr->fiatoshis ) if ( ((opcode == 'I' && pax->fiatoshis == block.vtx[0].vout[i].nValue) || (opcode == 'X' && pax->komodoshis == block.vtx[0].vout[i].nValue)) )
KOMODO_DEPOSIT -= ptr->fiatoshis; {
else KOMODO_DEPOSIT = 0; if ( pax->marked != 0 )
printf("DELETE %.8f DEPOSIT %s %.8f\n",dstr(ptr->komodoshis),ptr->symbol,dstr(ptr->fiatoshis)); errs++;
DL_DELETE(Q->list,&ptr->DL); else matched++;
n++; //printf("errs.%d i.%d match %.8f == %.8f\n",errs,i,dstr(pax != 0 ? pax->fiatoshis:-1),dstr(block.vtx[0].vout[i].nValue));
free(ptr); }
break; else
{
hash = block.GetHash();
//for (j=0; j<32; j++)
// printf("%02x",((uint8_t *)&hash)[j]);
//printf(" ht.%d blockhash couldnt find vout.[%d]\n",height,i);
}
} }
else
{
//for (j=0; j<32; j++)
// printf("%02x",((uint8_t *)&txids[i-1])[j]);
//printf(" cant paxfind txid\n");
}
komodo_paxmark(height,&space,txids[i-1],vouts[i-1],height);
}
if ( matched != num )
{
//printf("matched.%d vs num.%d\n",matched,num);
if ( height > 60000 )
return(-1);
} }
} }
portable_mutex_unlock(&Q->mutex); //printf("opretlen.%d num.%d\n",opretlen,num);
} }
if ( queue_size(&DepositsQ) == 0 && queue_size(&PendingsQ) == 0 ) return(0);
KOMODO_DEPOSIT = PENDING_KOMODO_TX = 0;
return(n);
} }
const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen,uint256 txid,uint16_t vout) const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen,uint256 txid,uint16_t vout)
{ {
uint8_t rmd160[20],addrtype,shortflag,pubkey33[33]; int32_t i,j,len,tokomodo=0; char base[4],coinaddr[64],destaddr[64]; int64_t fiatoshis,checktoshis; const char *typestr = "unknown"; uint8_t rmd160[20],addrtype,shortflag,pubkey33[33]; int32_t i,j,n,len,tokomodo,kmdheight; char base[4],coinaddr[64],destaddr[64]; struct pax_transaction space; uint256 txids[64]; uint16_t vouts[64]; double diff; uint64_t seed; int64_t fiatoshis,checktoshis; const char *typestr = "unknown";
#ifdef KOMODO_ISSUER tokomodo = (komodo_is_issuer() == 0);
tokomodo = 1; if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
#endif
if ( opretbuf[0] == ((tokomodo != 0) ? 'D' : 'W') )
{ {
if ( opretlen == 34 ) for (i=0; i<opretlen; i++)
printf("%02x",opretbuf[i]);
printf(" opret[%c] else path tokomodo.%d ht.%d\n",opretbuf[0],tokomodo,height);
}
if ( opretbuf[0] == 'D' )
{
if ( opretlen == 38 ) // any KMD tx
{ {
iguana_rwnum(0,&opretbuf[34],sizeof(kmdheight),&kmdheight);
memset(base,0,sizeof(base)); memset(base,0,sizeof(base));
PAX_pubkey(0,&opretbuf[1],&addrtype,rmd160,base,&shortflag,&fiatoshis); PAX_pubkey(0,&opretbuf[1],&addrtype,rmd160,base,&shortflag,&fiatoshis);
if ( fiatoshis < 0 ) if ( fiatoshis < 0 )
fiatoshis = -fiatoshis; fiatoshis = -fiatoshis;
bitcoin_address(coinaddr,addrtype,rmd160,20); bitcoin_address(coinaddr,addrtype,rmd160,20);
checktoshis = PAX_fiatdest(tokomodo,destaddr,pubkey33,coinaddr,height,base,fiatoshis); checktoshis = PAX_fiatdest(&seed,tokomodo,destaddr,pubkey33,coinaddr,kmdheight,base,fiatoshis);
for (i=0; i<opretlen; i++)
printf("%02x",opretbuf[i]);
printf(" DEPOSIT %.8f %c%s -> %s ",dstr(fiatoshis),shortflag!=0?'-':'+',base,coinaddr);
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)\n",dstr(checktoshis),dstr(value),destaddr);
typestr = "deposit"; typestr = "deposit";
#ifdef KOMODO_ISSUER printf("kmdheight.%d vs height.%d check %.8f vs %.8f tokomodo.%d %d seed.%llx\n",kmdheight,height,dstr(checktoshis),dstr(value),komodo_is_issuer(),strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0,(long long)seed);
if ( strncmp(KOMODO_SOURCE,base,strlen(base)) == 0 && value >= (9999*checktoshis)/10000 && shortflag == ASSETCHAINS_SHORTFLAG ) diff = ((double)value / checktoshis) - 1.;
if ( diff < 0. )
diff = -diff;
if ( kmdheight <= height )
{ {
komodo_gateway_deposit(value,shortflag,base,fiatoshis,rmd160,txid,vout); if ( tokomodo == 0 && strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0 && shortflag == ASSETCHAINS_SHORTFLAG )
{
if ( shortflag == 0 )
{
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 ( value >= checktoshis || (seed == 0 && diff < .01) )
{
if ( komodo_paxfind(&space,txid,vout) == 0 )
{
komodo_gateway_deposit(coinaddr,value,shortflag,base,fiatoshis,rmd160,txid,vout,kmdheight);
} else printf("duplicate deposit\n");
}
}
else // short
{
for (i=0; i<opretlen; i++)
printf("%02x",opretbuf[i]);
printf(" opret[%c] tokomodo.%d value %.8f vs check %.8f\n",opretbuf[0],tokomodo,dstr(value),dstr(checktoshis));
if ( value <= checktoshis || (seed == 0 && diff < .01) )
{
}
}
}
} }
#else
if ( tokomodo != 0 && value <= (10000*checktoshis)/9999 )
{
}
#endif
} }
} }
else else if ( strncmp((char *)"KMD",(char *)&opretbuf[opretlen-4],3) != 0 )
{ {
for (i=0; i<opretlen; i++) if ( tokomodo == 0 && opretbuf[0] == 'I' ) // assetchain coinbase
printf("%02x",opretbuf[i]);
printf(" komodo_opreturn[%c]: ht.%d %.8f opretlen.%d\n",opretbuf[0],height,dstr(value),opretlen);
if ( opretbuf[0] == 'I' )
{ {
uint256 issuedtxid; uint16_t issuedvout; if ( (n= komodo_issued_opreturn(&shortflag,base,txids,vouts,opretbuf,opretlen)) > 0 && shortflag == ASSETCHAINS_SHORTFLAG )
opretbuf++, opretlen--;
for (i=len=0; i<opretlen/34; i++)
{ {
for (j=0; j<32; j++) for (i=0; i<n; i++)
{ {
((uint8_t *)&issuedtxid)[j] = opretbuf[len++]; //for (j=0; j<32; j++)
printf("%02x",((uint8_t *)&issuedtxid)[j]); // printf("%02x",((uint8_t *)&txids[i])[j]);
if ( komodo_paxmark(height,&space,txids[i],vouts[i],height) == 0 )
{
komodo_gateway_deposit(0,0,0,0,0,0,txids[i],vouts[i],height);
}
else
{
//printf(" duplicate issuedtxid v%d i.%d of n.%d opretlen.%d\n",vouts[i],i,n,opretlen);
}
} }
issuedvout = opretbuf[len++];
issuedvout = (opretbuf[len++] << 8) | vout;
printf(" issuedtxid v%d i.%d opretlen.%d\n",issuedvout,i,opretlen);
if ( komodo_gateway_depositremove(issuedtxid,issuedvout) == 0 )
printf("error removing deposit\n");
} }
} }
else if ( tokomodo != 0 && opretbuf[0] == 'X' )
{
// verify and update limits
}
} }
return(typestr); return(typestr);
} }
@@ -190,16 +369,10 @@ void komodo_gateway_voutupdate(char *symbol,int32_t isspecial,int32_t height,int
int32_t i,opretlen,offset = 0; uint256 zero,utxid; const char *typestr; int32_t i,opretlen,offset = 0; uint256 zero,utxid; const char *typestr;
typestr = "unknown"; typestr = "unknown";
memcpy(&utxid,&txid,sizeof(utxid)); memcpy(&utxid,&txid,sizeof(utxid));
if ( 0 )//txi != 0 || vout != 0 )
{
for (i=0; i<len; i++)
printf("%02x",script[i]);
printf(" <- %s VOUTUPDATE.%d txi.%d vout.%d %.8f scriptlen.%d OP_RETURN.%d (%s) len.%d\n",symbol,height,txi,vout,dstr(value),len,script[0] == 0x6a,typestr,opretlen);
}
if ( script[offset++] == 0x6a ) if ( script[offset++] == 0x6a )
{ {
offset += komodo_scriptitemlen(&opretlen,&script[offset]); offset += komodo_scriptitemlen(&opretlen,&script[offset]);
if ( isspecial != 0 && len >= offset+32*2+4 && strcmp((char *)&script[offset+32*2+4],"KMD") == 0 ) if ( isspecial != 0 && len >= offset+32*2+4 && strcmp((char *)&script[offset+32*2+4],ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL) == 0 )
typestr = "notarized"; typestr = "notarized";
else if ( txi == 0 && vout == 1 && opretlen == 149 ) else if ( txi == 0 && vout == 1 && opretlen == 149 )
{ {
@@ -209,43 +382,48 @@ void komodo_gateway_voutupdate(char *symbol,int32_t isspecial,int32_t height,int
} }
else komodo_stateupdate(height,0,0,0,utxid,0,0,0,0,0,value,&script[offset],opretlen,vout); else komodo_stateupdate(height,0,0,0,utxid,0,0,0,0,0,value,&script[offset],opretlen,vout);
} }
else if ( numvouts > 13 ) else if ( numvouts >= KOMODO_MINRATIFY )
typestr = "ratify"; typestr = "ratify";
} }
int32_t komodo_gateway_tx(char *symbol,int32_t height,int32_t txi,char *txidstr,uint32_t port) int32_t komodo_gateway_tx(char *symbol,int32_t height,int32_t txi,char *txidstr,uint32_t port)
{ {
char *retstr,params[256],*hexstr; uint8_t script[10000]; cJSON *json,*result,*vouts,*item,*sobj; int32_t vout,n,len,isspecial,retval = -1; uint64_t value; bits256 txid; char *retstr,params[256],*hexstr; uint8_t script[10000]; cJSON *oldpub,*newpub,*json,*result,*vouts,*item,*sobj; int32_t vout,n,len,isspecial,retval = -1; uint64_t value; bits256 txid;
sprintf(params,"[\"%s\", 1]",txidstr); sprintf(params,"[\"%s\", 1]",txidstr);
if ( (retstr= komodo_issuemethod((char *)"getrawtransaction",params,port)) != 0 ) if ( (retstr= komodo_issuemethod((char *)"getrawtransaction",params,port)) != 0 )
{ {
if ( (json= cJSON_Parse(retstr)) != 0 ) if ( (json= cJSON_Parse(retstr)) != 0 )
{ {
if ( (result= jobj(json,(char *)"result")) != 0 && (vouts= jarray(&n,result,(char *)"vout")) != 0 ) if ( (result= jobj(json,(char *)"result")) != 0 )
{ {
oldpub = jobj(result,(char *)"vpub_old");
newpub = jobj(result,(char *)"vpub_new");
retval = 0; retval = 0;
isspecial = 0; if ( oldpub == 0 && newpub == 0 && (vouts= jarray(&n,result,(char *)"vout")) != 0 )
txid = jbits256(result,(char *)"txid");
for (vout=0; vout<n; vout++)
{ {
item = jitem(vouts,vout); isspecial = 0;
value = SATOSHIDEN * jdouble(item,(char *)"value"); txid = jbits256(result,(char *)"txid");
if ( (sobj= jobj(item,(char *)"scriptPubKey")) != 0 ) for (vout=0; vout<n; vout++)
{ {
if ( (hexstr= jstr(sobj,(char *)"hex")) != 0 ) item = jitem(vouts,vout);
value = SATOSHIDEN * jdouble(item,(char *)"value");
if ( (sobj= jobj(item,(char *)"scriptPubKey")) != 0 )
{ {
len = (int32_t)strlen(hexstr) >> 1; if ( (hexstr= jstr(sobj,(char *)"hex")) != 0 )
if ( vout == 0 && ((memcmp(&hexstr[2],CRYPTO777_PUBSECPSTR,66) == 0 && len == 35) || (memcmp(&hexstr[6],CRYPTO777_RMD160STR,40) == 0 && len == 25)) )
isspecial = 1;
else if ( len <= sizeof(script) )
{ {
decode_hex(script,len,hexstr); len = (int32_t)strlen(hexstr) >> 1;
komodo_gateway_voutupdate(symbol,isspecial,height,txi,txid,vout,n,value,script,len); if ( vout == 0 && ((memcmp(&hexstr[2],CRYPTO777_PUBSECPSTR,66) == 0 && len == 35) || (memcmp(&hexstr[6],CRYPTO777_RMD160STR,40) == 0 && len == 25)) )
isspecial = 1;
else if ( len <= sizeof(script) )
{
decode_hex(script,len,hexstr);
komodo_gateway_voutupdate(symbol,isspecial,height,txi,txid,vout,n,value,script,len);
}
} }
} }
} }
} }
} } else printf("error getting txids.(%s) %p\n",retstr,result);
free_json(json); free_json(json);
} }
free(retstr); free(retstr);
@@ -255,7 +433,7 @@ int32_t komodo_gateway_tx(char *symbol,int32_t height,int32_t txi,char *txidstr,
int32_t komodo_gateway_block(char *symbol,int32_t height,uint16_t port) int32_t komodo_gateway_block(char *symbol,int32_t height,uint16_t port)
{ {
char *retstr,*retstr2,params[128],*txidstr; int32_t i,n,retval = -1; cJSON *json,*tx,*result,*result2; char *retstr,*retstr2,params[128],*txidstr; int32_t i,n,retval = -1; cJSON *json,*tx=0,*result=0,*result2;
sprintf(params,"[%d]",height); sprintf(params,"[%d]",height);
if ( (retstr= komodo_issuemethod((char *)"getblockhash",params,port)) != 0 ) if ( (retstr= komodo_issuemethod((char *)"getblockhash",params,port)) != 0 )
{ {
@@ -276,17 +454,17 @@ int32_t komodo_gateway_block(char *symbol,int32_t height,uint16_t port)
break; break;
if ( i == n ) if ( i == n )
retval = 0; retval = 0;
else printf("error i.%d vs n.%d\n",i,n); else printf("komodo_gateway_block ht.%d error i.%d vs n.%d\n",height,i,n);
} } else printf("cant get result.%p or tx.%p\n",result,tx);
free_json(json); free_json(json);
} } else printf("cant parse2.(%s)\n",retstr2);
free(retstr2); free(retstr2);
} } else printf("error getblock %s\n",params);
} else printf("strlen.%ld (%s)\n",strlen(txidstr),txidstr); } else printf("strlen.%ld (%s)\n",strlen(txidstr),txidstr);
free_json(result); free_json(result);
} } else printf("couldnt parse.(%s)\n",retstr);
free(retstr); free(retstr);
} } else printf("error from getblockhash %d\n",height);
return(retval); return(retval);
} }
@@ -295,25 +473,32 @@ void komodo_gateway_iteration(char *symbol)
char *retstr; int32_t i,kmdheight; cJSON *infoobj,*result; uint256 zero; uint16_t port = 7771; char *retstr; int32_t i,kmdheight; cJSON *infoobj,*result; uint256 zero; uint16_t port = 7771;
if ( KMDHEIGHT <= 0 ) if ( KMDHEIGHT <= 0 )
KMDHEIGHT = 1; KMDHEIGHT = 1;
KOMODO_REALTIME = 0;
if ( (retstr= komodo_issuemethod((char *)"getinfo",0,port)) != 0 ) if ( (retstr= komodo_issuemethod((char *)"getinfo",0,port)) != 0 )
{ {
if ( (infoobj= cJSON_Parse(retstr)) != 0 ) if ( (infoobj= cJSON_Parse(retstr)) != 0 )
{ {
if ( (result= jobj(infoobj,(char *)"result")) != 0 && (kmdheight= jint(result,(char *)"blocks")) != 0 ) if ( (result= jobj(infoobj,(char *)"result")) != 0 && (kmdheight= jint(result,(char *)"blocks")) != 0 )
{ {
//printf("gateway KMDHEIGHT.%d kmdheight.%d\n",KMDHEIGHT,kmdheight);
for (i=0; i<1000 && KMDHEIGHT<kmdheight; i++,KMDHEIGHT++) for (i=0; i<1000 && KMDHEIGHT<kmdheight; i++,KMDHEIGHT++)
{ {
//printf("KMDHEIGHT %d\n",KMDHEIGHT); if ( (KMDHEIGHT % 10) == 0 )
if ( (KMDHEIGHT % 100) == 0 )
{ {
fprintf(stderr,"%s.%d ",symbol,KMDHEIGHT); if ( (KMDHEIGHT % 100) == 0 )
fprintf(stderr,"%s.%d ",symbol,KMDHEIGHT);
memset(&zero,0,sizeof(zero)); memset(&zero,0,sizeof(zero));
komodo_stateupdate(KMDHEIGHT,0,0,0,zero,0,0,0,0,KMDHEIGHT,0,0,0,0); komodo_stateupdate(KMDHEIGHT,0,0,0,zero,0,0,0,0,KMDHEIGHT,0,0,0,0);
} }
if ( komodo_gateway_block(symbol,KMDHEIGHT,port) < 0 ) if ( komodo_gateway_block(symbol,KMDHEIGHT,port) < 0 )
{
printf("error KMDHEIGHT %d\n",KMDHEIGHT);
break; break;
}
usleep(10000); usleep(10000);
} }
if ( KMDHEIGHT >= kmdheight )
KOMODO_REALTIME = (uint32_t)time(NULL);
} }
free_json(infoobj); free_json(infoobj);
} }
@@ -321,20 +506,46 @@ void komodo_gateway_iteration(char *symbol)
} }
else else
{ {
//printf("error from %s\n",symbol); printf("error from %s\n",symbol);
sleep(30); sleep(30);
} }
} }
#ifdef KOMODO_ISSUER void komodo_iteration(char *symbol)
void komodo_gateway_issuer() // from "assetchain" connectblock()
{ {
// check for redeems char *retstr,*base,*coinaddr,*txidstr,cmd[512]; uint64_t value,fiatoshis; cJSON *array,*item; int32_t i,n,vout,shortflag,height; uint256 txid; uint8_t rmd160[20],addrtype;
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
//[{"prev_hash":"5d5c9a49489b558de9e84f991f996dedaae6b9d0f157f82b2fec64662476d5cf","prev_vout":2,"EUR":0.78329000,"fiat":"EUR","height":57930,"KMD":0.10000000,"address":"RDhEGYScNQYetCyG75Kf8Fg61UWPdwc1C5"}]
sprintf(cmd,"{\"agent\":\"dpow\",\"method\":\"pending\",\"fiat\":\"%s\"}",symbol);
if ( (retstr= issue_curl(cmd)) != 0 )
{
if ( (array= cJSON_Parse(retstr)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
coinaddr = jstr(item,(char *)"address");
value = jdouble(item,(char *)"KMD") * COIN;
shortflag = juint(item,(char *)"short");
vout = jint(item,(char *)"prev_vout");
height = jint(item,(char *)"height");
base = jstr(item,(char *)"fiat");
txidstr = jstr(item,(char *)"prev_hash");
if ( coinaddr != 0 && base != 0 && value > 0 && height > 0 )
{
fiatoshis = jdouble(item,base) * COIN;
decode_hex((uint8_t *)&txid,sizeof(txid),txidstr);
bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr);
komodo_gateway_deposit(coinaddr,value,shortflag,base,fiatoshis,rmd160,txid,vout,height);
}
}
}
}
printf("retstr.(%s)\n",retstr);
free(retstr);
}
}
} }
#else
void komodo_gateway_redeemer() // from "KMD" connectblock()
{
}
#endif

View File

@@ -29,6 +29,6 @@ uint64_t ASSETCHAINS_SUPPLY = 10;
int32_t NOTARIZED_HEIGHT,Num_nutxos,KMDHEIGHT = 43000; int32_t NOTARIZED_HEIGHT,Num_nutxos,KMDHEIGHT = 43000;
uint256 NOTARIZED_HASH,NOTARIZED_DESTTXID; uint256 NOTARIZED_HASH,NOTARIZED_DESTTXID;
pthread_mutex_t komodo_mutex; pthread_mutex_t komodo_mutex;
uint32_t KOMODO_INITDONE; uint32_t KOMODO_INITDONE,KOMODO_REALTIME;
char KMDUSERPASS[1024]; uint16_t BITCOIND_PORT = 7771; char KMDUSERPASS[1024]; uint16_t BITCOIND_PORT = 7771;
uint64_t KOMODO_DEPOSIT,PENDING_KOMODO_TX; uint64_t PENDING_KOMODO_TX;

View File

@@ -13,7 +13,7 @@
* * * *
******************************************************************************/ ******************************************************************************/
const char *Notaries[][2] = const char *Notaries_genesis[][2] =
{ {
{ "jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, { "jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" },
{ "jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, { "jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" },
@@ -60,18 +60,6 @@ struct knotary_entry { UT_hash_handle hh; uint8_t pubkey[33],notaryid; };
struct knotaries_entry { int32_t height,numnotaries; struct knotary_entry *Notaries; } Pubkeys[10000]; struct knotaries_entry { int32_t height,numnotaries; struct knotary_entry *Notaries; } Pubkeys[10000];
struct notarized_checkpoint { uint256 notarized_hash,notarized_desttxid; int32_t nHeight,notarized_height; } *NPOINTS; int32_t NUM_NPOINTS; struct notarized_checkpoint { uint256 notarized_hash,notarized_desttxid; int32_t nHeight,notarized_height; } *NPOINTS; int32_t NUM_NPOINTS;
int32_t komodo_ratify_threshold(int32_t height,uint64_t signedmask)
{
int32_t numnotaries,i,wt = 0;
numnotaries = Pubkeys[height / KOMODO_ELECTION_GAP].numnotaries;
for (i=0; i<numnotaries; i++)
if ( ((1LL << i) & signedmask) != 0 )
wt++;
if ( wt > (numnotaries >> 1) || (wt > 7 && (signedmask & 3) != 0) )
return(1); // N/2+1 || N/3 + devsig
else return(0);
}
void komodo_nutxoadd(int32_t height,int32_t notaryid,uint256 txhash,uint64_t voutmask,int32_t numvouts) void komodo_nutxoadd(int32_t height,int32_t notaryid,uint256 txhash,uint64_t voutmask,int32_t numvouts)
{ {
struct nutxo_entry *np; struct nutxo_entry *np;
@@ -84,7 +72,7 @@ void komodo_nutxoadd(int32_t height,int32_t notaryid,uint256 txhash,uint64_t vou
np->voutmask = voutmask; np->voutmask = voutmask;
np->notaryid = notaryid; np->notaryid = notaryid;
HASH_ADD_KEYPTR(hh,NUTXOS,&np->txhash,sizeof(np->txhash),np); HASH_ADD_KEYPTR(hh,NUTXOS,&np->txhash,sizeof(np->txhash),np);
printf("Add NUTXO[%d] <- %s notaryid.%d t%u %s %llx\n",Num_nutxos,Notaries[notaryid][0],notaryid,komodo_txtime(txhash),txhash.ToString().c_str(),(long long)voutmask); //printf("Add NUTXO[%d] <- %s notaryid.%d t%u %s %llx\n",Num_nutxos,Notaries[notaryid][0],notaryid,komodo_txtime(txhash),txhash.ToString().c_str(),(long long)voutmask);
Num_nutxos++; Num_nutxos++;
pthread_mutex_unlock(&komodo_mutex); pthread_mutex_unlock(&komodo_mutex);
} }
@@ -101,6 +89,44 @@ int32_t komodo_nutxofind(int32_t height,uint256 txhash,int32_t vout)
return(-1); return(-1);
} }
int32_t komodo_ratify_threshold(int32_t height,uint64_t signedmask)
{
int32_t htind,numnotaries,i,wt = 0;
if ( ASSETCHAINS_SYMBOL[0] != 0 )
return(2);
if ( (htind= KOMODO_PUBKEYS_HEIGHT(height) / KOMODO_ELECTION_GAP) == 1 )
htind = 0;
numnotaries = Pubkeys[htind].numnotaries;
for (i=0; i<numnotaries; i++)
if ( ((1LL << i) & signedmask) != 0 )
wt++;
if ( wt > (numnotaries >> 1) || (wt > 7 && (signedmask & 3) != 0) )
return(1);
else return(0);
}
int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height)
{
int32_t i,htind,n; uint64_t mask = 0; struct knotary_entry *kp,*tmp;
if ( (htind= KOMODO_PUBKEYS_HEIGHT(height) / KOMODO_ELECTION_GAP) == 1 )
htind = 0;
pthread_mutex_lock(&komodo_mutex);
n = Pubkeys[htind].numnotaries;
HASH_ITER(hh,Pubkeys[htind].Notaries,kp,tmp)
{
if ( kp->notaryid < n )
{
mask |= (1LL << kp->notaryid);
memcpy(pubkeys[kp->notaryid],kp->pubkey,33);
} else printf("illegal notaryid.%d vs n.%d\n",kp->notaryid,n);
}
pthread_mutex_unlock(&komodo_mutex);
if ( mask == ((1LL << n)-1) )
return(n);
printf("error retrieving notaries ht.%d got mask.%llx for n.%d\n",height,(long long)mask,n);
return(-1);
}
void komodo_notarysinit(int32_t height,uint8_t pubkeys[64][33],int32_t num) void komodo_notarysinit(int32_t height,uint8_t pubkeys[64][33],int32_t num)
{ {
int32_t k,i,htind; struct knotary_entry *kp; struct knotaries_entry N; int32_t k,i,htind; struct knotary_entry *kp; struct knotaries_entry N;
@@ -120,8 +146,7 @@ void komodo_notarysinit(int32_t height,uint8_t pubkeys[64][33],int32_t num)
} }
} }
N.numnotaries = num; N.numnotaries = num;
htind = KOMODO_PUBKEYS_HEIGHT(height) / KOMODO_ELECTION_GAP; if ( (htind= KOMODO_PUBKEYS_HEIGHT(height) / KOMODO_ELECTION_GAP) == 1 )
if ( htind == 1 )
htind = 0; htind = 0;
for (i=htind; i<sizeof(Pubkeys)/sizeof(*Pubkeys); i++) for (i=htind; i<sizeof(Pubkeys)/sizeof(*Pubkeys); i++)
{ {
@@ -134,16 +159,18 @@ void komodo_notarysinit(int32_t height,uint8_t pubkeys[64][33],int32_t num)
int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33) int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33)
{ {
// -1 if not notary, 0 if notary, 1 if special notary // -1 if not notary, 0 if notary, 1 if special notary
struct knotary_entry *kp; int32_t numnotaries,modval = -1; struct knotary_entry *kp; int32_t numnotaries,htind,modval = -1;
*notaryidp = -1; *notaryidp = -1;
if ( height < 0 || height/KOMODO_ELECTION_GAP >= sizeof(Pubkeys)/sizeof(*Pubkeys) ) if ( height < 0 || height/KOMODO_ELECTION_GAP >= sizeof(Pubkeys)/sizeof(*Pubkeys) )
return(-1); return(-1);
if ( (htind= KOMODO_PUBKEYS_HEIGHT(height) / KOMODO_ELECTION_GAP) == 1 )
htind = 0;
pthread_mutex_lock(&komodo_mutex); pthread_mutex_lock(&komodo_mutex);
HASH_FIND(hh,Pubkeys[height/KOMODO_ELECTION_GAP].Notaries,pubkey33,33,kp); HASH_FIND(hh,Pubkeys[htind].Notaries,pubkey33,33,kp);
pthread_mutex_unlock(&komodo_mutex); pthread_mutex_unlock(&komodo_mutex);
if ( kp != 0 ) if ( kp != 0 )
{ {
if ( (numnotaries= Pubkeys[height/KOMODO_ELECTION_GAP].numnotaries) > 0 ) if ( (numnotaries= Pubkeys[htind].numnotaries) > 0 )
{ {
*notaryidp = kp->notaryid; *notaryidp = kp->notaryid;
modval = ((height % numnotaries) == kp->notaryid); modval = ((height % numnotaries) == kp->notaryid);
@@ -195,25 +222,25 @@ int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *n
return(0); return(0);
} }
void komodo_init() void komodo_init(int32_t height)
{ {
static int didinit; uint256 zero; int32_t k,n; uint8_t pubkeys[64][33]; static int didinit; uint256 zero; int32_t k,n; uint8_t pubkeys[64][33];
if ( didinit == 0 ) if ( height > didinit )
{ {
didinit = 1; if ( didinit == 0 )
iguana_initQ(&DepositsQ,(char *)"Deposits");
iguana_initQ(&PendingsQ,(char *)"Pendings");
pthread_mutex_init(&komodo_mutex,NULL);
decode_hex(NOTARY_PUBKEY33,33,(char *)NOTARY_PUBKEY.c_str());
n = (int32_t)(sizeof(Notaries)/sizeof(*Notaries));
for (k=0; k<n; k++)
{ {
if ( Notaries[k][0] == 0 || Notaries[k][1] == 0 || Notaries[k][0][0] == 0 || Notaries[k][1][0] == 0 ) pthread_mutex_init(&komodo_mutex,NULL);
break; decode_hex(NOTARY_PUBKEY33,33,(char *)NOTARY_PUBKEY.c_str());
decode_hex(pubkeys[k],33,(char *)Notaries[k][1]); n = (int32_t)(sizeof(Notaries_genesis)/sizeof(*Notaries_genesis));
for (k=0; k<n; k++)
{
if ( Notaries_genesis[k][0] == 0 || Notaries_genesis[k][1] == 0 || Notaries_genesis[k][0][0] == 0 || Notaries_genesis[k][1][0] == 0 )
break;
decode_hex(pubkeys[k],33,(char *)Notaries_genesis[k][1]);
}
komodo_notarysinit(0,pubkeys,k);
memset(&zero,0,sizeof(zero));
} }
komodo_notarysinit(0,pubkeys,k);
memset(&zero,0,sizeof(zero));
komodo_stateupdate(0,0,0,0,zero,0,0,0,0,0,0,0,0,0); komodo_stateupdate(0,0,0,0,zero,0,0,0,0,0,0,0,0,0);
} }
} }

View File

@@ -30,6 +30,72 @@ uint32_t MINDENOMS[] = { MIND, MIND, 100*MIND, MIND, MIND, MIND, MIND, MIND, //
10*MIND, 10*MIND,
}; };
int32_t Peggy_inds[539] = {289, 404, 50, 490, 59, 208, 87, 508, 366, 288, 13, 38, 159, 440, 120, 480, 361, 104, 534, 195, 300, 362, 489, 108, 143, 220, 131, 244, 133, 473, 315, 439, 210, 456, 219, 352, 153, 444, 397, 491, 286, 479, 519, 384, 126, 369, 155, 427, 373, 360, 135, 297, 256, 506, 322, 425, 501, 251, 75, 18, 420, 537, 443, 438, 407, 145, 173, 78, 340, 240, 422, 160, 329, 32, 127, 128, 415, 495, 372, 522, 60, 238, 129, 364, 471, 140, 171, 215, 378, 292, 432, 526, 252, 389, 459, 350, 233, 408, 433, 51, 423, 19, 62, 115, 211, 22, 247, 197, 530, 7, 492, 5, 53, 318, 313, 283, 169, 464, 224, 282, 514, 385, 228, 175, 494, 237, 446, 105, 150, 338, 346, 510, 6, 348, 89, 63, 536, 442, 414, 209, 216, 227, 380, 72, 319, 259, 305, 334, 236, 103, 400, 176, 267, 355, 429, 134, 257, 527, 111, 287, 386, 15, 392, 535, 405, 23, 447, 399, 291, 112, 74, 36, 435, 434, 330, 520, 335, 201, 478, 17, 162, 483, 33, 130, 436, 395, 93, 298, 498, 511, 66, 487, 218, 65, 309, 419, 48, 214, 377, 409, 462, 139, 349, 4, 513, 497, 394, 170, 307, 241, 185, 454, 29, 367, 465, 194, 398, 301, 229, 212, 477, 303, 39, 524, 451, 116, 532, 30, 344, 85, 186, 202, 517, 531, 515, 230, 331, 466, 147, 426, 234, 304, 64, 100, 416, 336, 199, 383, 200, 166, 258, 95, 188, 246, 136, 90, 68, 45, 312, 354, 184, 314, 518, 326, 401, 269, 217, 512, 81, 88, 272, 14, 413, 328, 393, 198, 226, 381, 161, 474, 353, 337, 294, 295, 302, 505, 137, 207, 249, 46, 98, 27, 458, 482, 262, 253, 71, 25, 0, 40, 525, 122, 341, 107, 80, 165, 243, 168, 250, 375, 151, 503, 124, 52, 343, 371, 206, 178, 528, 232, 424, 163, 273, 191, 149, 493, 177, 144, 193, 388, 1, 412, 265, 457, 255, 475, 223, 41, 430, 76, 102, 132, 96, 97, 316, 472, 213, 263, 3, 317, 324, 274, 396, 486, 254, 205, 285, 101, 21, 279, 58, 467, 271, 92, 538, 516, 235, 332, 117, 500, 529, 113, 445, 390, 358, 79, 34, 488, 245, 83, 509, 203, 476, 496, 347, 280, 12, 84, 485, 323, 452, 10, 146, 391, 293, 86, 94, 523, 299, 91, 164, 363, 402, 110, 321, 181, 138, 192, 469, 351, 276, 308, 277, 428, 182, 260, 55, 152, 157, 382, 121, 507, 225, 61, 431, 31, 106, 327, 154, 16, 49, 499, 73, 70, 449, 460, 187, 24, 248, 311, 275, 158, 387, 125, 67, 284, 35, 463, 190, 179, 266, 376, 221, 42, 26, 290, 357, 268, 43, 167, 99, 374, 242, 156, 239, 403, 339, 183, 320, 180, 306, 379, 441, 20, 481, 141, 77, 484, 69, 410, 502, 172, 417, 118, 461, 261, 47, 333, 450, 296, 453, 368, 359, 437, 421, 264, 504, 281, 270, 114, 278, 56, 406, 448, 411, 521, 418, 470, 123, 455, 148, 356, 468, 109, 204, 533, 365, 8, 345, 174, 370, 28, 57, 11, 2, 231, 310, 196, 119, 82, 325, 44, 342, 37, 189, 142, 222, 9, 54, };
uint64_t peggy_smooth_coeffs[sizeof(Peggy_inds)/sizeof(*Peggy_inds)] = // numprimes.13
{
962714545, 962506087, 962158759, 961672710, 961048151, 960285354, 959384649, 958346426, 957171134, // x.8
955859283, 954411438, 952828225, 951110328, 949258485, 947273493, 945156207, 942907532, 940528434, // x.17
938019929, 935383089, 932619036, 929728945, 926714044, 923575608, 920314964, 916933485, 913432593, // x.26
909813756, 906078486, 902228342, 898264923, 894189872, 890004874, 885711650, 881311964, 876807614, // x.35
872200436, 867492300, 862685110, 857780804, 852781347, 847688737, 842505000, 837232189, 831872382, // x.44
826427681, 820900212, 815292123, 809605581, 803842772, 798005901, 792097186, 786118864, 780073180, // x.53
773962395, 767788778, 761554609, 755262175, 748913768, 742511686, 736058231, 729555707, 723006417, // x.62
716412665, 709776755, 703100984, 696387648, 689639036, 682857428, 676045100, 669204315, 662337327, // x.71
655446378, 648533696, 641601496, 634651978, 627687325, 620709702, 613721256, 606724115, 599720386, // x.80
592712154, 585701482, 578690411, 571680955, 564675105, 557674825, 550682053, 543698699, 536726645, // x.89
529767743, 522823816, 515896658, 508988029, 502099660, 495233249, 488390461, 481572928, 474782249, // x.98
468019988, 461287675, 454586804, 447918836, 441285195, 434687268, 428126409, 421603932, 415121117, // x.107
408679208, 402279408, 395922888, 389610779, 383344175, 377124134, 370951677, 364827785, 358753406, // x.116
352729449, 346756785, 340836251, 334968645, 329154729, 323395230, 317690838, 312042206, 306449955, // x.125
300914667, 295436891, 290017141, 284655897, 279353604, 274110676, 268927490, 263804394, 258741701, // x.134
253739694, 248798623, 243918709, 239100140, 234343077, 229647649, 225013957, 220442073, 215932043, // x.143
211483883, 207097585, 202773112, 198510404, 194309373, 190169909, 186091877, 182075118, 178119452, // x.152
174224676, 170390565, 166616873, 162903335, 159249664, 155655556, 152120688, 148644718, 145227287, // x.161
141868021, 138566528, 135322401, 132135218, 129004542, 125929924, 122910901, 119946997, 117037723, // x.170
114182582, 111381062, 108632643, 105936795, 103292978, 100700645, 98159238, 95668194, 93226942, // x.179
90834903, 88491495, 86196126, 83948203, 81747126, 79592292, 77483092, 75418916, 73399150, // x.188
71423178, 69490383, 67600142, 65751837, 63944844, 62178541, 60452305, 58765515, 57117547, // x.197
55507781, 53935597, 52400377, 50901505, 49438366, 48010349, 46616844, 45257246, 43930951, // x.206
42637360, 41375878, 40145912, 38946876, 37778185, 36639262, 35529533, 34448428, 33395384, // x.215
32369842, 31371249, 30399057, 29452725, 28531717, 27635503, 26763558, 25915365, 25090413, // x.224
24288196, 23508216, 22749980, 22013003, 21296806, 20600917, 19924870, 19268206, 18630475, // x.233
18011231, 17410035, 16826458, 16260073, 15710466, 15177224, 14659944, 14158231, 13671694, // x.242
13199950, 12742625, 12299348, 11869759, 11453500, 11050225, 10659590, 10281262, 9914910, // x.251
9560213, 9216856, 8884529, 8562931, 8251764, 7950739, 7659571, 7377984, 7105706, // x.260
6842471, 6588020, 6342099, 6104460, 5874861, 5653066, 5438844, 5231969, 5032221, // x.269
4839386, 4653254, 4473620, 4300287, 4133059, 3971747, 3816167, 3666139, 3521488, // x.278
3382043, 3247640, 3118115, 2993313, 2873079, 2757266, 2645728, 2538325, 2434919, // x.287
2335380, 2239575, 2147382, 2058677, 1973342, 1891262, 1812325, 1736424, 1663453, // x.296
1593311, 1525898, 1461118, 1398879, 1339091, 1281666, 1226519, 1173569, 1122736, // x.305
1073944, 1027117, 982185, 939076, 897725, 858065, 820033, 783568, 748612, // x.314
715108, 682999, 652233, 622759, 594527, 567488, 541597, 516808, 493079, // x.323
470368, 448635, 427841, 407948, 388921, 370725, 353326, 336692, 320792, // x.332
305596, 291075, 277202, 263950, 251292, 239204, 227663, 216646, 206130, // x.341
196094, 186517, 177381, 168667, 160356, 152430, 144874, 137671, 130806, // x.350
124264, 118031, 112093, 106437, 101050, 95921, 91039, 86391, 81968, // x.359
77759, 73755, 69945, 66322, 62877, 59602, 56488, 53528, 50716, // x.368
48043, 45505, 43093, 40803, 38629, 36564, 34604, 32745, 30980, // x.377
29305, 27717, 26211, 24782, 23428, 22144, 20927, 19774, 18681, // x.386
17646, 16665, 15737, 14857, 14025, 13237, 12491, 11786, 11118, // x.395
10487, 9890, 9325, 8791, 8287, 7810, 7359, 6933, 6531, // x.404
6151, 5792, 5453, 5133, 4831, 4547, 4278, 4024, 3785, // x.413
3560, 3347, 3147, 2958, 2779, 2612, 2454, 2305, 2164, // x.422
2032, 1908, 1791, 1681, 1577, 1480, 1388, 1302, 1221, // x.431
1145, 1073, 1006, 942, 883, 827, 775, 725, 679, // x.440
636, 595, 557, 521, 487, 456, 426, 399, 373, // x.449
348, 325, 304, 284, 265, 248, 231, 216, 202, // x.458
188, 175, 164, 153, 142, 133, 124, 115, 107, // x.467
100, 93, 87, 81, 75, 70, 65, 61, 56, // x.476
53, 49, 45, 42, 39, 36, 34, 31, 29, // x.485
27, 25, 23, 22, 20, 19, 17, 16, 15, // x.494
14, 13, 12, 11, 10, 9, 9, 8, 7, // x.503
7, 6, 6, 5, 5, 5, 4, 4, 4, // x.512
3, 3, 3, 3, 2, 2, 2, 2, 2, // x.521
2, 2, 1, 1, 1, 1, 1, 1, 1, // x.530
1, 1, 1, 1, 1, 1, 0, 0, // isum 100000000000
};
uint64_t komodo_paxvol(uint64_t volume,uint64_t price) uint64_t komodo_paxvol(uint64_t volume,uint64_t price)
{ {
if ( volume < 10000000000 ) if ( volume < 10000000000 )
@@ -234,8 +300,11 @@ void komodo_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals)
uint64_t komodo_paxcalc(uint32_t *pvals,int32_t baseid,int32_t relid,uint64_t basevolume) uint64_t komodo_paxcalc(uint32_t *pvals,int32_t baseid,int32_t relid,uint64_t basevolume)
{ {
uint32_t pvalb,pvalr,kmdbtc,btcusd; uint64_t usdvol,baseusd,usdkmd,baserel,ranked[32]; uint32_t pvalb,pvalr,kmdbtc,btcusd; uint64_t usdvol,baseusd,usdkmd,baserel,ranked[32];
if ( basevolume > 1000000*COIN ) if ( basevolume > 10000*COIN )
{
printf("paxcalc overflow %.8f\n",dstr(basevolume));
return(0); return(0);
}
if ( (pvalb= pvals[baseid]) != 0 ) if ( (pvalb= pvals[baseid]) != 0 )
{ {
if ( relid == MAX_CURRENCIES ) if ( relid == MAX_CURRENCIES )
@@ -248,28 +317,35 @@ uint64_t komodo_paxcalc(uint32_t *pvals,int32_t baseid,int32_t relid,uint64_t ba
usdvol = komodo_paxvol(basevolume,baseusd) / MINDENOMS[baseid]; usdvol = komodo_paxvol(basevolume,baseusd) / MINDENOMS[baseid];
usdkmd = ((uint64_t)btcusd * 1000000000) / kmdbtc; usdkmd = ((uint64_t)btcusd * 1000000000) / kmdbtc;
//printf("base -> USD %llu, BTC %llu KMDUSD %llu\n",(long long)baseusd,(long long)btcusd,(long long)kmdusd); //printf("base -> USD %llu, BTC %llu KMDUSD %llu\n",(long long)baseusd,(long long)btcusd,(long long)kmdusd);
printf("usdkmd.%llu basevolume.%llu baseusd.%llu paxvol.%llu usdvol.%llu\n",(long long)usdkmd,(long long)basevolume,(long long)baseusd,(long long)komodo_paxvol(basevolume,baseusd),(long long)usdvol); //printf("usdkmd.%llu basevolume.%llu baseusd.%llu paxvol.%llu usdvol.%llu -> %.8f\n",(long long)usdkmd,(long long)basevolume,(long long)baseusd,(long long)komodo_paxvol(basevolume,baseusd),(long long)usdvol,dstr(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd)));
return(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd)); return(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd));
} } //else printf("zero val in KMD conv %llu %llu %llu\n",(long long)pvals[USD],(long long)kmdbtc,(long long)btcusd);
} }
else if ( baseid == relid ) else if ( baseid == relid )
{ {
if ( baseid != MAX_CURRENCIES ) if ( baseid != MAX_CURRENCIES )
{ {
pax_rank(ranked,pvals); pax_rank(ranked,pvals);
return(10 * ranked[baseid]); // map to percentage //printf("%s M1 percentage %.8f\n",CURRENCIES[baseid],dstr(10 * ranked[baseid]));
} return(10 * ranked[baseid]); // scaled percentage of M1 total
} else return(basevolume);
} }
else if ( (pvalr= pvals[relid]) != 0 ) else if ( (pvalr= pvals[relid]) != 0 )
{ {
baserel = ((uint64_t)pvalb * 1000000000) / pvalr; baserel = ((uint64_t)pvalb * 1000000000) / pvalr;
//printf("baserel.%lld %lld %lld %.8f %.8f\n",(long long)baserel,(long long)MINDENOMS[baseid],(long long)MINDENOMS[relid],dstr(MINDENOMS[baseid]/MINDENOMS[relid]),dstr(MINDENOMS[relid]/MINDENOMS[baseid]));
if ( MINDENOMS[baseid] > MINDENOMS[relid] )
basevolume /= (MINDENOMS[baseid] / MINDENOMS[relid]);
else if ( MINDENOMS[baseid] < MINDENOMS[relid] )
basevolume *= (MINDENOMS[relid] / MINDENOMS[baseid]);
return(komodo_paxvol(basevolume,baserel)); return(komodo_paxvol(basevolume,baserel));
} }
} else printf("null pval for %s\n",CURRENCIES[relid]);
} else printf("null pval for %s\n",CURRENCIES[baseid]);
return(0); return(0);
} }
uint64_t komodo_paxprice(int32_t height,char *base,char *rel,uint64_t basevolume) uint64_t _komodo_paxprice(int32_t height,char *base,char *rel,uint64_t basevolume)
{ {
int32_t baseid=-1,relid=-1,i; uint32_t *ptr; int32_t baseid=-1,relid=-1,i; uint32_t *ptr;
if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 ) if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 )
@@ -284,6 +360,79 @@ uint64_t komodo_paxprice(int32_t height,char *base,char *rel,uint64_t basevolume
return(0); return(0);
} }
uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume)
{
int32_t i,j,k,ind,zeroes,numvotes,wt,nonz; int64_t delta; uint64_t lastprice,seed,tolerance,den,densum,sum=0,votes[539];
if ( basevolume > 10000*COIN )
{
printf("komodo_paxprice overflow %.8f\n",dstr(basevolume));
return(0);
}
numvotes = (int32_t)(sizeof(Peggy_inds)/sizeof(*Peggy_inds));
memset(votes,0,sizeof(votes));
for (sum=i=zeroes=nonz=0; i<numvotes; i++)
{
if ( (votes[numvotes-1-i]= _komodo_paxprice(height-i,base,rel,100000)) == 0 )
{
zeroes++;
//printf("null price height.%d\n",height-i);
//return(0);
} else sum += votes[i], nonz++;
//printf("%.8f, ",dstr(votes[i]));
}
if ( nonz <= (numvotes >> 1) )
return(0);
sum /= nonz;
lastprice = sum;
for (i=0; i<numvotes; i++)
{
if ( votes[i] == 0 )
votes[i] = lastprice;
else lastprice = votes[i];
}
//printf("\n}; // numvotes.%d\n\n",numvotes);
*seedp = seed = komodo_seed(height);
tolerance = sum / 50;
for (k=0; k<numvotes; k++)
{
ind = Peggy_inds[(k + seed) % numvotes];
i = (int32_t)(ind % numvotes);
wt = 0;
if ( votes[i] != 0 )
{
for (j=0; j<numvotes; j++)
{
if ( votes[j] != 0 )
{
if ( (delta= (votes[i] - votes[j])) < 0 )
delta = -delta;
if ( delta <= tolerance )
{
wt++;
if ( wt > (numvotes >> 1) )
break;
}
}
}
}
if ( wt > (numvotes >> 1) )
{
ind = i;
for (densum=sum=j=0; j<numvotes; j++)
{
den = peggy_smooth_coeffs[j];
densum += den;
sum += (den * votes[(ind + j) % numvotes]);
}
sum /= densum;
sum = (sum * basevolume) / 100000;
printf("paxprice seed.%llx sum %.8f densum %.8f basevol %.8f height.%d\n",(long long)seed,dstr(sum),dstr(densum),dstr(basevolume),height);
break;
}
}
return(sum);
}
int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel) int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel)
{ {
int32_t baseid=-1,relid=-1,i,num = 0; uint32_t *ptr; int32_t baseid=-1,relid=-1,i,num = 0; uint32_t *ptr;
@@ -311,7 +460,7 @@ void komodo_paxpricefeed(int32_t height,uint8_t *pricefeed,int32_t opretlen)
//printf("komodo_paxpricefeed vout OP_RETURN.%d prices numpvals.%d opretlen.%d\n",height,numpvals,opretlen); //printf("komodo_paxpricefeed vout OP_RETURN.%d prices numpvals.%d opretlen.%d\n",height,numpvals,opretlen);
} }
uint64_t PAX_fiatdest(int32_t tokomodo,char *destaddr,uint8_t pubkey33[33],char *coinaddr,int32_t height,char *origbase,int64_t fiatoshis) uint64_t PAX_fiatdest(uint64_t *seedp,int32_t tokomodo,char *destaddr,uint8_t pubkey33[33],char *coinaddr,int32_t height,char *origbase,int64_t fiatoshis)
{ {
uint8_t shortflag = 0; char base[4]; int32_t i,baseid; uint8_t addrtype,rmd160[20]; int64_t komodoshis = 0; uint8_t shortflag = 0; char base[4]; int32_t i,baseid; uint8_t addrtype,rmd160[20]; int64_t komodoshis = 0;
if ( (baseid= komodo_baseid(origbase)) < 0 || baseid == MAX_CURRENCIES ) if ( (baseid= komodo_baseid(origbase)) < 0 || baseid == MAX_CURRENCIES )
@@ -321,7 +470,8 @@ uint64_t PAX_fiatdest(int32_t tokomodo,char *destaddr,uint8_t pubkey33[33],char
base[i] = 0; base[i] = 0;
if ( fiatoshis < 0 ) if ( fiatoshis < 0 )
shortflag = 1, fiatoshis = -fiatoshis; shortflag = 1, fiatoshis = -fiatoshis;
komodoshis = komodo_paxprice(height,base,(char *)"KMD",(uint64_t)fiatoshis); komodoshis = komodo_paxprice(seedp,height,base,(char *)"KMD",(uint64_t)fiatoshis);
//printf("PAX_fiatdest ht.%d price %s %.8f -> KMD %.8f\n",height,base,(double)fiatoshis/COIN,(double)komodoshis/COIN);
if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == 20 ) if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == 20 )
{ {
PAX_pubkey(1,pubkey33,&addrtype,rmd160,base,&shortflag,tokomodo != 0 ? &komodoshis : &fiatoshis); PAX_pubkey(1,pubkey33,&addrtype,rmd160,base,&shortflag,tokomodo != 0 ? &komodoshis : &fiatoshis);

View File

@@ -796,10 +796,17 @@ int32_t komodo_baseid(char *origbase)
for (i=0; i<=MAX_CURRENCIES; i++) for (i=0; i<=MAX_CURRENCIES; i++)
if ( strcmp(CURRENCIES[i],base) == 0 ) if ( strcmp(CURRENCIES[i],base) == 0 )
return(i); return(i);
printf("illegal base.(%s) %s\n",origbase,base); //printf("illegal base.(%s) %s\n",origbase,base);
return(-1); return(-1);
} }
int32_t komodo_is_issuer()
{
if ( ASSETCHAINS_SYMBOL[0] != 0 && komodo_baseid(ASSETCHAINS_SYMBOL) >= 0 )
return(1);
else return(0);
}
int32_t _unhex(char c) int32_t _unhex(char c)
{ {
if ( c >= '0' && c <= '9' ) if ( c >= '0' && c <= '9' )
@@ -1302,9 +1309,54 @@ void komodo_configfile(char *symbol,uint16_t port)
} else printf("couldnt open.(%s)\n",fname); } else printf("couldnt open.(%s)\n",fname);
} }
uint32_t komodo_assetmagic(char *symbol,uint64_t supply)
{
uint8_t buf[512]; int32_t len = 0;
len = iguana_rwnum(1,&buf[len],sizeof(supply),(void *)&supply);
strcpy((char *)&buf[len],symbol);
len += strlen(symbol);
return(calc_crc32(0,buf,len));
}
int32_t komodo_shortflag(char *symbol)
{
int32_t i,shortflag = 0;
if ( symbol[0] == '-' )
{
shortflag = 1;
for (i=0; symbol[i+1]!=0; i++)
symbol[i] = symbol[i+1];
symbol[i] = 0;
}
return(shortflag);
}
uint16_t komodo_assetport(uint32_t magic,int32_t shortflag)
{
return(8000 + shortflag*7777 + (magic % 7777));
}
uint16_t komodo_port(char *symbol,uint64_t supply,uint32_t *magicp,int32_t *shortflagp)
{
*magicp = komodo_assetmagic(symbol,supply);
*shortflagp = komodo_shortflag(symbol);
return(komodo_assetport(*magicp,*shortflagp));
}
void komodo_ports(uint16_t ports[MAX_CURRENCIES])
{
int32_t i,shortflag; uint32_t magic;
for (i=0; i<MAX_CURRENCIES; i++)
{
ports[i] = komodo_port(CURRENCIES[i],10,&magic,&shortflag);
printf("%u ",ports[i]);
}
printf("ports\n");
}
void komodo_args() void komodo_args()
{ {
std::string name; char *dirname; uint8_t buf[512]; int32_t i,len; std::string name; char *dirname; int32_t i,len;
IS_KOMODO_NOTARY = GetBoolArg("-notary", false); IS_KOMODO_NOTARY = GetBoolArg("-notary", false);
NOTARY_PUBKEY = GetArg("-pubkey", ""); NOTARY_PUBKEY = GetArg("-pubkey", "");
if ( strlen(NOTARY_PUBKEY.c_str()) == 66 ) if ( strlen(NOTARY_PUBKEY.c_str()) == 66 )
@@ -1314,17 +1366,7 @@ void komodo_args()
{ {
ASSETCHAINS_SUPPLY = GetArg("-ac_supply",10); ASSETCHAINS_SUPPLY = GetArg("-ac_supply",10);
strncpy(ASSETCHAINS_SYMBOL,name.c_str(),sizeof(ASSETCHAINS_SYMBOL)-1); strncpy(ASSETCHAINS_SYMBOL,name.c_str(),sizeof(ASSETCHAINS_SYMBOL)-1);
len = iguana_rwnum(1,&buf[len],sizeof(ASSETCHAINS_SUPPLY),(void *)&ASSETCHAINS_SUPPLY); ASSETCHAINS_PORT = komodo_port(ASSETCHAINS_SYMBOL,ASSETCHAINS_SUPPLY,&ASSETCHAINS_MAGIC,&ASSETCHAINS_SHORTFLAG);
strcpy((char *)&buf[len],ASSETCHAINS_SYMBOL);
len += strlen(ASSETCHAINS_SYMBOL);
ASSETCHAINS_MAGIC = calc_crc32(0,buf,len);
ASSETCHAINS_PORT = GetArg("-ac_port",8000 + (ASSETCHAINS_MAGIC % 7777));
if ( ASSETCHAINS_SYMBOL[0] == '-' )
{
ASSETCHAINS_SHORTFLAG = 1;
for (i=0; ASSETCHAINS_SYMBOL[i+1]!=0; i++)
ASSETCHAINS_SYMBOL[i] = ASSETCHAINS_SYMBOL[i+1];
}
//fprintf(stderr,"after args: %c%s port.%u magic.%08x supply.%u\n",ASSETCHAINS_SHORTFLAG!=0?'-':'+',ASSETCHAINS_SYMBOL,ASSETCHAINS_PORT,ASSETCHAINS_MAGIC,(int32_t)ASSETCHAINS_SUPPLY); //fprintf(stderr,"after args: %c%s port.%u magic.%08x supply.%u\n",ASSETCHAINS_SHORTFLAG!=0?'-':'+',ASSETCHAINS_SYMBOL,ASSETCHAINS_PORT,ASSETCHAINS_MAGIC,(int32_t)ASSETCHAINS_SUPPLY);
while ( (dirname= (char *)GetDataDir(false).string().c_str()) == 0 || dirname[0] == 0 ) while ( (dirname= (char *)GetDataDir(false).string().c_str()) == 0 || dirname[0] == 0 )
{ {
@@ -1344,7 +1386,7 @@ void komodo_args()
else else
{ {
ASSETCHAINS_PORT = 8777; ASSETCHAINS_PORT = 8777;
fprintf(stderr,"IS_KOMODO_NOTARY %d %s\n",IS_KOMODO_NOTARY,NOTARY_PUBKEY.c_str()); //fprintf(stderr,"IS_KOMODO_NOTARY %d %s\n",IS_KOMODO_NOTARY,NOTARY_PUBKEY.c_str());
} }
//fprintf(stderr,"%s chain params initialized\n",ASSETCHAINS_SYMBOL); //fprintf(stderr,"%s chain params initialized\n",ASSETCHAINS_SYMBOL);
} }

View File

@@ -550,9 +550,8 @@ CBlockTreeDB *pblocktree = NULL;
// Komodo globals // Komodo globals
#define KOMODO_TESTNET_EXPIRATION 60000 #define KOMODO_TESTNET_EXPIRATION 100000
//#define KOMODO_ENABLE_INTEREST enabling this is a hardfork #define KOMODO_ENABLE_INTEREST //enabling this is a hardfork
#define KOMODO_SOURCE "KMD"
#define KOMODO_PAX #define KOMODO_PAX
#define KOMODO_ZCASH #define KOMODO_ZCASH
#include "komodo.h" #include "komodo.h"
@@ -1470,16 +1469,31 @@ bool IsInitialBlockDownload()
const CChainParams& chainParams = Params(); const CChainParams& chainParams = Params();
LOCK(cs_main); LOCK(cs_main);
if (fImporting || fReindex) if (fImporting || fReindex)
{
//fprintf(stderr,"fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
return true; return true;
}
if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints())) if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
{
//fprintf(stderr,"checkpoint -> initialdownload\n");
return true; return true;
}
static bool lockIBDState = false; static bool lockIBDState = false;
if (lockIBDState) if (lockIBDState)
{
//fprintf(stderr,"lockIBDState true %d < %d\n",chainActive.Height(),pindexBestHeader->nHeight - 10);
return false; return false;
bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 || }
pindexBestHeader->GetBlockTime() < GetTime() - chainParams.MaxTipAge()); bool state;
if ( ASSETCHAINS_SYMBOL[0] == 0 )
state = (chainActive.Height() < pindexBestHeader->nHeight - 24*6) ||
pindexBestHeader->GetBlockTime() < (GetTime() - chainParams.MaxTipAge());
else state = (chainActive.Height() < pindexBestHeader->nHeight - 100);
if (!state) if (!state)
{
//fprintf(stderr,"lockIBDState tru\n");
lockIBDState = true; lockIBDState = true;
}
return state; return state;
} }
@@ -1621,8 +1635,8 @@ void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight) void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
{ {
// mark inputs spent if (!tx.IsCoinBase()) // mark inputs spent
if (!tx.IsCoinBase()) { {
txundo.vprevout.reserve(tx.vin.size()); txundo.vprevout.reserve(tx.vin.size());
BOOST_FOREACH(const CTxIn &txin, tx.vin) { BOOST_FOREACH(const CTxIn &txin, tx.vin) {
CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash); CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
@@ -1641,16 +1655,12 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
} }
} }
} }
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { // spend nullifiers
// spend nullifiers
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) { BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
inputs.SetNullifier(nf, true); inputs.SetNullifier(nf, true);
} }
} }
inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs
// add outputs
inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight);
} }
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight) void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight)
@@ -2243,7 +2253,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001); LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()); CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus());
if (block.vtx[0].GetValueOut() > blockReward) if (block.vtx[0].vout[0].nValue > blockReward)
//if (block.vtx[0].GetValueOut() > blockReward)
return state.DoS(100, return state.DoS(100,
error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)", error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
block.vtx[0].GetValueOut(), blockReward), block.vtx[0].GetValueOut(), blockReward),
@@ -3039,6 +3050,7 @@ bool CheckBlockHeader(int32_t height,CBlockIndex *pindex, const CBlockHeader& bl
return true; return true;
} }
int32_t komodo_check_deposit(int32_t height,const CBlock& block);
bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot) bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
{ {
// These are checks that are independent of context. // These are checks that are independent of context.
@@ -3095,7 +3107,8 @@ bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidat
if (nSigOps > MAX_BLOCK_SIGOPS) if (nSigOps > MAX_BLOCK_SIGOPS)
return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"), return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"),
REJECT_INVALID, "bad-blk-sigops", true); REJECT_INVALID, "bad-blk-sigops", true);
if ( komodo_check_deposit(height,block) < 0 )
return(false);
return true; return true;
} }
@@ -3302,8 +3315,10 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp) bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
{ {
// Preliminary checks // Preliminary checks
bool checked = CheckBlock(komodo_block2height(pblock),0,*pblock, state); bool checked;
if ( ASSETCHAINS_SYMBOL[0] == 0 )
checked = CheckBlock(komodo_block2height(pblock),0,*pblock, state);
else checked = CheckBlock(0,0,*pblock, state);
{ {
LOCK(cs_main); LOCK(cs_main);
bool fRequested = MarkBlockAsReceived(pblock->GetHash()); bool fRequested = MarkBlockAsReceived(pblock->GetHash());

View File

@@ -98,30 +98,35 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams,
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
} }
#define ASSETCHAINS_MINHEIGHT 100
int32_t komodo_pax_opreturn(uint8_t *opret,int32_t maxsize); int32_t komodo_pax_opreturn(uint8_t *opret,int32_t maxsize);
extern int32_t KOMODO_INITDONE; uint64_t komodo_paxtotal();
extern uint64_t KOMODO_DEPOSIT; int32_t komodo_is_issuer();
void komodo_gateway_deposits(CMutableTransaction *txNew,int32_t shortflag,char *symbol);
extern int32_t KOMODO_INITDONE,ASSETCHAINS_SHORTFLAG,KOMODO_REALTIME;
extern char ASSETCHAINS_SYMBOL[16]; extern char ASSETCHAINS_SYMBOL[16];
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
{ {
const CChainParams& chainparams = Params(); uint64_t deposits; const CChainParams& chainparams = Params();
// Create new block // Create new block
unique_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate()); unique_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
if(!pblocktemplate.get()) if(!pblocktemplate.get())
return NULL; return NULL;
CBlock *pblock = &pblocktemplate->block; // pointer for convenience CBlock *pblock = &pblocktemplate->block; // pointer for convenience
while ( ASSETCHAINS_SYMBOL[0] != 0 && chainActive.Tip()->nHeight > 10 && mempool.GetTotalTxSize() <= 0 ) if ( ASSETCHAINS_SYMBOL[0] != 0 )
fprintf(stderr,"start CreateNewBlock %s initdone.%d deposit %.8f mempool.%d RT.%u\n",ASSETCHAINS_SYMBOL,KOMODO_INITDONE,(double)komodo_paxtotal()/COIN,(int32_t)mempool.GetTotalTxSize(),KOMODO_REALTIME);
while ( mempool.GetTotalTxSize() <= 0 )
{ {
sleep(10); deposits = komodo_paxtotal();
if ( KOMODO_INITDONE == 0 || time(NULL) < KOMODO_INITDONE+60 ) if ( KOMODO_INITDONE == 0 || time(NULL) < KOMODO_INITDONE+60 || KOMODO_REALTIME == 0 )
continue; continue;
if ( KOMODO_DEPOSIT != 0 ) if ( deposits != 0 )
{
printf("KOMODO_DEPOSIT %llu pblock->nHeight %d mempool.GetTotalTxSize(%d)\n",(long long)KOMODO_DEPOSIT,(int32_t)chainActive.Tip()->nHeight,(int32_t)mempool.GetTotalTxSize());
break; break;
} sleep(10);
} }
if ( ASSETCHAINS_SYMBOL[0] != 0 )
printf("miner KOMODO_DEPOSIT %llu pblock->nHeight %d mempool.GetTotalTxSize(%d)\n",(long long)komodo_paxtotal(),(int32_t)chainActive.Tip()->nHeight,(int32_t)mempool.GetTotalTxSize());
// -regtest only: allow overriding block.nVersion with // -regtest only: allow overriding block.nVersion with
// -blockversion=N to test forking scenarios // -blockversion=N to test forking scenarios
@@ -320,8 +325,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
if (fPrintPriority) if (fPrintPriority)
{ {
LogPrintf("priority %.1f fee %s txid %s\n", LogPrintf("priority %.1f fee %s txid %s\n",dPriority, feeRate.ToString(), tx.GetHash().ToString());
dPriority, feeRate.ToString(), tx.GetHash().ToString());
} }
// Add transactions that depend on this one to the priority queue // Add transactions that depend on this one to the priority queue
@@ -351,27 +355,34 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
//txNew.nLockTime = (uint32_t)time(NULL) - 60; //txNew.nLockTime = (uint32_t)time(NULL) - 60;
txNew.vin.resize(1); txNew.vin.resize(1);
txNew.vin[0].prevout.SetNull(); txNew.vin[0].prevout.SetNull();
int32_t i,opretlen; uint8_t opret[256],*ptr; txNew.vout.resize(1);
if ( (opretlen= komodo_pax_opreturn(opret,sizeof(opret))) > 0 )
{
txNew.vout.resize(2);
txNew.vout[1].scriptPubKey.resize(opretlen);
ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data();
for (i=0; i<opretlen; i++)
ptr[i] = opret[i];
txNew.vout[1].nValue = 0;
//fprintf(stderr,"opretlen.%d\n",opretlen);
} else txNew.vout.resize(1);
txNew.vout[0].scriptPubKey = scriptPubKeyIn; txNew.vout[0].scriptPubKey = scriptPubKeyIn;
txNew.vout[0].nValue = GetBlockSubsidy(nHeight, chainparams.GetConsensus()); txNew.vout[0].nValue = GetBlockSubsidy(nHeight,chainparams.GetConsensus());
// Add fees // Add fees
txNew.vout[0].nValue += nFees; txNew.vout[0].nValue += nFees;
txNew.vin[0].scriptSig = CScript() << nHeight << OP_0; txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
int32_t i,opretlen; uint8_t opret[256],*ptr;
if ( (opretlen= komodo_pax_opreturn(opret,sizeof(opret))) > 0 )
{
txNew.vout.resize(2);
txNew.vout[1].scriptPubKey.resize(opretlen);
ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data();
for (i=0; i<opretlen; i++)
ptr[i] = opret[i];
txNew.vout[1].nValue = 0;
//fprintf(stderr,"opretlen.%d\n",opretlen);
}
komodo_gateway_deposits(&txNew,0,(char *)"EUR");
}
else if ( komodo_is_issuer() != 0 )
{
komodo_gateway_deposits(&txNew,0,ASSETCHAINS_SYMBOL);
fprintf(stderr,"txNew numvouts.%d\n",(int32_t)txNew.vout.size());
}
pblock->vtx[0] = txNew; pblock->vtx[0] = txNew;
pblocktemplate->vTxFees[0] = -nFees; pblocktemplate->vTxFees[0] = -nFees;
// Randomise nonce // Randomise nonce
arith_uint256 nonce = UintToArith256(GetRandHash()); arith_uint256 nonce = UintToArith256(GetRandHash());
// Clear the top and bottom 16 bits (for local use as thread flags and counters) // Clear the top and bottom 16 bits (for local use as thread flags and counters)
@@ -430,15 +441,25 @@ int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33)
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
{ {
CPubKey pubkey; CScript scriptPubKey; CPubKey pubkey; CScript scriptPubKey; uint8_t *script,*ptr; int32_t i;
if (!reservekey.GetReservedKey(pubkey))
return NULL;
scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
if ( USE_EXTERNAL_PUBKEY != 0 ) if ( USE_EXTERNAL_PUBKEY != 0 )
{ {
//fprintf(stderr,"use notary pubkey\n"); //fprintf(stderr,"use notary pubkey\n");
scriptPubKey = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG; scriptPubKey = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG;
} }
else
{
if (!reservekey.GetReservedKey(pubkey))
return NULL;
scriptPubKey.resize(35);
ptr = (uint8_t *)pubkey.begin();
script = (uint8_t *)scriptPubKey.data();
script[0] = 33;
for (i=0; i<33; i++)
script[i+1] = ptr[i];
script[34] = OP_CHECKSIG;
//scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
}
return CreateNewBlock(scriptPubKey); return CreateNewBlock(scriptPubKey);
} }
@@ -487,11 +508,22 @@ void static BitcoinMiner(CWallet *pwallet)
unsigned int n = chainparams.EquihashN(); unsigned int n = chainparams.EquihashN();
unsigned int k = chainparams.EquihashK(); unsigned int k = chainparams.EquihashK();
extern int32_t ASSETCHAIN_INIT,KOMODO_INITDONE; extern uint8_t NOTARY_PUBKEY33[33];
int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33);
int32_t notaryid = -1;
while ( ASSETCHAIN_INIT == 0 || KOMODO_INITDONE == 0 )
{
sleep(1);
}
komodo_chosennotary(&notaryid,chainActive.Tip()->nHeight,NOTARY_PUBKEY33);
std::string solver = GetArg("-equihashsolver", "tromp"); std::string solver;
if ( notaryid >= 0 || ASSETCHAINS_SYMBOL[0] != 0 )
solver = "tromp";
else solver = "default";
assert(solver == "tromp" || solver == "default"); assert(solver == "tromp" || solver == "default");
LogPrint("pow", "Using Equihash solver \"%s\" with n = %u, k = %u\n", solver, n, k); LogPrint("pow", "Using Equihash solver \"%s\" with n = %u, k = %u\n", solver, n, k);
//fprintf(stderr,"Mining with %s\n",solver.c_str()); fprintf(stderr,"Mining with %s\n",solver.c_str());
std::mutex m_cs; std::mutex m_cs;
bool cancelSolver = false; bool cancelSolver = false;
boost::signals2::connection c = uiInterface.NotifyBlockTip.connect( boost::signals2::connection c = uiInterface.NotifyBlockTip.connect(
@@ -502,6 +534,7 @@ void static BitcoinMiner(CWallet *pwallet)
); );
try { try {
//fprintf(stderr,"try %s Mining with %s\n",ASSETCHAINS_SYMBOL,solver.c_str());
while (true) while (true)
{ {
if (chainparams.MiningRequiresPeers()) if (chainparams.MiningRequiresPeers())
@@ -517,11 +550,14 @@ void static BitcoinMiner(CWallet *pwallet)
} }
if (!fvNodesEmpty && !IsInitialBlockDownload()) if (!fvNodesEmpty && !IsInitialBlockDownload())
break; break;
MilliSleep(1000); MilliSleep(5000);
//fprintf(stderr,"fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,ASSETCHAINS_SYMBOL,(int32_t)IsInitialBlockDownload());
} while (true); } while (true);
//fprintf(stderr,"Found peers\n"); //fprintf(stderr,"%s Found peers\n",ASSETCHAINS_SYMBOL);
} }
//fprintf(stderr,"create new block\n"); //if ( ASSETCHAINS_SYMBOL[0] != 0 )
// fprintf(stderr,"%s create new block\n",ASSETCHAINS_SYMBOL);
// //
// Create new block // Create new block
// //
@@ -537,24 +573,23 @@ void static BitcoinMiner(CWallet *pwallet)
} }
CBlock *pblock = &pblocktemplate->block; CBlock *pblock = &pblocktemplate->block;
IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
LogPrintf("Running ZcashMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(), LogPrintf("Running ZcashMiner.%s with %u transactions in block (%u bytes)\n",solver.c_str(),pblock->vtx.size(),::GetSerializeSize(*pblock,SER_NETWORK,PROTOCOL_VERSION));
::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
// //
// Search // Search
// //
int32_t notaryid; uint32_t savebits; int64_t nStart = GetTime(); int32_t notaryid; uint32_t savebits; int64_t nStart = GetTime();
savebits = pblock->nBits; savebits = pblock->nBits;
arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
if ( komodo_chosennotary(&notaryid,pindexPrev->nHeight+1,NOTARY_PUBKEY33) > 0 ) if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_chosennotary(&notaryid,pindexPrev->nHeight+1,NOTARY_PUBKEY33) > 0 )
{ {
hashTarget = arith_uint256().SetCompact(KOMODO_MINDIFF_NBITS); hashTarget = arith_uint256().SetCompact(KOMODO_MINDIFF_NBITS);
Mining_start = (uint32_t)time(NULL); Mining_start = (uint32_t)time(NULL);
//fprintf(stderr,"I am the chosen one for ht.%d\n",pindexPrev->nHeight+1); fprintf(stderr,"I am the chosen one for %s ht.%d\n",ASSETCHAINS_SYMBOL,pindexPrev->nHeight+1);
} else Mining_start = 0; } else Mining_start = 0;
Mining_height = pindexPrev->nHeight+1; Mining_height = pindexPrev->nHeight+1;
while (true) while (true)
{ {
//fprintf(stderr,"%s start mining loop\n",ASSETCHAINS_SYMBOL);
// Hash state // Hash state
crypto_generichash_blake2b_state state; crypto_generichash_blake2b_state state;
EhInitialiseState(n, k, state); EhInitialiseState(n, k, state);
@@ -568,23 +603,26 @@ void static BitcoinMiner(CWallet *pwallet)
crypto_generichash_blake2b_state curr_state; crypto_generichash_blake2b_state curr_state;
curr_state = state; curr_state = state;
crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size()); crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size());
// (x_1, x_2, ...) = A(I, V, n, k) // (x_1, x_2, ...) = A(I, V, n, k)
LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString()); LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
std::function<bool(std::vector<unsigned char>)> validBlock = std::function<bool(std::vector<unsigned char>)> validBlock =
[&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams] [&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams]
(std::vector<unsigned char> soln) { (std::vector<unsigned char> soln)
{
// Write the solution to the hash and compute the result. // Write the solution to the hash and compute the result.
LogPrint("pow", "- Checking solution against target\n"); LogPrint("pow", "- Checking solution against target\n");
pblock->nSolution = soln; pblock->nSolution = soln;
solutionTargetChecks.increment(); solutionTargetChecks.increment();
if ( UintToArith256(pblock->GetHash()) > hashTarget ) if ( UintToArith256(pblock->GetHash()) > hashTarget )
return false;
if ( Mining_start != 0 && time(NULL) < Mining_start+50 )
{ {
printf("Round robin diff sleep %d\n",(int32_t)(Mining_start+50-time(NULL))); //if ( ASSETCHAINS_SYMBOL[0] != 0 )
sleep(Mining_start+50-time(NULL)); // printf("missed target\n");
return false;
}
if ( ASSETCHAINS_SYMBOL[0] == 0 && Mining_start != 0 && time(NULL) < Mining_start+20 )
{
printf("Round robin diff sleep %d\n",(int32_t)(Mining_start+20-time(NULL)));
sleep(Mining_start+20-time(NULL));
} }
// Found a solution // Found a solution
SetThreadPriority(THREAD_PRIORITY_NORMAL); SetThreadPriority(THREAD_PRIORITY_NORMAL);
@@ -595,7 +633,10 @@ void static BitcoinMiner(CWallet *pwallet)
std::lock_guard<std::mutex> lock{m_cs}; std::lock_guard<std::mutex> lock{m_cs};
cancelSolver = false; cancelSolver = false;
} }
fprintf(stderr,"%s Block found %d\n",ASSETCHAINS_SYMBOL,Mining_height); int32_t i; uint256 hash = pblock->GetHash();
for (i=0; i<32; i++)
fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
fprintf(stderr," <- %s Block found %d\n",ASSETCHAINS_SYMBOL,Mining_height);
SetThreadPriority(THREAD_PRIORITY_LOWEST); SetThreadPriority(THREAD_PRIORITY_LOWEST);
// In regression test mode, stop mining after a block is found. // In regression test mode, stop mining after a block is found.
if (chainparams.MineBlocksOnDemand()) { if (chainparams.MineBlocksOnDemand()) {
@@ -611,7 +652,7 @@ void static BitcoinMiner(CWallet *pwallet)
}; };
// TODO: factor this out into a function with the same API for each solver. // TODO: factor this out into a function with the same API for each solver.
if (solver == "tromp") { if (solver == "tromp" && notaryid >= 0 ) {
// Create solver and initialize it. // Create solver and initialize it.
equi eq(1); equi eq(1);
eq.setstate(&curr_state); eq.setstate(&curr_state);
@@ -662,14 +703,29 @@ void static BitcoinMiner(CWallet *pwallet)
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
// Regtest mode doesn't require peers // Regtest mode doesn't require peers
if (vNodes.empty() && chainparams.MiningRequiresPeers()) if (vNodes.empty() && chainparams.MiningRequiresPeers())
{
if ( ASSETCHAINS_SYMBOL[0] != 0 )
printf("no nodes, break\n");
break; break;
}
if ((UintToArith256(pblock->nNonce) & 0xffff) == 0xffff) if ((UintToArith256(pblock->nNonce) & 0xffff) == 0xffff)
{
if ( ASSETCHAINS_SYMBOL[0] != 0 )
printf("0xffff, break\n");
break; break;
}
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60) if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
{
if ( ASSETCHAINS_SYMBOL[0] != 0 )
printf("timeout, break\n");
break; break;
if (pindexPrev != chainActive.Tip()) }
if ( pindexPrev != chainActive.Tip() )
{
if ( ASSETCHAINS_SYMBOL[0] != 0 )
printf("Tip advanced, break\n");
break; break;
}
// Update nNonce and nTime // Update nNonce and nTime
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1); pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
pblock->nBits = savebits; pblock->nBits = savebits;

View File

@@ -382,24 +382,69 @@ Value gettxoutsetinfo(const Array& params, bool fHelp)
uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
uint32_t komodo_txtime(uint256 hash); uint32_t komodo_txtime(uint256 hash);
uint64_t komodo_paxprice(int32_t height,char *base,char *rel,uint64_t basevolume); uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume);
int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel); int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel);
int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height);
char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len);
Value notaries(const Array& params, bool fHelp)
{
Array a; Object ret; int32_t i,j,n,m; char *hexstr; uint8_t pubkeys[64][33]; char btcaddr[64],kmdaddr[64],*ptr;
if ( fHelp || params.size() != 1 )
throw runtime_error("notaries height\n");
LOCK(cs_main);
int32_t height = atoi(params[0].get_str().c_str());
if ( height < 0 || height > chainActive.Height()+2000 )
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
else
{
if ( (n= komodo_notaries(pubkeys,height)) > 0 )
{
for (i=0; i<n; i++)
{
Object item;
std::string btcaddress,kmdaddress,hex;
bitcoin_address(btcaddr,0,pubkeys[i],33);
m = (int32_t)strlen(btcaddr);
btcaddress.resize(m);
ptr = (char *)btcaddress.data();
memcpy(ptr,btcaddr,n);
bitcoin_address(kmdaddr,60,pubkeys[i],33);
m = (int32_t)strlen(kmdaddr);
kmdaddress.resize(m);
ptr = (char *)kmdaddress.data();
memcpy(ptr,kmdaddr,m);
hex.resize(66);
hexstr = (char *)hex.data();
for (j=0; j<33; j++)
sprintf(&hexstr[j*2],"%02x",pubkeys[i][j]);
item.push_back(Pair("pubkey", hex));
item.push_back(Pair("BTCaddress", btcaddress));
item.push_back(Pair("KMDaddress", kmdaddress));
a.push_back(item);
}
}
ret.push_back(Pair("notaries", a));
}
return ret;
}
Value paxprice(const Array& params, bool fHelp) Value paxprice(const Array& params, bool fHelp)
{ {
if ( fHelp || params.size() < 3 || params.size() > 4 ) if ( fHelp || params.size() < 3 || params.size() > 4 )
throw runtime_error("paxprice \"base\" \"rel\" height amount\n"); throw runtime_error("paxprice \"base\" \"rel\" height amount\n");
LOCK(cs_main); LOCK(cs_main);
Object ret; uint64_t basevolume=0,relvolume; Object ret; uint64_t basevolume=0,relvolume,seed;
std::string base = params[0].get_str(); std::string base = params[0].get_str();
std::string rel = params[1].get_str(); std::string rel = params[1].get_str();
int32_t height = atoi(params[2].get_str().c_str()); int32_t height = atoi(params[2].get_str().c_str());
if ( params.size() == 3 || (basevolume= COIN * atof(params[3].get_str().c_str())) == 0 ) if ( params.size() == 3 || (basevolume= COIN * atof(params[3].get_str().c_str())) == 0 )
basevolume = COIN; basevolume = COIN;
relvolume = komodo_paxprice(height,(char *)base.c_str(),(char *)rel.c_str(),basevolume); relvolume = komodo_paxprice(&seed,height,(char *)base.c_str(),(char *)rel.c_str(),basevolume);
ret.push_back(Pair("base", base)); ret.push_back(Pair("base", base));
ret.push_back(Pair("rel", rel)); ret.push_back(Pair("rel", rel));
ret.push_back(Pair("height", height)); ret.push_back(Pair("height", height));
ret.push_back(Pair("seed", seed));
if ( height < 0 || height > chainActive.Height() ) if ( height < 0 || height > chainActive.Height() )
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
else else

View File

@@ -107,7 +107,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "z_getoperationresult", 0}, { "z_getoperationresult", 0},
{ "z_importkey", 1 }, { "z_importkey", 1 },
{ "paxprice", 4 }, { "paxprice", 4 },
{ "paxprice2", 3 }, { "paxprices", 3 },
{ "notaries", 1 },
}; };
class CRPCConvertTable class CRPCConvertTable

View File

@@ -605,15 +605,14 @@ Value getblocktemplate(const Array& params, bool fHelp)
if (tx.IsCoinBase()) { if (tx.IsCoinBase()) {
// Show founders' reward if it is required // Show founders' reward if it is required
if (pblock->vtx[0].vout.size() > 1) { //if (pblock->vtx[0].vout.size() > 1) {
// Correct this if GetBlockTemplate changes the order // Correct this if GetBlockTemplate changes the order
entry.push_back(Pair("foundersreward", (int64_t)tx.vout[1].nValue)); // entry.push_back(Pair("foundersreward", (int64_t)tx.vout[1].nValue));
} //}
entry.push_back(Pair("required", true)); entry.push_back(Pair("required", true));
txCoinbase = entry; txCoinbase = entry;
} else { } else
transactions.push_back(entry); transactions.push_back(entry);
}
} }
Object aux; Object aux;
@@ -804,8 +803,7 @@ Value getblocksubsidy(const Array& params, bool fHelp)
"1. height (numeric, optional) The block height. If not provided, defaults to the current height of the chain.\n" "1. height (numeric, optional) The block height. If not provided, defaults to the current height of the chain.\n"
"\nResult:\n" "\nResult:\n"
"{\n" "{\n"
" \"miner\" : x.xxx (numeric) The mining reward amount in ZEC.\n" " \"miner\" : x.xxx (numeric) The mining reward amount in KMD.\n"
" \"founders\" : x.xxx (numeric) The founders reward amount in ZEC.\n"
"}\n" "}\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("getblocksubsidy", "1000") + HelpExampleCli("getblocksubsidy", "1000")

View File

@@ -302,6 +302,7 @@ static const CRPCCommand vRPCCommands[] =
{ "blockchain", "verifychain", &verifychain, true }, { "blockchain", "verifychain", &verifychain, true },
{ "blockchain", "paxprice", &paxprice, true }, { "blockchain", "paxprice", &paxprice, true },
{ "blockchain", "paxprices", &paxprices, true }, { "blockchain", "paxprices", &paxprices, true },
{ "blockchain", "notaries", &notaries, true },
/* Mining */ /* Mining */
{ "mining", "getblocktemplate", &getblocktemplate, true }, { "mining", "getblocktemplate", &getblocktemplate, true },
@@ -401,7 +402,8 @@ static const CRPCCommand vRPCCommands[] =
{ "wallet", "z_exportwallet", &z_exportwallet, true }, { "wallet", "z_exportwallet", &z_exportwallet, true },
{ "wallet", "z_importwallet", &z_importwallet, true }, { "wallet", "z_importwallet", &z_importwallet, true },
{ "wallet", "paxdeposit", &paxdeposit, true } { "wallet", "paxdeposit", &paxdeposit, true },
{ "wallet", "paxwithdraw", &paxwithdraw, true }
#endif // ENABLE_WALLET #endif // ENABLE_WALLET
}; };
@@ -965,15 +967,16 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush; conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
return false; return false;
} }
JSONRequest jreq; JSONRequest jreq;
try try
{ {
// Parse request // Parse request
Value valRequest; Value valRequest;
if (!read_string(strRequest, valRequest)) if (!read_string(strRequest, valRequest))
{
fprintf(stderr,"CANTPARSE.(%s)\n",strRequest.c_str());
throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
}
// Return immediately if in warmup // Return immediately if in warmup
{ {
LOCK(cs_rpcWarmup); LOCK(cs_rpcWarmup);

View File

@@ -243,9 +243,11 @@ extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fH
extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value notaries(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value paxprice(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value paxprice(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value paxprices(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value paxprices(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value paxdeposit(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value paxdeposit(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value paxwithdraw(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp);

View File

@@ -401,19 +401,27 @@ void PrintExceptionContinue(const std::exception* pex, const char* pszThread)
} }
extern char ASSETCHAINS_SYMBOL[16]; extern char ASSETCHAINS_SYMBOL[16];
extern int32_t ASSETCHAINS_SHORTFLAG;
boost::filesystem::path GetDefaultDataDir() boost::filesystem::path GetDefaultDataDir()
{ {
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
char symbol[16];
if ( ASSETCHAINS_SYMBOL[0] != 0 )
{
if ( ASSETCHAINS_SHORTFLAG != 0 )
sprintf(symbol,"-%s",ASSETCHAINS_SYMBOL);
else strcpy(symbol,ASSETCHAINS_SYMBOL);
} else symbol[0] = 0;
// Windows < Vista: C:\Documents and Settings\Username\Application Data\Zcash // Windows < Vista: C:\Documents and Settings\Username\Application Data\Zcash
// Windows >= Vista: C:\Users\Username\AppData\Roaming\Zcash // Windows >= Vista: C:\Users\Username\AppData\Roaming\Zcash
// Mac: ~/Library/Application Support/Zcash // Mac: ~/Library/Application Support/Zcash
// Unix: ~/.zcash // Unix: ~/.zcash
#ifdef WIN32 #ifdef WIN32
// Windows // Windows
if ( ASSETCHAINS_SYMBOL[0] == 0 ) if ( symbol[0] == 0 )
return GetSpecialFolderPath(CSIDL_APPDATA) / "Komodo"; return GetSpecialFolderPath(CSIDL_APPDATA) / "Komodo";
else return GetSpecialFolderPath(CSIDL_APPDATA) / "Komodo" / ASSETCHAINS_SYMBOL; else return GetSpecialFolderPath(CSIDL_APPDATA) / "Komodo" / symbol;
#else #else
fs::path pathRet; fs::path pathRet;
char* pszHome = getenv("HOME"); char* pszHome = getenv("HOME");
@@ -425,19 +433,19 @@ boost::filesystem::path GetDefaultDataDir()
// Mac // Mac
pathRet /= "Library/Application Support"; pathRet /= "Library/Application Support";
TryCreateDirectory(pathRet); TryCreateDirectory(pathRet);
if ( ASSETCHAINS_SYMBOL[0] == 0 ) if ( symbol[0] == 0 )
return pathRet / "Komodo"; return pathRet / "Komodo";
else else
{ {
pathRet /= "Komodo"; pathRet /= "Komodo";
TryCreateDirectory(pathRet); TryCreateDirectory(pathRet);
return pathRet / ASSETCHAINS_SYMBOL; return pathRet / symbol;
} }
#else #else
// Unix // Unix
if ( ASSETCHAINS_SYMBOL[0] == 0 ) if ( symbol[0] == 0 )
return pathRet / ".komodo"; return pathRet / ".komodo";
else return pathRet / ".komodo" / ASSETCHAINS_SYMBOL; else return pathRet / ".komodo" / symbol;
#endif #endif
#endif #endif
} }

View File

@@ -466,14 +466,19 @@ Value sendtoaddress(const Array& params, bool fHelp)
return wtx.GetHash().GetHex(); return wtx.GetHash().GetHex();
} }
uint64_t PAX_fiatdest(int32_t tokomodo,char *destaddr,uint8_t pubkey33[33],char *coinaddr,int32_t height,char *base,int64_t fiatoshis); uint64_t PAX_fiatdest(uint64_t *seedp,int32_t tokomodo,char *destaddr,uint8_t pubkey37[37],char *coinaddr,int32_t height,char *base,int64_t fiatoshis);
int32_t komodo_opreturnscript(uint8_t *script,uint8_t type,uint8_t *opret,int32_t opretlen); int32_t komodo_opreturnscript(uint8_t *script,uint8_t type,uint8_t *opret,int32_t opretlen);
#define CRYPTO777_KMDADDR "RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA" #define CRYPTO777_KMDADDR "RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA"
extern char ASSETCHAINS_SYMBOL[16];
int32_t komodo_is_issuer();
int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp);
Value paxdeposit(const Array& params, bool fHelp) Value paxdeposit(const Array& params, bool fHelp)
{ {
uint64_t komodoshis = 0; char destaddr[64]; uint8_t i,pubkey33[33]; uint64_t seed,komodoshis = 0; int32_t height; char destaddr[64]; uint8_t i,pubkey37[33];
bool fSubtractFeeFromAmount = false; bool fSubtractFeeFromAmount = false;
if ( komodo_is_issuer() != 0 )
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "paxdeposit only from KMD");
if (!EnsureWalletIsAvailable(fHelp)) if (!EnsureWalletIsAvailable(fHelp))
return Value::null; return Value::null;
if (fHelp || params.size() != 3) if (fHelp || params.size() != 3)
@@ -485,25 +490,62 @@ Value paxdeposit(const Array& params, bool fHelp)
int64_t fiatoshis = atof(params[1].get_str().c_str()) * COIN; int64_t fiatoshis = atof(params[1].get_str().c_str()) * COIN;
std::string base = params[2].get_str(); std::string base = params[2].get_str();
std::string dest; std::string dest;
komodoshis = PAX_fiatdest(0,destaddr,pubkey33,(char *)params[0].get_str().c_str(),chainActive.Tip()->nHeight,(char *)base.c_str(),fiatoshis); height = chainActive.Tip()->nHeight;
komodoshis = PAX_fiatdest(&seed,0,destaddr,pubkey37,(char *)params[0].get_str().c_str(),height,(char *)base.c_str(),fiatoshis);
dest.append(destaddr); dest.append(destaddr);
CBitcoinAddress destaddress(CRYPTO777_KMDADDR); CBitcoinAddress destaddress(CRYPTO777_KMDADDR);
if (!destaddress.IsValid()) if (!destaddress.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid dest Bitcoin address"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid dest Bitcoin address");
for (i=0; i<33; i++) for (i=0; i<33; i++)
printf("%02x",pubkey33[i]); printf("%02x",pubkey37[i]);
printf(" ht.%d srcaddr.(%s) %s fiatoshis.%lld -> dest.(%s) komodoshis.%llu\n",chainActive.Tip()->nHeight,(char *)params[0].get_str().c_str(),(char *)base.c_str(),(long long)fiatoshis,destaddr,(long long)komodoshis); printf(" ht.%d srcaddr.(%s) %s fiatoshis.%lld -> dest.(%s) komodoshis.%llu seed.%llx\n",height,(char *)params[0].get_str().c_str(),(char *)base.c_str(),(long long)fiatoshis,destaddr,(long long)komodoshis,(long long)seed);
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked();
CWalletTx wtx; CWalletTx wtx;
uint8_t opretbuf[64]; int32_t opretlen; uint64_t fee = komodoshis / 1000; uint8_t opretbuf[64]; int32_t opretlen; uint64_t fee = komodoshis / 1000;
if ( fee < 10000 ) if ( fee < 10000 )
fee = 10000; fee = 10000;
opretlen = komodo_opreturnscript(opretbuf,'D',pubkey33,33); iguana_rwnum(1,&pubkey37[33],sizeof(height),&height);
opretlen = komodo_opreturnscript(opretbuf,'D',pubkey37,37);
SendMoney(address.Get(),fee,fSubtractFeeFromAmount,wtx,opretbuf,opretlen,komodoshis); SendMoney(address.Get(),fee,fSubtractFeeFromAmount,wtx,opretbuf,opretlen,komodoshis);
return wtx.GetHash().GetHex(); return wtx.GetHash().GetHex();
} }
Value paxwithdraw(const Array& params, bool fHelp)
{
extern int32_t KMDHEIGHT,KOMODO_REALTIME;
CWalletTx wtx; std::string dest; int32_t height; uint64_t seed,komodoshis = 0; char destaddr[64]; uint8_t i,pubkey37[37]; bool fSubtractFeeFromAmount = false;
if ( ASSETCHAINS_SYMBOL[0] == 0 )
return(0);
if (!EnsureWalletIsAvailable(fHelp))
return 0;
if (fHelp || params.size() != 2)
throw runtime_error("paxwithdraw \"address\" fiatamount");
if ( KOMODO_REALTIME == 0 )
return(0);
LOCK2(cs_main, pwalletMain->cs_wallet);
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
int64_t fiatoshis = atof(params[1].get_str().c_str()) * COIN;
komodoshis = PAX_fiatdest(&seed,1,destaddr,pubkey37,(char *)params[0].get_str().c_str(),KMDHEIGHT,ASSETCHAINS_SYMBOL,fiatoshis);
dest.append(destaddr);
CBitcoinAddress destaddress(CRYPTO777_KMDADDR);
if (!destaddress.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid dest Bitcoin address");
for (i=0; i<33; i++)
printf("%02x",pubkey37[i]);
height = KMDHEIGHT;
printf(" ht.%d srcaddr.(%s) %s fiatoshis.%lld -> dest.(%s) komodoshis.%llu seed.%llx\n",height,(char *)params[0].get_str().c_str(),ASSETCHAINS_SYMBOL,(long long)fiatoshis,destaddr,(long long)komodoshis,(long long)seed);
EnsureWalletIsUnlocked();
uint8_t opretbuf[64]; int32_t opretlen; uint64_t fee = komodoshis / 1000;
if ( fee < 10000 )
fee = 10000;
iguana_rwnum(1,&pubkey37[33],sizeof(height),&height);
opretlen = komodo_opreturnscript(opretbuf,'W',pubkey37,37);
SendMoney(destaddress.Get(),fee,fSubtractFeeFromAmount,wtx,opretbuf,opretlen,fiatoshis);
return wtx.GetHash().GetHex();
}
Value listaddressgroupings(const Array& params, bool fHelp) Value listaddressgroupings(const Array& params, bool fHelp)
{ {
if (!EnsureWalletIsAvailable(fHelp)) if (!EnsureWalletIsAvailable(fHelp))

View File

@@ -2392,6 +2392,7 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure) // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
if (coinControl && coinControl->HasSelected()) if (coinControl && coinControl->HasSelected())
{ {
extern char ASSETCHAINS_SYMBOL[16];
uint64_t interest; uint64_t interest;
BOOST_FOREACH(const COutput& out, vCoins) BOOST_FOREACH(const COutput& out, vCoins)
{ {
@@ -2400,7 +2401,8 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*
nValueRet += out.tx->vout[out.i].nValue; nValueRet += out.tx->vout[out.i].nValue;
interest = komodo_interest(chainActive.Tip()->nHeight,out.tx->vout[out.i].nValue,out.tx->nLockTime,chainActive.Tip()->nTime); interest = komodo_interest(chainActive.Tip()->nHeight,out.tx->vout[out.i].nValue,out.tx->nLockTime,chainActive.Tip()->nTime);
#ifdef KOMODO_ENABLE_INTEREST #ifdef KOMODO_ENABLE_INTEREST
nValueRet += interest; if ( ASSETCHAINS_SYMBOL[0] == 0 && txheight >= 60000 )
nValueRet += interest;
#endif #endif
fprintf(stderr,"interest %llu from %llu lock.%u tip.%u\n",(long long)interest,(long long)out.tx->vout[out.i].nValue,out.tx->nLockTime,chainActive.Tip()->nTime); fprintf(stderr,"interest %llu from %llu lock.%u tip.%u\n",(long long)interest,(long long)out.tx->vout[out.i].nValue,out.tx->nLockTime,chainActive.Tip()->nTime);
setCoinsRet.insert(make_pair(out.tx, out.i)); setCoinsRet.insert(make_pair(out.tx, out.i));

View File

@@ -58,7 +58,7 @@ static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000;
//! Size of witness cache //! Size of witness cache
// Should be large enough that we can expect not to reorg beyond our cache // Should be large enough that we can expect not to reorg beyond our cache
// unless there is some exceptional network disruption. // unless there is some exceptional network disruption.
static const unsigned int WITNESS_CACHE_SIZE = COINBASE_MATURITY; static const unsigned int WITNESS_CACHE_SIZE = COINBASE_MATURITY+1;
class CAccountingEntry; class CAccountingEntry;
class CBlockIndex; class CBlockIndex;