From fab7660527b9772a43bbb4c04b63cd622e682b23 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 24 Jun 2022 22:58:41 +0300 Subject: [PATCH 01/27] log numvalid for a notarisation tx candidate as well for KMD chain minsigs to count nota tx as valid nota is 13, but for assetchains (ACs) it could be 7 or 11, depends on current height. this change allows to log how much valid signatures exists in nota tx candidate. for example this nota tx: https://pirate.explorer.dexstats.info/tx/32023e1e396ce5a7ba00bd3f6bc7d619c92bce052cf1b5fc2081b30466004124 in PIRATE chain have only 11 valid signatures: ``` 2022-06-24 19:51:29 [PIRATE] ht.1957772 txi.1 signedmask.100400000382e5 numvins.13 numvalid.11 numvouts.2 <<<<<<<<<<< notarized ``` as the following signatures/keys: ``` RGdxqk4hSBtGX9XxdBNMEKuupigrPra5Ju (pbca26_NA, S5) RLqnbAwfucQEcSzcBXEXAavLTtL1FrWxqJ (webworker01_NA, S5) ``` doesn't exists in S6, but tx anyway counted as valid nota: ``` [PIRATE] matched.1 VALID (PIRATE) MoM.af0b2f2372dd85a1074651fcf775076679668a35b7a16236628095a885b02b34 [40] CCid.0 [PIRATE] ht.1957772 NOTARIZED.1957764 PIRATE.0000000037bf4b6de7ab49c7a332e5f02fcd98a12f4c75106159c5b89381cd0c KMDTXID.11216cfb3fed63a9bd0d44672f983d671b5fe3797de96a4feb5c87b1a238d769 lens.(111 114) MoM.af0b2f2372dd85a1074651fcf775076679668a35b7a16236628095a885b02b34 40 ``` bcs 11 sigs is allowed for ACs too. --- src/komodo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/komodo.cpp b/src/komodo.cpp index 608bc367..18b06b31 100644 --- a/src/komodo.cpp +++ b/src/komodo.cpp @@ -707,7 +707,7 @@ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) fflush(signedfp); } transaction = i; - LogPrintf("[%s] ht.%d txi.%d signedmask.%llx numvins.%d numvouts.%d <<<<<<<<<<< notarized\n",ASSETCHAINS_SYMBOL,height,i,(long long)signedmask,numvins,numvouts); + LogPrintf("[%s] ht.%d txi.%d signedmask.%llx numvins.%d numvalid.%d numvouts.%d <<<<<<<<<<< notarized\n",ASSETCHAINS_SYMBOL,height,i,(long long)signedmask,numvins,numvalid,numvouts); } notarized = 1; } From 1bccb82383fcafd71903292f617fac7e4e46c882 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Tue, 16 Aug 2022 13:36:34 +0300 Subject: [PATCH 02/27] Avoid SIGSEGV in tromp solver https://github.com/KomodoPlatform/komodo/pull/556 https://github.com/tromp/equihash/commit/882bc1ff7a49b92ad9d80a7a59aaa159ecdc2ce0 - fix MAXSOLS bug https://github.com/zcash/zcash/pull/6114 --- src/Makefile.ktest.include | 3 +- src/miner.cpp | 92 +++++++++++++++++++++++++++++++------- 2 files changed, 79 insertions(+), 16 deletions(-) diff --git a/src/Makefile.ktest.include b/src/Makefile.ktest.include index 0d8a185d..f665d786 100644 --- a/src/Makefile.ktest.include +++ b/src/Makefile.ktest.include @@ -19,7 +19,8 @@ komodo_test_SOURCES = \ test-komodo/test_netbase_tests.cpp \ test-komodo/test_events.cpp \ test-komodo/test_hex.cpp \ - test-komodo/test_haraka_removal.cpp + test-komodo/test_haraka_removal.cpp \ + test-komodo/test_miner.cpp komodo_test_CPPFLAGS = $(komodod_CPPFLAGS) diff --git a/src/miner.cpp b/src/miner.cpp index 0303b60a..0a8e7ced 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1197,6 +1197,27 @@ CBlockIndex *get_chainactive(int32_t height) int32_t gotinvalid; extern int32_t getkmdseason(int32_t height); +bool check_tromp_solution(equi &eq, std::function)> validBlock) +{ + // Convert solution indices to byte array (decompress) and pass it to validBlock method. + for (size_t s = 0; s < std::min(MAXSOLS, eq.nsols); s++) + { + LogPrint("pow", "Checking solution %d\n", s+1); + std::vector index_vector(PROOFSIZE); + for (size_t i = 0; i < PROOFSIZE; i++) { + index_vector[i] = eq.sols[s][i]; + } + std::vector sol_char = GetMinimalFromIndices(index_vector, DIGITBITS); + + if (validBlock(sol_char)) { + // If we find a POW solution, do not try other solutions + // because they become invalid as we created a new block in blockchain. + return true; + } + } + return false; +} + #ifdef ENABLE_WALLET void static BitcoinMiner(CWallet *pwallet) #else @@ -1644,21 +1665,8 @@ void static BitcoinMiner() eq.digitK(0); ehSolverRuns.increment(); - // Convert solution indices to byte array (decompress) and pass it to validBlock method. - for (size_t s = 0; s < eq.nsols; s++) { - LogPrint("pow", "Checking solution %d\n", s+1); - std::vector index_vector(PROOFSIZE); - for (size_t i = 0; i < PROOFSIZE; i++) { - index_vector[i] = eq.sols[s][i]; - } - std::vector sol_char = GetMinimalFromIndices(index_vector, DIGITBITS); - - if (validBlock(sol_char)) { - // If we find a POW solution, do not try other solutions - // because they become invalid as we created a new block in blockchain. - break; - } - } + check_tromp_solution(eq, validBlock); + } else { try { // If we find a valid block, we rebuild @@ -1803,3 +1811,57 @@ void static BitcoinMiner() } #endif // ENABLE_MINING + +/**** + * This should only be called from a unit test, as the equihash code + * can only be included once (no separation of implementation from declaration). + * This verifies that std::min(MAXSOLS, eq.nsols) prevents a SIGSEGV. + */ +bool test_tromp_equihash() +{ + // get the sols to be less than nsols + + // create a context + CBlock block; + const CChainParams& params = Params(); + + crypto_generichash_blake2b_state state; + EhInitialiseState(params.EquihashN(), params.EquihashK(), state); + // I = the block header minus nonce and solution. + CEquihashInput I{block}; + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << I; + // H(I||... + crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size()); + // H(I||V||... + crypto_generichash_blake2b_state curr_state; + curr_state = state; + crypto_generichash_blake2b_update(&state,block.nNonce.begin(),block.nNonce.size()); + + // Create solver and initialize it. + equi eq(1); + eq.setstate(&curr_state); + + // Initialization done, start algo driver. + eq.digit0(0); + eq.xfull = eq.bfull = eq.hfull = 0; + eq.showbsizes(0); + for (u32 r = 1; r < WK; r++) { + (r&1) ? eq.digitodd(r, 0) : eq.digiteven(r, 0); + eq.xfull = eq.bfull = eq.hfull = 0; + eq.showbsizes(r); + } + eq.digitK(0); + + // force nsols to be more than MAXSOLS (8) + while (eq.nsols <= MAXSOLS * 800) + { + tree t(1); + eq.candidate(t); + } + + auto func = [](std::vector) { return false; }; + + // this used to throw a SIGSEGV + return check_tromp_solution(eq, func); +} From 733e7a57c87f6a9c352b4390ffff84a58499bbf3 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Tue, 16 Aug 2022 23:56:36 +0300 Subject: [PATCH 03/27] Clean up memory on shutdown - https://github.com/KomodoPlatform/komodo/pull/549 --- src/init.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 7cdbeff4..8aac8458 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -272,6 +272,8 @@ void Shutdown() pcoinsdbview = NULL; delete pblocktree; pblocktree = NULL; + delete pnotarisations; + pnotarisations = nullptr; } #ifdef ENABLE_WALLET if (pwalletMain) From b03b48ed1c03d8cd5629477e5d2651834001d47b Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Sat, 20 Aug 2022 20:03:10 +0200 Subject: [PATCH 04/27] Lock cs_main for TestBlockValidity - https://github.com/KomodoPlatform/komodo/pull/486 Also we get rid of LastTip() calls in this PR, changed them to Tip(). --- src/cc/CCutils.cpp | 6 +- src/cc/payments.cpp | 3 +- src/cc/rewards.cpp | 2 +- src/cc/sudoku.cpp | 4 +- src/chain.h | 9 +- src/komodo.cpp | 4 +- src/komodo_bitcoind.cpp | 20 ++-- src/komodo_gateway.cpp | 2 +- src/komodo_jumblr.cpp | 2 +- src/komodo_nSPV_fullnode.h | 12 +-- src/komodo_nSPV_wallet.h | 2 +- src/komodo_pax.cpp | 4 +- src/main.cpp | 91 ++++++++----------- src/metrics.cpp | 2 +- src/miner.cpp | 106 ++++++++++------------ src/rest.cpp | 6 +- src/rpc/blockchain.cpp | 30 +++--- src/rpc/mining.cpp | 25 +++-- src/rpc/misc.cpp | 12 +-- src/rpc/rawtransaction.cpp | 4 +- src/txmempool.cpp | 6 +- src/wallet/asyncrpcoperation_sendmany.cpp | 20 ++-- src/wallet/rpcdump.cpp | 4 +- src/wallet/rpcwallet.cpp | 23 +++-- src/wallet/wallet.cpp | 16 +--- 25 files changed, 187 insertions(+), 228 deletions(-) diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index be3a9617..12755a9e 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -533,7 +533,7 @@ int64_t CCduration(int32_t &numblocks,uint256 txid) LogPrintf("CCduration no txtime %u or txheight.%d %p for txid %s\n",txtime,txheight,pindex,uint256_str(str,txid)); return(0); } - else if ( (pindex= chainActive.LastTip()) == 0 || pindex->nTime < txtime || pindex->nHeight <= txheight ) + else if ( (pindex= chainActive.Tip()) == 0 || pindex->nTime < txtime || pindex->nHeight <= txheight ) { if ( pindex->nTime < txtime ) LogPrintf("CCduration backwards timestamps %u %u for txid %s hts.(%d %d)\n",(uint32_t)pindex->nTime,txtime,uint256_str(str,txid),txheight,(int32_t)pindex->nHeight); @@ -671,7 +671,7 @@ int32_t komodo_get_current_height() { return (NSPV_inforesult.height); } - else return chainActive.LastTip()->nHeight; + else return chainActive.Tip()->nHeight; } bool komodo_txnotarizedconfirmed(uint256 txid) @@ -719,7 +719,7 @@ bool komodo_txnotarizedconfirmed(uint256 txid) LogPrintf("komodo_txnotarizedconfirmed no txheight.%d %p for txid %s\n",txheight,pindex,txid.ToString().c_str()); return(0); } - else if ( (pindex= chainActive.LastTip()) == 0 || pindex->nHeight < txheight ) + else if ( (pindex= chainActive.Tip()) == 0 || pindex->nHeight < txheight ) { LogPrintf("komodo_txnotarizedconfirmed backwards heights for txid %s hts.(%d %d)\n",txid.ToString().c_str(),txheight,(int32_t)pindex->nHeight); return(0); diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 542c4076..8dbc5df8 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -351,7 +351,8 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & txidpk = CCtxidaddr(txidaddr,createtxid); GetCCaddress1of2(cp,txidaddr,Paymentspk,txidpk); //LogPrintf( "lockedblocks.%i minrelease.%i totalallocations.%i txidopret1.%s txidopret2.%s\n",lockedblocks, minrelease, totalallocations, txidoprets[0].ToString().c_str(), txidoprets[1].ToString().c_str() ); - if ( !CheckTxFee(tx, PAYMENTS_TXFEE+1, chainActive.LastTip()->nHeight, chainActive.LastTip()->nTime, actualtxfee) ) + if ( !CheckTxFee(tx, PAYMENTS_TXFEE+1, chainActive.Tip()->nHeight, + chainActive.Tip()->nTime, actualtxfee) ) return eval->Invalid("txfee is too high"); // Check that the change vout is playing the txid address. if ( IsPaymentsvout(cp,tx,0,txidaddr,ccopret) == 0 ) diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index a8a14630..c2e85c7f 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -294,7 +294,7 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t if ( (*cp->ismyvin)(tx.vin[i].scriptSig) == 0 ) return eval->Invalid("unexpected normal vin for unlock"); } - if ( !CheckTxFee(tx, txfee, chainActive.LastTip()->nHeight, chainActive.LastTip()->nTime, dummy) ) + if ( !CheckTxFee(tx, txfee, chainActive.Tip()->nHeight, chainActive.Tip()->nTime, dummy) ) return eval->Invalid("txfee is too high"); amount = vinTx.vout[0].nValue; reward = RewardsCalc((int64_t)amount,tx.vin[0].prevout.hash,(int64_t)APR,(int64_t)minseconds,(int64_t)maxseconds,GetLatestTimestamp(eval->GetCurrentHeight())); diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 7291a3af..42fa422f 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -2537,7 +2537,7 @@ int32_t sudoku_captcha(int32_t dispflag,uint32_t timestamps[81],int32_t height) LogPrintf("list[0] %u vs list[%d-1] %u\n",list[0],n,list[n-1]); retval = -1; } - else if ( list[n-1] > chainActive.LastTip()->nTime+200 ) + else if ( list[n-1] > chainActive.Tip()->nTime+200 ) retval = -2; else if ( solvetime >= 777 ) retval = 0; @@ -2658,7 +2658,7 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params result.push_back(Pair("result","success")); result.push_back(Pair("name","sudoku")); result.push_back(Pair("method","gen")); - hash = chainActive.LastTip()->GetBlockHash(); + hash = chainActive.Tip()->GetBlockHash(); memcpy(&srandi,&hash,sizeof(srandi)); srandi ^= (uint32_t)time(NULL); while ( 1 ) diff --git a/src/chain.h b/src/chain.h index 8e61fe02..46080f0e 100644 --- a/src/chain.h +++ b/src/chain.h @@ -486,16 +486,11 @@ class CChain { return vChain.size() > 0 ? vChain[0] : NULL; } - /** Returns the index entry for the tip of this chain, or NULL if none. */ + /** Returns the index entry for the tip of this chain, or nullptr if none. */ CBlockIndex *Tip() const { - return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL; + return vChain.size() > 0 ? vChain[vChain.size() - 1] : nullptr; } - /** Returns the last tip of the chain, or NULL if none. */ - CBlockIndex *LastTip() const { - return vChain.size() > 0 ? lastTip : NULL; - } - /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */ CBlockIndex *operator[](int nHeight) const { if (nHeight < 0 || nHeight >= (int)vChain.size()) diff --git a/src/komodo.cpp b/src/komodo.cpp index 18b06b31..5886c14e 100644 --- a/src/komodo.cpp +++ b/src/komodo.cpp @@ -646,7 +646,7 @@ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) komodo_stateupdate(pindex->nHeight,0,0,0,zero,0,0,0,0,-pindex->nHeight,pindex->nTime,0,0,0,0,zero,0); } } - komodo_currentheight_set(chainActive.LastTip()->nHeight); + komodo_currentheight_set(chainActive.Tip()->nHeight); int transaction = 0; if ( pindex != 0 ) { @@ -725,7 +725,7 @@ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) if ( len >= sizeof(uint32_t) && len <= sizeof(scriptbuf) ) { memcpy(scriptbuf,(uint8_t *)&block.vtx[i].vout[j].scriptPubKey[0],len); - notaryid = komodo_voutupdate(fJustCheck,&isratification,notaryid,scriptbuf,len,height,txhash,i,j,&voutmask,&specialtx,¬arizedheight,(uint64_t)block.vtx[i].vout[j].nValue,notarized,signedmask,(uint32_t)chainActive.LastTip()->GetBlockTime()); + notaryid = komodo_voutupdate(fJustCheck,&isratification,notaryid,scriptbuf,len,height,txhash,i,j,&voutmask,&specialtx,¬arizedheight,(uint64_t)block.vtx[i].vout[j].nValue,notarized,signedmask,(uint32_t)chainActive.Tip()->GetBlockTime()); if ( fJustCheck && notaryid == -2 ) { // We see a valid notarisation here, save its location. diff --git a/src/komodo_bitcoind.cpp b/src/komodo_bitcoind.cpp index f5604653..03fe945d 100644 --- a/src/komodo_bitcoind.cpp +++ b/src/komodo_bitcoind.cpp @@ -845,20 +845,18 @@ int32_t komodo_blockload(CBlock& block,CBlockIndex *pindex) uint32_t komodo_chainactive_timestamp() { - if ( chainActive.LastTip() != 0 ) - return((uint32_t)chainActive.LastTip()->GetBlockTime()); + if ( chainActive.Tip() != 0 ) + return((uint32_t)chainActive.Tip()->GetBlockTime()); else return(0); } CBlockIndex *komodo_chainactive(int32_t height) { - if ( chainActive.LastTip() != 0 ) + if ( chainActive.Tip() != 0 ) { - if ( height <= chainActive.LastTip()->nHeight ) + if ( height <= chainActive.Tip()->nHeight ) return(chainActive[height]); - // else LogPrintf("komodo_chainactive height %d > active.%d\n",height,chainActive.LastTip()->nHeight); } - //LogPrintf("komodo_chainactive null chainActive.LastTip() height %d\n",height); return(0); } @@ -1057,7 +1055,7 @@ uint32_t komodo_blocktime(uint256 hash) bool komodo_checkpoint(int32_t *notarized_heightp, int32_t nHeight, uint256 hash) { CBlockIndex *pindex; - if ( (pindex= chainActive.LastTip()) == 0 ) + if ( (pindex= chainActive.Tip()) == 0 ) return false; // get the most recent (highest) notarized_checkpointdata @@ -1103,7 +1101,7 @@ uint32_t komodo_interest_args(uint32_t *txheighttimep,int32_t *txheightp,uint32_ *valuep = tx.vout[n].nValue; *txheightp = pindex->nHeight; *txheighttimep = pindex->nTime; - if ( *tiptimep == 0 && (tipindex= chainActive.LastTip()) != 0 ) + if ( *tiptimep == 0 && (tipindex= chainActive.Tip()) != 0 ) *tiptimep = (uint32_t)tipindex->nTime; locktime = tx.nLockTime; //LogPrintf("tx locktime.%u %.8f height.%d | tiptime.%u\n",locktime,(double)*valuep/COIN,*txheightp,*tiptimep); @@ -1133,7 +1131,7 @@ uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 int32_t komodo_nextheight() { CBlockIndex *pindex; int32_t ht; - if ( (pindex= chainActive.LastTip()) != 0 && (ht= pindex->nHeight) > 0 ) + if ( (pindex= chainActive.Tip()) != 0 && (ht= pindex->nHeight) > 0 ) return(ht+1); else return(komodo_longestchain() + 1); } @@ -1144,7 +1142,7 @@ int32_t komodo_isrealtime(int32_t *kmdheightp) if ( (sp= komodo_stateptrget((char *)"KMD")) != 0 ) *kmdheightp = sp->CURRENT_HEIGHT; else *kmdheightp = 0; - if ( (pindex= chainActive.LastTip()) != 0 && pindex->nHeight >= (int32_t)komodo_longestchain() ) + if ( (pindex= chainActive.Tip()) != 0 && pindex->nHeight >= (int32_t)komodo_longestchain() ) return(1); else return(0); } @@ -2177,7 +2175,7 @@ int32_t komodo_acpublic(uint32_t tiptime) { if ( tiptime == 0 ) { - if ( (pindex= chainActive.LastTip()) != 0 ) + if ( (pindex= chainActive.Tip()) != 0 ) tiptime = pindex->nTime; } if ( (ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"ZEX") == 0) && tiptime >= KOMODO_SAPLING_DEADLINE ) diff --git a/src/komodo_gateway.cpp b/src/komodo_gateway.cpp index 89bbb6e3..5f6e6ad1 100644 --- a/src/komodo_gateway.cpp +++ b/src/komodo_gateway.cpp @@ -1559,7 +1559,7 @@ void komodo_passport_iteration() komodo_statefname(fname,baseid<32?base:(char *)"",(char *)"realtime"); if ( (fp= fopen(fname,"wb")) != 0 ) { - buf[0] = (uint32_t)chainActive.LastTip()->nHeight; + buf[0] = (uint32_t)chainActive.Tip()->nHeight; buf[1] = (uint32_t)komodo_longestchain(); if ( buf[0] != 0 && buf[0] == buf[1] ) { diff --git a/src/komodo_jumblr.cpp b/src/komodo_jumblr.cpp index 1f77f7b8..1663edc3 100644 --- a/src/komodo_jumblr.cpp +++ b/src/komodo_jumblr.cpp @@ -619,7 +619,7 @@ void jumblr_iteration() free(retstr), retstr = 0; } } - height = (int32_t)chainActive.LastTip()->nHeight; + height = (int32_t)chainActive.Tip()->nHeight; if ( time(NULL) < lasttime+40 ) return; lasttime = (uint32_t)time(NULL); diff --git a/src/komodo_nSPV_fullnode.h b/src/komodo_nSPV_fullnode.h index 2c6bfd12..e778d31d 100644 --- a/src/komodo_nSPV_fullnode.h +++ b/src/komodo_nSPV_fullnode.h @@ -90,7 +90,7 @@ int32_t NSPV_ntzextract(struct NSPV_ntz *ptr,uint256 ntztxid,int32_t txidht,uint int32_t NSPV_getntzsresp(struct NSPV_ntzsresp *ptr,int32_t origreqheight) { struct NSPV_ntzargs prev,next; int32_t reqheight = origreqheight; - if ( reqheight < chainActive.LastTip()->nHeight ) + if ( reqheight < chainActive.Tip()->nHeight ) reqheight++; if ( NSPV_notarized_bracket(&prev,&next,reqheight) == 0 ) { @@ -132,7 +132,7 @@ int32_t NSPV_setequihdr(struct NSPV_equihdr *hdr,int32_t height) int32_t NSPV_getinfo(struct NSPV_inforesp *ptr,int32_t reqheight) { int32_t prevMoMheight,len = 0; CBlockIndex *pindex, *pindex2; struct NSPV_ntzsresp pair; - if ( (pindex= chainActive.LastTip()) != 0 ) + if ( (pindex= chainActive.Tip()) != 0 ) { ptr->height = pindex->nHeight; ptr->blockhash = pindex->GetBlockHash(); @@ -167,7 +167,7 @@ int32_t NSPV_getaddressutxos(struct NSPV_utxosresp *ptr,char *coinaddr,bool isCC skipcount = 0; if ( (ptr->numutxos= (int32_t)unspentOutputs.size()) >= 0 && ptr->numutxos < maxlen ) { - tipheight = chainActive.LastTip()->nHeight; + tipheight = chainActive.Tip()->nHeight; ptr->nodeheight = tipheight; if ( skipcount >= ptr->numutxos ) skipcount = ptr->numutxos-1; @@ -333,7 +333,7 @@ int32_t NSPV_getccmoduleutxos(struct NSPV_utxosresp *ptr, char *coinaddr, int64_ ptr->numutxos = 0; strncpy(ptr->coinaddr, coinaddr, sizeof(ptr->coinaddr) - 1); ptr->CCflag = 1; - tipheight = chainActive.LastTip()->nHeight; + tipheight = chainActive.Tip()->nHeight; ptr->nodeheight = tipheight; // will be checked in libnspv //} @@ -441,7 +441,7 @@ int32_t NSPV_getaddresstxids(struct NSPV_txidsresp *ptr,char *coinaddr,bool isCC int32_t maxlen,txheight,ind=0,n = 0,len = 0; CTransaction tx; uint256 hashBlock; std::vector > txids; SetCCtxids(txids,coinaddr,isCC); - ptr->nodeheight = chainActive.LastTip()->nHeight; + ptr->nodeheight = chainActive.Tip()->nHeight; maxlen = MAX_BLOCK_SIZE(ptr->nodeheight) - 512; maxlen /= sizeof(*ptr->txids); strncpy(ptr->coinaddr,coinaddr,sizeof(ptr->coinaddr)-1); @@ -622,7 +622,7 @@ int32_t NSPV_mempoolfuncs(bits256 *satoshisp,int32_t *vindexp,std::vector txids; bits256 satoshis; uint256 tmp,tmpdest; int32_t i,len = 0; - ptr->nodeheight = chainActive.LastTip()->nHeight; + ptr->nodeheight = chainActive.Tip()->nHeight; strncpy(ptr->coinaddr,coinaddr,sizeof(ptr->coinaddr)-1); ptr->CCflag = isCC; ptr->txid = txid; diff --git a/src/komodo_nSPV_wallet.h b/src/komodo_nSPV_wallet.h index c91963e6..f38903bc 100644 --- a/src/komodo_nSPV_wallet.h +++ b/src/komodo_nSPV_wallet.h @@ -389,7 +389,7 @@ UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis) // what its a mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID; mtx.nVersion = SAPLING_TX_VERSION; if ( ASSETCHAINS_SYMBOL[0] == 0 ) { - if ( !komodo_hardfork_active((uint32_t)chainActive.LastTip()->nTime) ) + if ( !komodo_hardfork_active((uint32_t)chainActive.Tip()->nTime) ) mtx.nLockTime = (uint32_t)time(NULL) - 777; else mtx.nLockTime = (uint32_t)chainActive.Tip()->GetMedianTimePast(); diff --git a/src/komodo_pax.cpp b/src/komodo_pax.cpp index e4ff2088..b19a4691 100644 --- a/src/komodo_pax.cpp +++ b/src/komodo_pax.cpp @@ -603,13 +603,13 @@ uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume) { int32_t i,nonz=0; int64_t diff; uint64_t price,seed,sum = 0; - if ( ASSETCHAINS_SYMBOL[0] == 0 && chainActive.LastTip() != 0 && height > chainActive.LastTip()->nHeight ) + if ( ASSETCHAINS_SYMBOL[0] == 0 && chainActive.Tip() != 0 && height > chainActive.Tip()->nHeight ) { if ( height < 100000000 ) { static uint32_t counter; if ( counter++ < 3 ) - LogPrintf("komodo_paxprice height.%d vs tip.%d\n",height,chainActive.LastTip()->nHeight); + LogPrintf("komodo_paxprice height.%d vs tip.%d\n",height,chainActive.Tip()->nHeight); } return(0); } diff --git a/src/main.cpp b/src/main.cpp index 57401513..c5eeadee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -341,10 +341,9 @@ namespace { int GetHeight() { CBlockIndex *pindex; - if ( (pindex= chainActive.LastTip()) != 0 ) + if ( (pindex= chainActive.Tip()) != 0 ) return pindex->nHeight; - else return(0); - /*return chainActive.Height();*/ + return 0; } void UpdatePreferredDownload(CNode* node, CNodeState* state) @@ -1254,7 +1253,6 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde // Rules that apply before Sapling: if (!saplingActive) { // Size limits - //BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE(chainActive.LastTip()->nHeight+1) > MAX_TX_SIZE_BEFORE_SAPLING); // sanity if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_BEFORE_SAPLING) return state.DoS(100, error("ContextualCheckTransaction(): size limits failed"), REJECT_INVALID, "bad-txns-oversize"); @@ -1492,7 +1490,6 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio REJECT_INVALID, "bad-txns-vout-empty"); // Size limits - //BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE(chainActive.LastTip()->nHeight+1) >= MAX_TX_SIZE_AFTER_SAPLING); // sanity BOOST_STATIC_ASSERT(MAX_TX_SIZE_AFTER_SAPLING > MAX_TX_SIZE_BEFORE_SAPLING); // sanity if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_AFTER_SAPLING) return state.DoS(100, error("CheckTransaction(): size limits failed"), @@ -1786,9 +1783,9 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa uint32_t tiptime; int flag=0,nextBlockHeight = chainActive.Height() + 1; auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus()); - if ( nextBlockHeight <= 1 || chainActive.LastTip() == 0 ) + if ( nextBlockHeight <= 1 || chainActive.Tip() == 0 ) tiptime = (uint32_t)time(NULL); - else tiptime = (uint32_t)chainActive.LastTip()->nTime; + else tiptime = (uint32_t)chainActive.Tip()->nTime; //LogPrintf("addmempool 0\n"); // Node operator can choose to reject tx by number of transparent inputs static_assert(std::numeric_limits::max() >= std::numeric_limits::max(), "size_t too small"); @@ -1805,7 +1802,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } //LogPrintf("addmempool 1\n"); auto verifier = libzcash::ProofVerifier::Strict(); - if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,chainActive.LastTip()->nHeight+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 ) + if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,chainActive.Tip()->nHeight+1, + chainActive.Tip()->GetMedianTimePast() + 777,0) < 0 ) { return error("%s: komodo_validate_interest failed txid.%s", __func__, tx.GetHash().ToString()); } @@ -1941,9 +1939,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Bring the best block into scope view.GetBestBlock(); - nValueIn = view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime); - if ( 0 && interest != 0 ) - LogPrintf("add interest %.8f\n",(double)interest/COIN); + nValueIn = view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx,chainActive.Tip()->nTime); // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool view.SetBackend(dummy); } @@ -2067,10 +2063,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // invalid blocks, however allowing such transactions into the mempool // can be exploited as a DoS attack. // XXX: is this neccesary for CryptoConditions? - if ( KOMODO_CONNECTING <= 0 && chainActive.LastTip() != 0 ) + if ( KOMODO_CONNECTING <= 0 && chainActive.Tip() != 0 ) { flag = 1; - KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.LastTip()->nHeight + 1; + KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.Tip()->nHeight + 1; } //LogPrintf("addmempool 7\n"); @@ -2586,7 +2582,8 @@ void CheckForkWarningConditions() if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 288) pindexBestForkTip = NULL; - if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > (chainActive.LastTip()->nChainWork + (GetBlockProof(*chainActive.LastTip()) * 6)))) + if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork + > (chainActive.Tip()->nChainWork + (GetBlockProof(*chainActive.Tip()) * 6)))) { if (!fLargeWorkForkFound && pindexBestForkBase) { @@ -2621,7 +2618,7 @@ void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip) AssertLockHeld(cs_main); // If we are on a fork that is sufficiently large, set a warning flag CBlockIndex* pfork = pindexNewForkTip; - CBlockIndex* plonger = chainActive.LastTip(); + CBlockIndex* plonger = chainActive.Tip(); while (pfork && pfork != plonger) { while (plonger && plonger->nHeight > pfork->nHeight) @@ -2678,7 +2675,7 @@ void static InvalidChainFound(CBlockIndex* pindexNew) pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime())); - CBlockIndex *tip = chainActive.LastTip(); + CBlockIndex *tip = chainActive.Tip(); assert (tip); LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__, tip->GetBlockHash().ToString(), chainActive.Height(), @@ -2822,14 +2819,13 @@ namespace Consensus { // Check for negative or overflow input values nValueIn += coins->vout[prevout.n].nValue; #ifdef KOMODO_ENABLE_INTEREST - if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 )//chainActive.LastTip() != 0 && chainActive.LastTip()->nHeight >= 60000 ) + if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 ) { if ( coins->vout[prevout.n].nValue >= 10*COIN ) { int64_t interest; int32_t txheight; uint32_t locktime; if ( (interest= komodo_accrued_interest(&txheight,&locktime,prevout.hash,prevout.n,0,coins->vout[prevout.n].nValue,(int32_t)nSpendHeight-1)) != 0 ) { - //LogPrintf("checkResult %.8f += val %.8f interest %.8f ht.%d lock.%u tip.%u\n",(double)nValueIn/COIN,(double)coins->vout[prevout.n].nValue/COIN,(double)interest/COIN,txheight,locktime,chainActive.LastTip()->nTime); nValueIn += interest; } } @@ -3658,21 +3654,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin LogPrintf("valueout %.8f too big\n",(double)valueout/COIN); return state.DoS(100, error("ConnectBlock(): GetValueOut too big"),REJECT_INVALID,"tx valueout is too big"); } - //prevsum = voutsum; - //voutsum += valueout; - /*if ( KOMODO_VALUETOOBIG(voutsum) != 0 ) - { - LogPrintf("voutsum %.8f too big\n",(double)voutsum/COIN); - return state.DoS(100, error("ConnectBlock(): voutsum too big"),REJECT_INVALID,"tx valueout is too big"); - } - else - if ( voutsum < prevsum ) // PRLPAY overflows this and it isnt a conclusive test anyway - return state.DoS(100, error("ConnectBlock(): voutsum less after adding valueout"),REJECT_INVALID,"tx valueout is too big");*/ if (!tx.IsCoinBase()) { - nFees += (stakeTxValue= view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime) - valueout); + nFees += (stakeTxValue= view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx, + chainActive.Tip()->nTime) - valueout); sum += interest; - //LogPrintf( "tx.%s nFees.%li interest.%li\n", tx.GetHash().ToString().c_str(), stakeTxValue, interest); std::vector vChecks; if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, false, txdata[i], chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL)) @@ -4027,17 +4013,17 @@ void static UpdateTip(CBlockIndex *pindexNew) { KOMODO_NEWBLOCKS++; double progress; if ( ASSETCHAINS_SYMBOL[0] == 0 ) { - progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip()); + progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()); } else { int32_t longestchain = komodo_longestchain(); progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0; } LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__, - chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(), + chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), - (unsigned long)chainActive.LastTip()->nChainTx, - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()), progress, + (unsigned long)chainActive.Tip()->nChainTx, + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), progress, pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize()); cvBlockChange.notify_all(); @@ -4424,7 +4410,7 @@ static void PruneBlockIndexCandidates() { // Note that we can't delete the current block itself, as we may need to return to it later in case a // reorganization to a better block fails. std::set::iterator it = setBlockIndexCandidates.begin(); - while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.LastTip())) { + while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) { setBlockIndexCandidates.erase(it++); } // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates. @@ -4516,8 +4502,9 @@ static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBloc if ( KOMODO_REWIND != 0 ) { CBlockIndex *tipindex; - LogPrintf(">>>>>>>>>>> rewind start ht.%d -> KOMODO_REWIND.%d\n",chainActive.LastTip()->nHeight,KOMODO_REWIND); - while ( KOMODO_REWIND > 0 && (tipindex= chainActive.LastTip()) != 0 && tipindex->nHeight > KOMODO_REWIND ) + LogPrintf(">>>>>>>>>>> rewind start ht.%d -> KOMODO_REWIND.%d\n", + chainActive.Tip()->nHeight,KOMODO_REWIND); + while ( KOMODO_REWIND > 0 && (tipindex= chainActive.Tip()) != 0 && tipindex->nHeight > KOMODO_REWIND ) { fBlocksDisconnected = true; LogPrintf("%d ",(int32_t)tipindex->nHeight); @@ -5092,9 +5079,9 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, for (i=31; i>=0; i--) LogPrintf("%02x",((uint8_t *)&hash)[i]); LogPrintf(" <- CheckBlockHeader\n"); - if ( chainActive.LastTip() != 0 ) + if ( chainActive.Tip() != 0 ) { - hash = chainActive.LastTip()->GetBlockHash(); + hash = chainActive.Tip()->GetBlockHash(); for (i=31; i>=0; i--) LogPrintf("%02x",((uint8_t *)&hash)[i]); LogPrintf(" <- chainTip\n"); @@ -5405,7 +5392,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta // Don't accept any forks from the main chain prior to last checkpoint CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints()); int32_t notarized_height; - if ( nHeight == 1 && chainActive.LastTip() != 0 && chainActive.LastTip()->nHeight > 1 ) + if ( nHeight == 1 && chainActive.Tip() != 0 && chainActive.Tip()->nHeight > 1 ) { CBlockIndex *heightblock = chainActive[nHeight]; if ( heightblock != 0 && heightblock->GetBlockHash() == hash ) @@ -5648,7 +5635,7 @@ bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, C if ( saplinght < 0 ) *futureblockp = 1; // the problem is when a future sapling block comes in before we detected saplinght - if ( saplinght > 0 && (tmpptr= chainActive.LastTip()) != 0 ) + if ( saplinght > 0 && (tmpptr= chainActive.Tip()) != 0 ) { LogPrintf("saplinght.%d tipht.%d blockht.%d cmp.%d\n",saplinght,(int32_t)tmpptr->nHeight,pindex->nHeight,pindex->nHeight < 0 || (pindex->nHeight >= saplinght && pindex->nHeight < saplinght+50000) || (tmpptr->nHeight > saplinght-720 && tmpptr->nHeight < saplinght+720)); if ( pindex->nHeight < 0 || (pindex->nHeight >= saplinght && pindex->nHeight < saplinght+50000) || (tmpptr->nHeight > saplinght-720 && tmpptr->nHeight < saplinght+720) ) @@ -5813,11 +5800,10 @@ bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNo bool checked; uint256 hash; int32_t futureblock=0; auto verifier = libzcash::ProofVerifier::Disabled(); hash = pblock->GetHash(); - //LogPrintf("ProcessBlock %d\n",(int32_t)chainActive.LastTip()->nHeight); { LOCK(cs_main); - if ( chainActive.LastTip() != 0 ) - komodo_currentheight_set(chainActive.LastTip()->nHeight); + if ( chainActive.Tip() != 0 ) + komodo_currentheight_set(chainActive.Tip()->nHeight); checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0); bool fRequested = MarkBlockAsReceived(hash); fRequested |= fForceProcessing; @@ -5847,7 +5833,7 @@ bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNo /*if ( ASSETCHAINS_SYMBOL[0] == 0 ) { //LogPrintf("request headers from failed process block peer\n"); - pfrom->PushMessage("getheaders", chainActive.GetLocator(chainActive.LastTip()), uint256()); + pfrom->PushMessage("getheaders", chainActive.GetLocator(chainActive.Tip()), uint256()); }*/ komodo_longestchain(); return error("%s: AcceptBlock FAILED", __func__); @@ -5859,7 +5845,6 @@ bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNo if (futureblock == 0 && !ActivateBestChain(false, state, pblock)) return error("%s: ActivateBestChain failed", __func__); - //LogPrintf("finished ProcessBlock %d\n",(int32_t)chainActive.LastTip()->nHeight); return true; } @@ -5878,23 +5863,19 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex // NOTE: CheckBlockHeader is called by CheckBlock if (!ContextualCheckBlockHeader(block, state, pindexPrev)) { - //LogPrintf("TestBlockValidity failure A checkPOW.%d\n",fCheckPOW); return false; } int32_t futureblock; if (!CheckBlock(&futureblock,indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot)) { - //LogPrintf("TestBlockValidity failure B checkPOW.%d\n",fCheckPOW); return false; } if (!ContextualCheckBlock(0,block, state, pindexPrev)) { - //LogPrintf("TestBlockValidity failure C checkPOW.%d\n",fCheckPOW); return false; } if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW)) { - //LogPrintf("TestBlockValidity failure D checkPOW.%d\n",fCheckPOW); return false; } assert(state.IsValid()); @@ -6336,7 +6317,7 @@ bool static LoadBlockIndexDB() double progress; if ( ASSETCHAINS_SYMBOL[0] == 0 ) { - progress = Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.LastTip()); + progress = Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip()); } else { int32_t longestchain = komodo_longestchain(); // TODO: komodo_longestchain does not have the data it needs at the time LoadBlockIndexDB @@ -6344,13 +6325,13 @@ bool static LoadBlockIndexDB() progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 0.5; } LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__, - chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(), - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()), + chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), progress); EnforceNodeDeprecation(chainActive.Height(), true); CBlockIndex *pindex; - if ( (pindex= chainActive.LastTip()) != 0 ) + if ( (pindex= chainActive.Tip()) != 0 ) { if ( ASSETCHAINS_SAPLING <= 0 ) { @@ -7806,7 +7787,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_main); - if (chainActive.LastTip() != 0 && chainActive.LastTip()->nHeight > 100000 && IsInitialBlockDownload()) + if (chainActive.Tip() != 0 && chainActive.Tip()->nHeight > 100000 && IsInitialBlockDownload()) { //LogPrintf("dont process getheaders during initial download\n"); return true; diff --git a/src/metrics.cpp b/src/metrics.cpp index 7ec6298b..1901e7a2 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -240,7 +240,7 @@ int printStats(bool mining) { LOCK2(cs_main, cs_vNodes); height = chainActive.Height(); - tipmediantime = chainActive.LastTip()->GetMedianTimePast(); + tipmediantime = chainActive.Tip()->GetMedianTimePast(); connections = vNodes.size(); netsolps = GetNetworkHashPS(120, -1); } diff --git a/src/miner.cpp b/src/miner.cpp index 0a8e7ced..f4a1a726 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -174,7 +174,7 @@ int32_t komodo_waituntilelegible(uint32_t blocktime, int32_t stakeHeight, uint32 break; if ( (rand() % 100) < 2-(secToElegible>ASSETCHAINS_STAKED_BLOCK_FUTURE_MAX) ) LogPrintf( "[%s:%i] %llds until elegible...\n", ASSETCHAINS_SYMBOL, stakeHeight, (long long)secToElegible); - if ( chainActive.LastTip()->nHeight >= stakeHeight ) + if ( chainActive.Tip()->nHeight >= stakeHeight ) { LogPrintf( "[%s:%i] Chain advanced, reset staking loop.\n", ASSETCHAINS_SYMBOL, stakeHeight); return(0); @@ -229,9 +229,9 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 pblocktemplate->vTxSigOps.push_back(-1); // updated at end // Largest block you're willing to create: - unsigned int nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE(chainActive.LastTip()->nHeight+1)); + unsigned int nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE(chainActive.Tip()->nHeight+1)); // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: - nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE(chainActive.LastTip()->nHeight+1)-1000), nBlockMaxSize)); + nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE(chainActive.Tip()->nHeight+1)-1000), nBlockMaxSize)); // How much of the block should be dedicated to high-priority transactions, // included regardless of the fees they pay @@ -254,7 +254,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 boost::this_thread::disable_interruption(); ENTER_CRITICAL_SECTION(cs_main); ENTER_CRITICAL_SECTION(mempool.cs); - pindexPrev = chainActive.LastTip(); + pindexPrev = chainActive.Tip(); const int nHeight = pindexPrev->nHeight + 1; const Consensus::Params &consensusParams = chainparams.GetConsensus(); uint32_t consensusBranchId = CurrentEpochBranchId(nHeight, consensusParams); @@ -576,7 +576,8 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 //LogPrintf("dont have inputs\n"); continue; } - CAmount nTxFees = view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime)-tx.GetValueOut(); + CAmount nTxFees = view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx, + chainActive.Tip()->nTime)-tx.GetValueOut(); nTxSigOps += GetP2SHSigOpCount(tx, view); if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1) @@ -690,8 +691,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 pblocktemplate->vTxSigOps.push_back(GetLegacySigOpCount(txStaked)); nFees += txfees; pblock->nTime = blocktime; - //LogPrintf("staking PoS ht.%d t%u lag.%u\n",(int32_t)chainActive.LastTip()->nHeight+1,blocktime,(uint32_t)(GetTime() - (blocktime-13))); - } else return(0); //LogPrintf("no utxos eligible for staking\n"); + } else return(0); } // Create coinbase tx @@ -707,7 +707,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 //LogPrintf( "MINER: coinbasetx.%s\n", EncodeHexTx(txNew).c_str()); //LogPrintf("mine ht.%d with %.8f\n",nHeight,(double)txNew.vout[0].nValue/COIN); - //if ((uint32_t)chainActive.LastTip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) { + //if ((uint32_t)chainActive.Tip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) { if ( ASSETCHAINS_ADAPTIVEPOW <= 0 ) txNew.nLockTime = std::max(pindexPrev->GetMedianTimePast()+1, GetTime()); else txNew.nLockTime = std::max((int64_t)(pindexPrev->nTime+1), GetTime()); @@ -1075,18 +1075,18 @@ static bool ProcessBlockFound(CBlock* pblock) #endif // ENABLE_WALLET { LogPrintf("%s\n", pblock->ToString()); - LogPrintf("generated %s height.%d\n", FormatMoney(pblock->vtx[0].vout[0].nValue),chainActive.LastTip()->nHeight+1); + LogPrintf("generated %s height.%d\n", FormatMoney(pblock->vtx[0].vout[0].nValue),chainActive.Tip()->nHeight+1); // Found a solution { - if (pblock->hashPrevBlock != chainActive.LastTip()->GetBlockHash()) + if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash()) { uint256 hash; int32_t i; hash = pblock->hashPrevBlock; for (i=31; i>=0; i--) LogPrintf("%02x",((uint8_t *)&hash)[i]); LogPrintf(" <- prev (stale)\n"); - hash = chainActive.LastTip()->GetBlockHash(); + hash = chainActive.Tip()->GetBlockHash(); for (i=31; i>=0; i--) LogPrintf("%02x",((uint8_t *)&hash)[i]); LogPrintf(" <- chainTip (stale)\n"); @@ -1116,7 +1116,7 @@ static bool ProcessBlockFound(CBlock* pblock) // Process this block the same as if we had received it from another node CValidationState state; - if (!ProcessNewBlock(1,chainActive.LastTip()->nHeight+1,state, NULL, pblock, true, NULL)) + if (!ProcessNewBlock(1,chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL)) return error("KomodoMiner: ProcessNewBlock, block not accepted"); TrackMinedBlock(pblock->GetHash()); @@ -1180,9 +1180,9 @@ void waitForPeers(const CChainParams &chainparams) #ifdef ENABLE_WALLET CBlockIndex *get_chainactive(int32_t height) { - if ( chainActive.LastTip() != 0 ) + if ( chainActive.Tip() != 0 ) { - if ( height <= chainActive.LastTip()->nHeight ) + if ( height <= chainActive.Tip()->nHeight ) { LOCK(cs_main); return(chainActive[height]); @@ -1252,7 +1252,16 @@ void static BitcoinMiner() break; } if ( ASSETCHAINS_SYMBOL[0] == 0 ) - komodo_chosennotary(¬aryid,chainActive.Height()+1,NOTARY_PUBKEY33,(uint32_t)chainActive.Tip()->GetMedianTimePast()); + { + int newHeight; + uint32_t timePast; + { + LOCK(cs_main); + newHeight = chainActive.Height() + 1; + timePast = (uint32_t)chainActive.Tip()->GetMedianTimePast(); + } + komodo_chosennotary(¬aryid,newHeight,NOTARY_PUBKEY33,timePast); + } if ( notaryid != My_notaryid ) My_notaryid = notaryid; std::string solver; @@ -1280,10 +1289,8 @@ void static BitcoinMiner() LogPrintf("try %s Mining with %s\n",ASSETCHAINS_SYMBOL,solver.c_str()); while (true) { - if (chainparams.MiningRequiresPeers()) //chainActive.LastTip()->nHeight != 235300 && + if (chainparams.MiningRequiresPeers()) { - //if ( ASSETCHAINS_SEED != 0 && chainActive.LastTip()->nHeight < 100 ) - // break; // Busy-wait for the network to come online so we don't waste time mining // on an obsolete chain. In regtest mode we expect to fly solo. miningTimer.stop(); @@ -1306,17 +1313,16 @@ void static BitcoinMiner() // Create new block // unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrev = chainActive.LastTip(); + CBlockIndex* pindexPrev = nullptr; + { + LOCK(cs_main); + pindexPrev = chainActive.Tip(); + } if ( Mining_height != pindexPrev->nHeight+1 ) { Mining_height = pindexPrev->nHeight+1; Mining_start = (uint32_t)time(NULL); } - if ( ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_STAKED == 0 ) - { - //LogPrintf("%s create new block ht.%d\n",ASSETCHAINS_SYMBOL,Mining_height); - //sleep(3); - } #ifdef ENABLE_WALLET // notaries always default to staking @@ -1548,24 +1554,12 @@ void static BitcoinMiner() solutionTargetChecks.increment(); B = *pblock; h = UintToArith256(B.GetHash()); - /*for (z=31; z>=16; z--) - LogPrintf("%02x",((uint8_t *)&h)[z]); - LogPrintf(" mined "); - for (z=31; z>=16; z--) - LogPrintf("%02x",((uint8_t *)&HASHTarget)[z]); - LogPrintf(" hashTarget "); - for (z=31; z>=16; z--) - LogPrintf("%02x",((uint8_t *)&HASHTarget_POW)[z]); - LogPrintf(" POW\n");*/ if ( h > hashTarget ) { - //if ( ASSETCHAINS_STAKED != 0 && KOMODO_MININGTHREADS == 0 ) - // MilliSleep(30); return false; } if ( IS_KOMODO_NOTARY && B.nTime > GetTime() ) { - //LogPrintf("need to wait %d seconds to submit block\n",(int32_t)(B.nTime - GetTime())); while ( GetTime() < B.nTime-2 ) { #ifdef WIN32 @@ -1573,8 +1567,13 @@ void static BitcoinMiner() #else sleep(1); #endif + CBlockIndex *tip = nullptr; - if ( chainActive.LastTip()->nHeight >= Mining_height ) + { + LOCK(cs_main); + tip = chainActive.Tip(); + } + if ( tip->nHeight >= Mining_height ) { LogPrintf("new block arrived\n"); return(false); @@ -1609,13 +1608,15 @@ void static BitcoinMiner() LogPrintf("%02x",((uint8_t *)&tmp)[z]); LogPrintf( "\n"); } - CValidationState state; - if ( !TestBlockValidity(state,B, chainActive.LastTip(), true, false)) + bool blockValid; + { + LOCK(cs_main); + CValidationState state; + blockValid = TestBlockValidity(state, B, chainActive.Tip(), true, false); + } + if ( !blockValid ) { h = UintToArith256(B.GetHash()); - for (z=31; z>=0; z--) - LogPrintf("%02x",((uint8_t *)&h)[z]); - LogPrintf(" Invalid block mined, try again\n"); gotinvalid = 1; return(false); } @@ -1717,10 +1718,13 @@ void static BitcoinMiner() LogPrintf("timeout, break\n"); break; } - if ( pindexPrev != chainActive.LastTip() ) + CBlockIndex *tip = nullptr; + { + LOCK(cs_main); + tip = chainActive.Tip(); + } + if ( pindexPrev != tip ) { - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) - LogPrintf("Tip advanced, break\n"); break; } // Update nNonce and nTime @@ -1732,19 +1736,7 @@ void static BitcoinMiner() HASHTarget.SetCompact(pblock->nBits); hashTarget = HASHTarget; savebits = pblock->nBits; - //hashTarget = HASHTarget_POW = komodo_adaptivepow_target(Mining_height,HASHTarget,pblock->nTime); } - /*if ( NOTARY_PUBKEY33[0] == 0 ) - { - int32_t percPoS; - UpdateTime(pblock, consensusParams, pindexPrev); - if (consensusParams.fPowAllowMinDifficultyBlocks) - { - // Changing pblock->nTime can change work required on testnet: - HASHTarget.SetCompact(pblock->nBits); - HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED); - } - }*/ } } } diff --git a/src/rest.cpp b/src/rest.cpp index 3fb87f8f..10fa6507 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -548,7 +548,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) // serialize data // use exact same output as mentioned in Bip64 CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); - ssGetUTXOResponse << chainActive.Height() << chainActive.LastTip()->GetBlockHash() << bitmap << outs; + ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; string ssGetUTXOResponseString = ssGetUTXOResponse.str(); req->WriteHeader("Content-Type", "application/octet-stream"); @@ -558,7 +558,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) case RF_HEX: { CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); - ssGetUTXOResponse << chainActive.Height() << chainActive.LastTip()->GetBlockHash() << bitmap << outs; + ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); @@ -572,7 +572,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) // pack in some essentials // use more or less the same output as mentioned in Bip64 objGetUTXOResponse.push_back(Pair("chainHeight", chainActive.Height())); - objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.LastTip()->GetBlockHash().GetHex())); + objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex())); objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation)); UniValue utxos(UniValue::VARR); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 57dc2b9f..f75a283c 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -61,10 +61,10 @@ double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficul // minimum difficulty = 1.0. if (blockindex == NULL) { - if (chainActive.LastTip() == NULL) + if (chainActive.Tip() == NULL) return 1.0; else - blockindex = chainActive.LastTip(); + blockindex = chainActive.Tip(); } uint32_t bits; @@ -375,7 +375,7 @@ UniValue getbestblockhash(const UniValue& params, bool fHelp, const CPubKey& myp ); LOCK(cs_main); - return chainActive.LastTip()->GetBlockHash().GetHex(); + return chainActive.Tip()->GetBlockHash().GetHex(); } UniValue getdifficulty(const UniValue& params, bool fHelp, const CPubKey& mypk) @@ -965,13 +965,13 @@ UniValue kvsearch(const UniValue& params, bool fHelp, const CPubKey& mypk) if ( (keylen= (int32_t)strlen(params[0].get_str().c_str())) > 0 ) { ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL))); - ret.push_back(Pair("currentheight", (int64_t)chainActive.LastTip()->nHeight)); + ret.push_back(Pair("currentheight", (int64_t)chainActive.Tip()->nHeight)); ret.push_back(Pair("key",params[0].get_str())); ret.push_back(Pair("keylen",keylen)); if ( keylen < sizeof(key) ) { memcpy(key,params[0].get_str().c_str(),keylen); - if ( (valuesize= komodo_kvsearch(&refpubkey,chainActive.LastTip()->nHeight,&flags,&height,value,key,keylen)) >= 0 ) + if ( (valuesize= komodo_kvsearch(&refpubkey,chainActive.Tip()->nHeight,&flags,&height,value,key,keylen)) >= 0 ) { std::string val; char *valuestr; val.resize(valuesize); @@ -999,7 +999,7 @@ UniValue minerids(const UniValue& params, bool fHelp, const CPubKey& mypk) LOCK(cs_main); int32_t height = atoi(params[0].get_str().c_str()); if ( height <= 0 ) - height = chainActive.LastTip()->nHeight; + height = chainActive.Tip()->nHeight; else { CBlockIndex *pblockindex = chainActive[height]; @@ -1061,8 +1061,8 @@ UniValue notaries(const UniValue& params, bool fHelp, const CPubKey& mypk) else timestamp = (uint32_t)time(NULL); if ( height < 0 ) { - height = chainActive.LastTip()->nHeight; - timestamp = chainActive.LastTip()->GetBlockTime(); + height = chainActive.Tip()->nHeight; + timestamp = chainActive.Tip()->GetBlockTime(); } else if ( params.size() < 2 ) { @@ -1150,7 +1150,7 @@ UniValue paxprice(const UniValue& params, bool fHelp, const CPubKey& mypk) std::string rel = params[1].get_str(); int32_t height; if ( params.size() == 2 ) - height = chainActive.LastTip()->nHeight; + height = chainActive.Tip()->nHeight; else height = atoi(params[2].get_str().c_str()); //if ( params.size() == 3 || (basevolume= COIN * atof(params[3].get_str().c_str())) == 0 ) basevolume = 100000; @@ -1719,7 +1719,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp, const CPubKey& my LOCK(cs_main); double progress; if ( ASSETCHAINS_SYMBOL[0] == 0 ) { - progress = Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.LastTip()); + progress = Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()); } else { int32_t longestchain = KOMODO_LONGESTCHAIN;//komodo_longestchain(); progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0; @@ -1729,10 +1729,10 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp, const CPubKey& my obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("synced", KOMODO_INSYNC!=0)); obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); - obj.push_back(Pair("bestblockhash", chainActive.LastTip()->GetBlockHash().GetHex())); + obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty())); obj.push_back(Pair("verificationprogress", progress)); - obj.push_back(Pair("chainwork", chainActive.LastTip()->nChainWork.GetHex())); + obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); obj.push_back(Pair("size_on_disk", CalculateCurrentUsage())); obj.push_back(Pair("pruned", fPruneMode)); @@ -1740,7 +1740,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp, const CPubKey& my pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), tree); obj.push_back(Pair("commitments", static_cast(tree.size()))); - CBlockIndex* tip = chainActive.LastTip(); + CBlockIndex* tip = chainActive.Tip(); UniValue valuePools(UniValue::VARR); valuePools.push_back(ValuePoolDesc("sprout", tip->nChainSproutValue, boost::none)); valuePools.push_back(ValuePoolDesc("sapling", tip->nChainSaplingValue, boost::none)); @@ -1766,7 +1766,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp, const CPubKey& my if (fPruneMode) { - CBlockIndex *block = chainActive.LastTip(); + CBlockIndex *block = chainActive.Tip(); while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) block = block->pprev; @@ -1859,7 +1859,7 @@ UniValue getchaintips(const UniValue& params, bool fHelp, const CPubKey& mypk) //pthread_mutex_unlock(&mutex); // Always report the currently active tip. - setTips.insert(chainActive.LastTip()); + setTips.insert(chainActive.Tip()); /* Construct the output array. */ UniValue res(UniValue::VARR); const CBlockIndex *forked; diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 53a62731..0c4f7708 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -63,7 +63,7 @@ int32_t komodo_newStakerActive(int32_t height, uint32_t timestamp); */ int64_t GetNetworkHashPS(int lookup, int height) { - CBlockIndex *pb = chainActive.LastTip(); + CBlockIndex *pb = chainActive.Tip(); if (height >= 0 && height < chainActive.Height()) pb = chainActive[height]; @@ -270,7 +270,7 @@ UniValue generate(const UniValue& params, bool fHelp, const CPubKey& mypk) CBlock *pblock = &pblocktemplate->block; { LOCK(cs_main); - IncrementExtraNonce(pblock, chainActive.LastTip(), nExtraNonce); + IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); } // Hash state @@ -314,7 +314,7 @@ UniValue generate(const UniValue& params, bool fHelp, const CPubKey& mypk) } endloop: CValidationState state; - if (!ProcessNewBlock(1,chainActive.LastTip()->nHeight+1,state, NULL, pblock, true, NULL)) + if (!ProcessNewBlock(1,chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL)) throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); @@ -668,7 +668,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp return "duplicate-inconclusive"; } - CBlockIndex* const pindexPrev = chainActive.LastTip(); + CBlockIndex* const pindexPrev = chainActive.Tip(); // TestBlockValidity only supports blocks built on the current Tip if (block.hashPrevBlock != pindexPrev->GetBlockHash()) return "inconclusive-not-best-prevblk"; @@ -718,7 +718,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp else { // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier - hashWatchedChain = chainActive.LastTip()->GetBlockHash(); + hashWatchedChain = chainActive.Tip()->GetBlockHash(); nTransactionsUpdatedLastLP = nTransactionsUpdatedLast; } @@ -728,7 +728,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp checktxtime = boost::get_system_time() + boost::posix_time::minutes(1); boost::unique_lock lock(csBestBlock); - while (chainActive.LastTip()->GetBlockHash() == hashWatchedChain && IsRPCRunning()) + while (chainActive.Tip()->GetBlockHash() == hashWatchedChain && IsRPCRunning()) { if (!cvBlockChange.timed_wait(lock, checktxtime)) { @@ -750,7 +750,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp static CBlockIndex* pindexPrev; static int64_t nStart; static CBlockTemplate* pblocktemplate; - if (pindexPrev != chainActive.LastTip() || + if (pindexPrev != chainActive.Tip() || (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5)) { // Clear pindexPrev so future calls make a new block, despite any failures from here on @@ -758,7 +758,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp // Store the pindexBest used before CreateNewBlockWithKey, to avoid races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrevNew = chainActive.LastTip(); + CBlockIndex* pindexPrevNew = chainActive.Tip(); nStart = GetTime(); // Create new block @@ -825,7 +825,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp // Correct this if GetBlockTemplate changes the order entry.push_back(Pair("foundersreward", (int64_t)tx.vout[1].nValue)); } - CAmount nReward = GetBlockSubsidy(chainActive.LastTip()->nHeight+1, Params().GetConsensus()); + CAmount nReward = GetBlockSubsidy(chainActive.Tip()->nHeight+1, Params().GetConsensus()); entry.push_back(Pair("coinbasevalue", nReward)); entry.push_back(Pair("required", true)); txCoinbase = entry; @@ -859,7 +859,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp // result.push_back(Pair("coinbaseaux", aux)); // result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); //} - result.push_back(Pair("longpollid", chainActive.LastTip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast))); + result.push_back(Pair("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast))); if ( ASSETCHAINS_STAKED != 0 ) { arith_uint256 POWtarget; int32_t PoSperc; @@ -877,7 +877,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp result.push_back(Pair("mutable", aMutable)); result.push_back(Pair("noncerange", "00000000ffffffff")); result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS)); - result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE(chainActive.LastTip()->nHeight+1))); + result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE(chainActive.Tip()->nHeight+1))); result.push_back(Pair("curtime", pblock->GetBlockTime())); result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); @@ -959,8 +959,7 @@ UniValue submitblock(const UniValue& params, bool fHelp, const CPubKey& mypk) CValidationState state; submitblock_StateCatcher sc(block.GetHash()); RegisterValidationInterface(&sc); - //LogPrintf("submitblock, height=%d, coinbase sequence: %d, scriptSig: %s\n", chainActive.LastTip()->nHeight+1, block.vtx[0].vin[0].nSequence, block.vtx[0].vin[0].scriptSig.ToString().c_str()); - bool fAccepted = ProcessNewBlock(1,chainActive.LastTip()->nHeight+1,state, NULL, &block, true, NULL); + bool fAccepted = ProcessNewBlock(1,chainActive.Tip()->nHeight+1,state, NULL, &block, true, NULL); UnregisterValidationInterface(&sc); if (fBlockPresent) { diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 3676dfe2..136b49cb 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -176,7 +176,7 @@ UniValue geterablockheights(const UniValue& params, bool fHelp, const CPubKey& m CBlockIndex *pindex; int8_t lastera,era = 0; UniValue ret(UniValue::VOBJ); - for (size_t i = 1; i < chainActive.LastTip()->nHeight; i++) + for (size_t i = 1; i < chainActive.Tip()->nHeight; i++) { pindex = chainActive[i]; era = getera(pindex->nTime)+1; @@ -272,8 +272,8 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) longestchain = chainActive.Height(); //fprintf(stderr,"after longestchain %u\n",(uint32_t)time(NULL)); obj.push_back(Pair("longestchain", longestchain)); - if ( chainActive.LastTip() != 0 ) - obj.push_back(Pair("tiptime", (int)chainActive.LastTip()->nTime)); + if ( chainActive.Tip() != 0 ) + obj.push_back(Pair("tiptime", (int)chainActive.Tip()->nTime)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); #ifdef ENABLE_WALLET if (pwalletMain) { @@ -297,7 +297,7 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) if ( (notaryid= StakedNotaryID(notaryname, (char *)NOTARY_ADDRESS.c_str())) != -1 ) { obj.push_back(Pair("notaryid", notaryid)); obj.push_back(Pair("notaryname", notaryname)); - } else if( (notaryid= komodo_whoami(pubkeystr,(int32_t)chainActive.LastTip()->nHeight,komodo_chainactive_timestamp())) >= 0 ) { + } else if( (notaryid= komodo_whoami(pubkeystr,(int32_t)chainActive.Tip()->nHeight,komodo_chainactive_timestamp())) >= 0 ) { obj.push_back(Pair("notaryid", notaryid)); if ( KOMODO_LASTMINED != 0 ) obj.push_back(Pair("lastmined", KOMODO_LASTMINED)); @@ -1085,7 +1085,7 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp, const CPubKey& mypk result.push_back(Pair("utxos", utxos)); LOCK(cs_main); - result.push_back(Pair("hash", chainActive.LastTip()->GetBlockHash().GetHex())); + result.push_back(Pair("hash", chainActive.Tip()->GetBlockHash().GetHex())); result.push_back(Pair("height", (int)chainActive.Height())); return result; } else { @@ -1235,7 +1235,7 @@ CAmount checkburnaddress(CAmount &received, int64_t &nNotaryPay, int32_t &height balance += it->second; } // Get notary pay from current chain tip - CBlockIndex* pindex = chainActive.LastTip(); + CBlockIndex* pindex = chainActive.Tip(); nNotaryPay = pindex->nNotaryPay; height = pindex->nHeight; } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 9bb72173..464658b2 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -272,7 +272,7 @@ void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue& const CTxOut& txout = tx.vout[i]; UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); - if ( ASSETCHAINS_SYMBOL[0] == 0 && pindex != 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.LastTip()) != 0 ) + if ( ASSETCHAINS_SYMBOL[0] == 0 && pindex != 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.Tip()) != 0 ) { int64_t interest; int32_t txheight; uint32_t locktime; interest = komodo_accrued_interest(&txheight,&locktime,tx.GetHash(),i,0,txout.nValue,(int32_t)tipindex->nHeight); @@ -374,7 +374,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) const CTxOut& txout = tx.vout[i]; UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); - if ( KOMODO_NSPV_FULLNODE && ASSETCHAINS_SYMBOL[0] == 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.LastTip()) != 0 ) + if ( KOMODO_NSPV_FULLNODE && ASSETCHAINS_SYMBOL[0] == 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.Tip()) != 0 ) { int64_t interest; int32_t txheight; uint32_t locktime; interest = komodo_accrued_interest(&txheight,&locktime,tx.GetHash(),i,0,txout.nValue,(int32_t)tipindex->nHeight); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index cf4c6fad..4037843e 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -520,12 +520,12 @@ void CTxMemPool::removeExpired(unsigned int nBlockHeight) for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { const CTransaction& tx = it->GetTx(); - tipindex = chainActive.LastTip(); + tipindex = chainActive.Tip(); - /* cmptime = chainActive.LastTip()->GetMedianTimePast() + 777 - here for interest validation, inside + /* cmptime = chainActive.Tip()->GetMedianTimePast() + 777 - here for interest validation, inside CTxMemPool::removeExpired. need to test, may be here better to validate against pindexNew->nTime. In ConnectBlock we have a condition for each tx like komodo_validate_interest(..., block.nTime), so - blocks mined with such txes will be valid. Mean, may be chainActive.LastTip()->GetMedianTimePast() + 777 + blocks mined with such txes will be valid. Mean, may be chainActive.Tip()->GetMedianTimePast() + 777 is "too earlier" condition. [nBlockHeight should be equal tipindex->nHeight+1 here] */ diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index dca93461..08f22a71 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -376,8 +376,8 @@ bool AsyncRPCOperation_sendmany::main_impl() { // locktime to spend time locked coinbases if (ASSETCHAINS_SYMBOL[0] == 0) { - //if ((uint32_t)chainActive.LastTip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) - if ( !komodo_hardfork_active((uint32_t)chainActive.LastTip()->nTime) ) + //if ((uint32_t)chainActive.Tip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) + if ( !komodo_hardfork_active((uint32_t)chainActive.Tip()->nTime) ) builder_.SetLockTime((uint32_t)time(NULL) - 60); // set lock time for Komodo interest else builder_.SetLockTime((uint32_t)chainActive.Tip()->GetMedianTimePast()); @@ -393,8 +393,8 @@ bool AsyncRPCOperation_sendmany::main_impl() { } if (ASSETCHAINS_SYMBOL[0] == 0) { - //if ((uint32_t)chainActive.LastTip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) - if ( !komodo_hardfork_active((uint32_t)chainActive.LastTip()->nTime) ) + //if ((uint32_t)chainActive.Tip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) + if ( !komodo_hardfork_active((uint32_t)chainActive.Tip()->nTime) ) rawTx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 else rawTx.nLockTime = (uint32_t)chainActive.Tip()->GetMedianTimePast(); @@ -599,8 +599,8 @@ bool AsyncRPCOperation_sendmany::main_impl() { CMutableTransaction mtx(tx_); crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_); mtx.joinSplitPubKey = joinSplitPubKey_; - //if ((uint32_t)chainActive.LastTip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) - if ( !komodo_hardfork_active((uint32_t)chainActive.LastTip()->nTime) ) + //if ((uint32_t)chainActive.Tip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) + if ( !komodo_hardfork_active((uint32_t)chainActive.Tip()->nTime) ) mtx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 else mtx.nLockTime = (uint32_t)chainActive.Tip()->GetMedianTimePast(); @@ -1375,8 +1375,8 @@ void AsyncRPCOperation_sendmany::add_taddr_outputs_to_tx() { CTxOut out(nAmount, scriptPubKey); rawTx.vout.push_back(out); } - //if ((uint32_t)chainActive.LastTip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) - if ( !komodo_hardfork_active((uint32_t)chainActive.LastTip()->nTime) ) + //if ((uint32_t)chainActive.Tip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) + if ( !komodo_hardfork_active((uint32_t)chainActive.Tip()->nTime) ) rawTx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 else rawTx.nLockTime = (uint32_t)chainActive.Tip()->GetMedianTimePast(); @@ -1406,8 +1406,8 @@ void AsyncRPCOperation_sendmany::add_taddr_change_output_to_tx(CBitcoinAddress * CMutableTransaction rawTx(tx_); rawTx.vout.push_back(out); - //if ((uint32_t)chainActive.LastTip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) - if ( !komodo_hardfork_active((uint32_t)chainActive.LastTip()->nTime) ) + //if ((uint32_t)chainActive.Tip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) + if ( !komodo_hardfork_active((uint32_t)chainActive.Tip()->nTime) ) rawTx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 else rawTx.nLockTime = (uint32_t)chainActive.Tip()->GetMedianTimePast(); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 4d64297e..83aa75a6 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -374,7 +374,7 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys if (!file.is_open()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); - int64_t nTimeBegin = chainActive.LastTip()->GetBlockTime(); + int64_t nTimeBegin = chainActive.Tip()->GetBlockTime(); bool fGood = true; @@ -455,7 +455,7 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys file.close(); pwalletMain->ShowProgress("", 100); // hide progress dialog in GUI - CBlockIndex *pindex = chainActive.LastTip(); + CBlockIndex *pindex = chainActive.Tip(); while (pindex && pindex->pprev && pindex->GetBlockTime() > nTimeBegin - 7200) pindex = pindex->pprev; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index fe26b38f..536623ef 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -539,7 +539,7 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) if ( ASSETCHAINS_PRIVATE != 0 && AmountFromValue(params[1]) > 0 ) { - if ( komodo_isnotaryvout((char *)params[0].get_str().c_str(),chainActive.LastTip()->nTime) == 0 ) + if ( komodo_isnotaryvout((char *)params[0].get_str().c_str(),chainActive.Tip()->nTime) == 0 ) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid " + strprintf("%s",komodo_chainname()) + " address"); } @@ -663,7 +663,7 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) valuesize = (int32_t)strlen(params[1].get_str().c_str()); } memcpy(keyvalue,key,keylen); - if ( (refvaluesize= komodo_kvsearch(&refpubkey,chainActive.LastTip()->nHeight,&tmpflags,&height,&keyvalue[keylen],key,keylen)) >= 0 ) + if ( (refvaluesize= komodo_kvsearch(&refpubkey,chainActive.Tip()->nHeight,&tmpflags,&height,&keyvalue[keylen],key,keylen)) >= 0 ) { if ( (tmpflags & KOMODO_KVPROTECTED) != 0 ) { @@ -688,7 +688,7 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) // LogPrintf("%02x",((uint8_t *)&sig)[i]); //LogPrintf(" sig for keylen.%d + valuesize.%d\n",keylen,refvaluesize); ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL))); - height = chainActive.LastTip()->nHeight; + height = chainActive.Tip()->nHeight; if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 ) ret.push_back(Pair("owner",refpubkey.GetHex())); ret.push_back(Pair("height", (int64_t)height)); @@ -760,7 +760,7 @@ UniValue paxdeposit(const UniValue& params, bool fHelp, const CPubKey& mypk) int64_t fiatoshis = atof(params[1].get_str().c_str()) * COIN; std::string base = params[2].get_str(); std::string dest; - height = chainActive.LastTip()->nHeight; + height = chainActive.Tip()->nHeight; if ( pax_fiatstatus(&available,&deposited,&issued,&withdrawn,&approved,&redeemed,(char *)base.c_str()) != 0 || available < fiatoshis ) { LogPrintf("available %llu vs fiatoshis %llu\n",(long long)available,(long long)fiatoshis); @@ -2984,16 +2984,15 @@ UniValue listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); CBlockIndex *tipindex,*pindex = it->second; uint64_t interest; uint32_t locktime; - if ( pindex != 0 && (tipindex= chainActive.LastTip()) != 0 ) + if ( pindex != 0 && (tipindex= chainActive.Tip()) != 0 ) { interest = komodo_accrued_interest(&txheight,&locktime,out.tx->GetHash(),out.i,0,nValue,(int32_t)tipindex->nHeight); //interest = komodo_interest(txheight,nValue,out.tx->nLockTime,tipindex->nTime); entry.push_back(Pair("interest",ValueFromAmount(interest))); } - //LogPrintf("nValue %.8f pindex.%p tipindex.%p locktime.%u txheight.%d pindexht.%d\n",(double)nValue/COIN,pindex,chainActive.LastTip(),locktime,txheight,pindex->nHeight); } - else if ( chainActive.LastTip() != 0 ) - txheight = (chainActive.LastTip()->nHeight - out.nDepth - 1); + else if ( chainActive.Tip() != 0 ) + txheight = (chainActive.Tip()->nHeight - out.nDepth - 1); entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); entry.push_back(Pair("rawconfirmations",out.nDepth)); entry.push_back(Pair("confirmations",komodo_dpowconfs(txheight,out.nDepth))); @@ -3020,7 +3019,7 @@ uint64_t komodo_interestsum() { BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); CBlockIndex *tipindex,*pindex = it->second; - if ( pindex != 0 && (tipindex= chainActive.LastTip()) != 0 ) + if ( pindex != 0 && (tipindex= chainActive.Tip()) != 0 ) { interest = komodo_accrued_interest(&txheight,&locktime,out.tx->GetHash(),out.i,0,nValue,(int32_t)tipindex->nHeight); //interest = komodo_interest(pindex->nHeight,nValue,out.tx->nLockTime,tipindex->nTime); @@ -3753,7 +3752,7 @@ UniValue z_getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - bool allowSapling = (Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight <= chainActive.LastTip()->nHeight); + bool allowSapling = (Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight <= chainActive.Tip()->nHeight); std::string defaultType; if ( GetTime() < KOMODO_SAPLING_ACTIVATION ) @@ -4995,12 +4994,12 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp, const CPubKey& myp Params().GetConsensus(), nextBlockHeight, pwalletMain); // Contextual transaction we will build on - int blockHeight = chainActive.LastTip()->nHeight; + int blockHeight = chainActive.Tip()->nHeight; nextBlockHeight = blockHeight + 1; // (used if no Sapling addresses are involved) CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction( Params().GetConsensus(), nextBlockHeight); - contextualTx.nLockTime = chainActive.LastTip()->nHeight; + contextualTx.nLockTime = chainActive.Tip()->nHeight; if (contextualTx.nVersion == 1) { contextualTx.nVersion = 2; // Tx format should support vjoinsplits diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a271b47e..fe2445ce 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2794,7 +2794,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup double dProgressStart = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false); - double dProgressTip = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip(), false); + double dProgressTip = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip(), false); while (pindex) { if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0) @@ -3349,25 +3349,19 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const if ( !IS_MODE_EXCHANGEWALLET ) { uint32_t locktime; int32_t txheight; CBlockIndex *tipindex; - if ( ASSETCHAINS_SYMBOL[0] == 0 && chainActive.LastTip() != 0 && chainActive.LastTip()->nHeight >= 60000 ) + if ( ASSETCHAINS_SYMBOL[0] == 0 && chainActive.Tip() != 0 && chainActive.Tip()->nHeight >= 60000 ) { if ( pcoin->vout[i].nValue >= 10*COIN ) { - if ( (tipindex= chainActive.LastTip()) != 0 ) + if ( (tipindex= chainActive.Tip()) != 0 ) { komodo_accrued_interest(&txheight,&locktime,wtxid,i,0,pcoin->vout[i].nValue,(int32_t)tipindex->nHeight); interest = komodo_interestnew(txheight,pcoin->vout[i].nValue,locktime,tipindex->nTime); } else interest = 0; - //interest = komodo_interestnew(chainActive.LastTip()->nHeight+1,pcoin->vout[i].nValue,pcoin->nLockTime,chainActive.LastTip()->nTime); if ( interest != 0 ) { - //LogPrintf("wallet nValueRet %.8f += interest %.8f ht.%d lock.%u/%u tip.%u\n",(double)pcoin->vout[i].nValue/COIN,(double)interest/COIN,txheight,locktime,pcoin->nLockTime,tipindex->nTime); - //LogPrintf("wallet nValueRet %.8f += interest %.8f ht.%d lock.%u tip.%u\n",(double)pcoin->vout[i].nValue/COIN,(double)interest/COIN,chainActive.LastTip()->nHeight+1,pcoin->nLockTime,chainActive.LastTip()->nTime); - //ptr = (uint64_t *)&pcoin->vout[i].nValue; - //(*ptr) += interest; ptr = (uint64_t *)&pcoin->vout[i].interest; (*ptr) = interest; - //pcoin->vout[i].nValue += interest; } else { @@ -3780,8 +3774,8 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt txNew.nLockTime = 0; else { - if ( !komodo_hardfork_active((uint32_t)chainActive.LastTip()->nTime) ) - txNew.nLockTime = (uint32_t)chainActive.LastTip()->nTime + 1; // set to a time close to now + if ( !komodo_hardfork_active((uint32_t)chainActive.Tip()->nTime) ) + txNew.nLockTime = (uint32_t)chainActive.Tip()->nTime + 1; // set to a time close to now else txNew.nLockTime = (uint32_t)chainActive.Tip()->GetMedianTimePast(); } From f6ce184b2c5561a7ab9e5514887b11d3e412e998 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Sat, 20 Aug 2022 20:08:31 +0200 Subject: [PATCH 05/27] Ensure pindexPrev is not null before mining against it. Backport of https://github.com/zcash/zcash/pull/5853 to our codebase. --- src/miner.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/miner.cpp b/src/miner.cpp index f4a1a726..53aff8d4 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1318,6 +1318,13 @@ void static BitcoinMiner() LOCK(cs_main); pindexPrev = chainActive.Tip(); } + + // If we don't have a valid chain tip to work from, wait and try again. + if (pindexPrev == nullptr) { + MilliSleep(1000); + continue; + } + if ( Mining_height != pindexPrev->nHeight+1 ) { Mining_height = pindexPrev->nHeight+1; From e7069b0caab96be63051fec2fd91743dfe75746d Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Tue, 6 Sep 2022 18:42:41 +0200 Subject: [PATCH 06/27] CDBEnv bitdb -> std::shared_ptr bitdb(new CDBEnv()) --- src/wallet/db.cpp | 45 ++++++++++++++++++++++++--------------------- src/wallet/db.h | 6 +++--- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 834fdcd2..68d8bd23 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -46,7 +46,10 @@ unsigned int nWalletDBUpdated; // CDB // -CDBEnv bitdb; +// A singleton for all wallets in this process +// Making this a static variable causes problems with testing, so +// switching to a shared_ptr +std::shared_ptr bitdb(new CDBEnv()); void CDBEnv::EnvShutdown() { @@ -274,17 +277,17 @@ CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnClose nFlags |= DB_CREATE; { - LOCK(bitdb.cs_db); - if (!bitdb.Open(GetDataDir())) + LOCK(bitdb->cs_db); + if (!bitdb->Open(GetDataDir())) throw runtime_error("CDB: Failed to open database environment."); strFile = strFilename; - ++bitdb.mapFileUseCount[strFile]; - pdb = bitdb.mapDb[strFile]; + ++bitdb->mapFileUseCount[strFile]; + pdb = bitdb->mapDb[strFile]; if (pdb == NULL) { - pdb = new Db(bitdb.dbenv, 0); + pdb = new Db(bitdb->dbenv, 0); - bool fMockDb = bitdb.IsMock(); + bool fMockDb = bitdb->IsMock(); if (fMockDb) { DbMpoolFile* mpf = pdb->get_mpf(); ret = mpf->set_flags(DB_MPOOL_NOFILE, 1); @@ -302,7 +305,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnClose if (ret != 0) { delete pdb; pdb = NULL; - --bitdb.mapFileUseCount[strFile]; + --bitdb->mapFileUseCount[strFile]; strFile = ""; throw runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFile)); } @@ -314,7 +317,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnClose fReadOnly = fTmp; } - bitdb.mapDb[strFile] = pdb; + bitdb->mapDb[strFile] = pdb; } } } @@ -329,7 +332,7 @@ void CDB::Flush() if (fReadOnly) nMinutes = 1; - bitdb.dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0); + bitdb->dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0); } void CDB::Close() @@ -345,8 +348,8 @@ void CDB::Close() Flush(); { - LOCK(bitdb.cs_db); - --bitdb.mapFileUseCount[strFile]; + LOCK(bitdb->cs_db); + --bitdb->mapFileUseCount[strFile]; } } @@ -377,19 +380,19 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) { while (true) { { - LOCK(bitdb.cs_db); - if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) { + LOCK(bitdb->cs_db); + if (!bitdb->mapFileUseCount.count(strFile) || bitdb->mapFileUseCount[strFile] == 0) { // Flush log data to the dat file - bitdb.CloseDb(strFile); - bitdb.CheckpointLSN(strFile); - bitdb.mapFileUseCount.erase(strFile); + bitdb->CloseDb(strFile); + bitdb->CheckpointLSN(strFile); + bitdb->mapFileUseCount.erase(strFile); bool fSuccess = true; LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile); string strFileRes = strFile + ".rewrite"; { // surround usage of db with extra {} CDB db(strFile.c_str(), "r"); - Db* pdbCopy = new Db(bitdb.dbenv, 0); + Db* pdbCopy = new Db(bitdb->dbenv, 0); int ret = pdbCopy->open(NULL, // Txn pointer strFileRes.c_str(), // Filename @@ -432,17 +435,17 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) } if (fSuccess) { db.Close(); - bitdb.CloseDb(strFile); + bitdb->CloseDb(strFile); if (pdbCopy->close(0)) fSuccess = false; delete pdbCopy; } } if (fSuccess) { - Db dbA(bitdb.dbenv, 0); + Db dbA(bitdb->dbenv, 0); if (dbA.remove(strFile.c_str(), NULL, 0)) fSuccess = false; - Db dbB(bitdb.dbenv, 0); + Db dbB(bitdb->dbenv, 0); if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0)) fSuccess = false; } diff --git a/src/wallet/db.h b/src/wallet/db.h index 8ad246de..dd9d50a5 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -60,7 +60,7 @@ class CDBEnv public: mutable CCriticalSection cs_db; - DbEnv *dbenv; + DbEnv *dbenv = nullptr; std::map mapFileUseCount; std::map mapDb; @@ -109,7 +109,7 @@ class CDBEnv } }; -extern CDBEnv bitdb; +extern std::shared_ptr bitdb; /** RAII class that provides access to a Berkeley database */ @@ -292,7 +292,7 @@ class CDB { if (!pdb || activeTxn) return false; - DbTxn* ptxn = bitdb.TxnBegin(); + DbTxn* ptxn = bitdb->TxnBegin(); if (!ptxn) return false; activeTxn = ptxn; From c7646f0e600480af2bc079685aea2561e0c8a9b9 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 9 Sep 2022 01:28:33 +0200 Subject: [PATCH 07/27] initial backport of Komodo #559 into our codebase - https://github.com/KomodoPlatform/komodo/pull/559 Tests (gtest, etc.) needs additional changes to build. --- src/addrman.h | 48 +- src/alert.cpp | 3 +- src/alert.h | 10 +- src/amount.h | 14 +- src/{cc/CCPegs.h => assetchain.h} | 58 +- src/bitcoin-cli.cpp | 9 +- src/bitcoind.cpp | 50 +- src/cc/CC made easy.md | 2 - src/cc/CCGateways.h | 2 + src/cc/CCImportGateway.h | 6 +- src/cc/CCPayments.h | 3 +- src/cc/CCPrices.h | 62 - src/cc/CCassetstx.cpp | 2 +- src/cc/CCcustom.cpp | 40 - src/cc/CCinclude.h | 42 +- src/cc/CCrewards.h | 1 - src/cc/CCtokens.cpp | 3 +- src/cc/CCutils.cpp | 76 +- src/cc/assets.cpp | 8 +- src/cc/auction.cpp | 1 + src/cc/betprotocol.cpp | 3 +- src/cc/cclib.cpp | 1 + src/cc/channels.cpp | 1 + src/cc/crypto777/OS_portable.h | 26 +- src/cc/customcc.cpp | 2 + src/cc/dapps/dappstd.c | 8 +- src/cc/dice.cpp | 4 +- src/cc/dilithium.c | 2 +- src/cc/eval.cpp | 10 +- src/cc/eval.h | 7 +- src/cc/faucet.cpp | 1 + src/cc/fsm.cpp | 1 + src/cc/games/prices.cpp | 3 +- src/cc/gamescc.cpp | 13 +- src/cc/gamescc.h | 1 + src/cc/gateways.cpp | 1 + src/cc/heir.cpp | 4 +- src/cc/import.cpp | 408 +-- src/cc/import.h | 59 + src/cc/importgateway.cpp | 3 +- src/cc/includes/cJSON.h | 7 +- src/cc/lotto.cpp | 1 + src/cc/musig.cpp | 1 + src/cc/oracles.cpp | 9 +- src/cc/payments.cpp | 6 +- src/cc/pegs.cpp | 1284 -------- src/cc/prices.cpp | 2510 ---------------- src/cc/rewards.cpp | 8 +- src/cc/rogue/main.c | 42 +- src/cc/rogue_rpc.cpp | 9 +- src/cc/sudoku.cpp | 10 +- src/chain.cpp | 18 +- src/chain.h | 83 +- src/chainparams.cpp | 254 +- src/chainparams.h | 154 +- src/chainparamsbase.h | 23 +- src/checkpoints.cpp | 37 +- src/checkpoints.h | 38 +- src/coins.cpp | 34 +- src/coins.h | 17 +- src/consensus/consensus.h | 2 - src/consensus/params.h | 23 +- src/consensus/upgrades.cpp | 4 - src/crosschain.cpp | 209 +- src/crosschain.h | 104 +- src/crosschain_authority.cpp | 70 - src/dbwrapper.h | 54 +- src/deprecation.cpp | 5 +- src/importcoin.cpp | 270 +- src/importcoin.h | 237 +- src/init.cpp | 77 +- src/init.h | 7 + src/komodo-tx.cpp | 1 + src/komodo.cpp | 319 +- src/komodo.h | 67 +- src/komodo_bitcoind.cpp | 362 +-- src/komodo_bitcoind.h | 32 +- src/komodo_cJSON.c | 4 - src/komodo_cJSON.h | 4 + src/komodo_ccdata.cpp | 7 +- src/komodo_curve25519.cpp | 79 +- src/komodo_curve25519.h | 8 - src/komodo_defs.h | 108 +- src/komodo_events.cpp | 83 +- src/komodo_events.h | 12 +- src/komodo_extern_globals.h | 30 +- src/komodo_gateway.cpp | 2669 ++--------------- src/komodo_gateway.h | 243 +- src/komodo_globals.cpp | 266 +- src/komodo_globals.h | 209 +- src/komodo_hardfork.cpp | 484 +++ src/komodo_hardfork.h | 475 +-- src/komodo_interest.cpp | 260 +- src/komodo_interest.h | 48 +- src/komodo_jumblr.cpp | 763 ----- src/komodo_jumblr.h | 112 - src/komodo_kv.cpp | 265 +- src/komodo_kv.h | 68 +- src/komodo_nSPV.h | 11 +- src/komodo_nSPV_defs.h | 14 +- src/komodo_nSPV_fullnode.h | 17 +- src/komodo_nSPV_superlite.h | 6 +- src/komodo_nSPV_wallet.h | 13 +- src/komodo_notary.cpp | 354 ++- src/komodo_notary.h | 54 +- src/komodo_pax.cpp | 154 +- src/komodo_pax.h | 9 +- src/komodo_port.c | 31 +- src/komodo_structs.cpp | 99 +- src/komodo_structs.h | 76 +- src/komodo_utils.cpp | 1222 +++++--- src/komodo_utils.h | 316 +- src/main.cpp | 455 ++- src/main.h | 92 +- src/metrics.cpp | 5 +- src/miner.cpp | 295 +- src/miner.h | 5 +- src/mini-gmp.c | 2 +- src/mini-gmp.h | 2 +- src/net.cpp | 19 +- src/notaries_staked.cpp | 50 +- src/notaries_staked.h | 4 +- src/notarisationdb.cpp | 82 +- src/notarisationdb.h | 39 +- src/policy/fees.cpp | 8 +- src/pow.cpp | 47 +- src/qt/komodo.cpp | 25 +- src/qt/transactiondesc.cpp | 3 +- src/rest.cpp | 9 +- src/rpc/blockchain.cpp | 413 +-- src/rpc/blockchain.h | 20 + src/rpc/client.cpp | 3 - src/rpc/crosschain.cpp | 76 +- src/rpc/mining.cpp | 154 +- src/rpc/misc.cpp | 98 +- src/rpc/net.cpp | 3 +- src/rpc/net.h | 20 + src/rpc/rawtransaction.cpp | 65 +- src/rpc/rawtransaction.h | 19 + src/rpc/register.h | 7 - src/rpc/server.cpp | 52 +- src/rpc/server.h | 34 - src/rpc/testtransactions.cpp | 268 -- src/script/interpreter.cpp | 11 + src/script/sign.cpp | 7 - src/script/standard.cpp | 8 +- src/sendalert.cpp | 1 - src/txdb.cpp | 3 +- src/txdb.h | 186 +- src/txmempool.cpp | 34 +- src/util.cpp | 90 +- src/util.h | 15 + src/utiltime.cpp | 29 +- src/utiltime.h | 35 +- src/wallet-utility.cpp | 5 +- .../asyncrpcoperation_mergetoaddress.cpp | 2 +- src/wallet/asyncrpcoperation_sendmany.cpp | 17 +- .../asyncrpcoperation_shieldcoinbase.cpp | 2 +- src/wallet/rpcdump.cpp | 9 +- src/wallet/rpcwallet.cpp | 575 +--- src/wallet/rpcwallet.h | 13 + src/wallet/wallet.cpp | 82 +- src/wallet/walletdb.cpp | 28 +- src/zcash/CreateJoinSplit.cpp | 1 - src/zcbenchmarks.cpp | 2 +- 165 files changed, 6128 insertions(+), 13360 deletions(-) rename src/{cc/CCPegs.h => assetchain.h} (52%) delete mode 100644 src/cc/CCPrices.h create mode 100644 src/cc/import.h delete mode 100644 src/cc/pegs.cpp delete mode 100644 src/cc/prices.cpp delete mode 100644 src/crosschain_authority.cpp create mode 100644 src/komodo_hardfork.cpp delete mode 100644 src/komodo_jumblr.cpp delete mode 100644 src/komodo_jumblr.h create mode 100644 src/rpc/blockchain.h create mode 100644 src/rpc/net.h create mode 100644 src/rpc/rawtransaction.h delete mode 100644 src/rpc/testtransactions.cpp diff --git a/src/addrman.h b/src/addrman.h index 28e07a82..93c3692a 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -258,6 +258,33 @@ friend class CAddrManTest; //! Wraps GetRandInt to allow tests to override RandomInt and make it deterministic. virtual int RandomInt(int nMax); + /*** + * @brief Clears the internal collections and fills them again + * @note the mutex should be held before this method is called + * @note the constructor calls this directly with no lock + */ + void Clear_() + { + std::vector().swap(vRandom); + nKey = GetRandHash(); + for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) { + for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) { + vvNew[bucket][entry] = -1; + } + } + for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) { + for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) { + vvTried[bucket][entry] = -1; + } + } + + nIdCount = 0; + nTried = 0; + nNew = 0; + mapInfo.clear(); + mapAddr.clear(); + } + #ifdef DEBUG_ADDRMAN //! Perform consistency check. Returns an error code or zero. int Check_(); @@ -502,29 +529,12 @@ friend class CAddrManTest; void Clear() { LOCK(cs); - std::vector().swap(vRandom); - nKey = GetRandHash(); - for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) { - for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) { - vvNew[bucket][entry] = -1; - } - } - for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) { - for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) { - vvTried[bucket][entry] = -1; - } - } - - nIdCount = 0; - nTried = 0; - nNew = 0; - mapInfo.clear(); - mapAddr.clear(); + Clear_(); } CAddrMan() { - Clear(); + Clear_(); } ~CAddrMan() diff --git a/src/alert.cpp b/src/alert.cpp index e76f6a41..4991e360 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -261,8 +261,7 @@ bool CAlert::ProcessAlert(const std::vector& alertKey, bool fThre return true; } -void -CAlert::Notify(const std::string& strMessage, bool fThread) +void CAlert::Notify(const std::string& strMessage, bool fThread) { std::string strCmd = GetArg("-alertnotify", ""); if (strCmd.empty()) return; diff --git a/src/alert.h b/src/alert.h index 16204c9c..51703aab 100644 --- a/src/alert.h +++ b/src/alert.h @@ -29,11 +29,6 @@ #include #include -class CAlert; -class CNode; -class uint256; - -extern std::map mapAlerts; extern CCriticalSection cs_mapAlerts; /** Alerts are for notifying old versions if they become too obsolete and @@ -86,6 +81,9 @@ class CUnsignedAlert std::string ToString() const; }; +class CNode; +class uint256; + /** An alert is a combination of a serialized CUnsignedAlert and a signature. */ class CAlert : public CUnsignedAlert { @@ -124,4 +122,6 @@ class CAlert : public CUnsignedAlert static CAlert getAlertByHash(const uint256 &hash); }; +extern std::map mapAlerts; + #endif // BITCOIN_ALERT_H diff --git a/src/amount.h b/src/amount.h index c2d48475..4ec00935 100644 --- a/src/amount.h +++ b/src/amount.h @@ -21,10 +21,11 @@ #ifndef BITCOIN_AMOUNT_H #define BITCOIN_AMOUNT_H -#include "serialize.h" +#include "serialize.h" #include #include +#include typedef int64_t CAmount; @@ -32,17 +33,6 @@ static const CAmount COIN = 100000000; static const CAmount CENT = 1000000; extern const std::string CURRENCY_UNIT; - -/** No amount larger than this (in satoshi) is valid. - * - * Note that this constant is *not* the total money supply, which in Bitcoin - * currently happens to be less than 21,000,000 BTC for various reasons, but - * rather a sanity check. As this sanity check is used by consensus-critical - * validation code, the exact value of the MAX_MONEY constant is consensus - * critical; in unusual circumstances like a(nother) overflow bug that allowed - * for the creation of coins out of thin air modification could lead to a fork. - * */ -//static const CAmount MAX_MONEY = 21000000 * COIN; extern int64_t MAX_MONEY; inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } diff --git a/src/cc/CCPegs.h b/src/assetchain.h similarity index 52% rename from src/cc/CCPegs.h rename to src/assetchain.h index 78f1acca..c6c4a94f 100644 --- a/src/cc/CCPegs.h +++ b/src/assetchain.h @@ -1,3 +1,4 @@ +#pragma once /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * @@ -12,25 +13,42 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ +#include +class assetchain +{ +public: + assetchain() : symbol_("") {} + assetchain(const std::string& symbol) : symbol_(symbol) + { + if (symbol_.size() > 64) + symbol_ = symbol_.substr(0, 64); + } + /***** + * @returns true if the chain is Komodo + */ + bool isKMD() { return symbol_.empty(); } + /**** + * @param in the symbol to compare + * @returns true if this chain's symbol matches + */ + bool isSymbol(const std::string& in) { return in == symbol_; } + /**** + * @returns this chain's symbol (will be empty for KMD) + */ + std::string symbol() { return symbol_; } + /**** + * @returns this chain's symbol, "KMD" in the case of Komodo + */ + std::string ToString() + { + if (symbol_.empty()) + return "KMD"; + return symbol_; + } + bool SymbolStartsWith(const std::string& in) { return symbol_.find(in) == 0; } +private: + std::string symbol_; +}; -#ifndef CC_PEGS_H -#define CC_PEGS_H - -#include "CCinclude.h" - -bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); - -// CCcustom -UniValue PegsCreate(const CPubKey& pk,uint64_t txfee,int64_t amount,std::vector bindtxids); -UniValue PegsFund(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount); -UniValue PegsGet(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount); -UniValue PegsRedeem(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid); -UniValue PegsLiquidate(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, uint256 liquidatetxid); -UniValue PegsExchange(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount); -UniValue PegsAccountHistory(const CPubKey& pk,uint256 pegstxid); -UniValue PegsAccountInfo(const CPubKey& pk,uint256 pegstxid); -UniValue PegsWorstAccounts(uint256 pegstxid); -UniValue PegsInfo(uint256 pegstxid); - -#endif +extern assetchain chainName; diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 54497258..31e0979c 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -31,8 +31,10 @@ #include #include #include "support/events.h" +#include "assetchain.h" + uint16_t BITCOIND_RPCPORT = 7771; -char ASSETCHAINS_SYMBOL[65]; +assetchain chainName; #include @@ -95,10 +97,9 @@ static int AppInitRPC(int argc, char* argv[]) // Parameters // ParseParameters(argc, argv); - std:string name; - name = GetArg("-ac_name",""); + std:string name = GetArg("-ac_name",""); if ( !name.empty() ) - strncpy(ASSETCHAINS_SYMBOL,name.c_str(),sizeof(ASSETCHAINS_SYMBOL)-1); + chainName = assetchain(name); if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) { std::string strUsage = _("Komodo RPC client version") + " " + FormatFullVersion() + "\n" + PrivacyInfo(); diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 3fcaf1c2..15a10853 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -28,6 +28,12 @@ #include "httpserver.h" #include "httprpc.h" +#include "komodo.h" +#include "komodo_defs.h" +#include "komodo_gateway.h" +#include "komodo_bitcoind.h" +#include "komodo_gateway.h" + #include #include #include @@ -56,16 +62,6 @@ */ static bool fDaemon; -#include "komodo_defs.h" -#define KOMODO_ASSETCHAIN_MAXLEN 65 -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; -extern int32_t ASSETCHAINS_BLOCKTIME; -extern uint64_t ASSETCHAINS_CBOPRET; -void komodo_passport_iteration(); -uint64_t komodo_interestsum(); -int32_t komodo_longestchain(); -void komodo_cbopretupdate(int32_t forceflag); -CBlockIndex *komodo_chainactive(int32_t height); void WaitForShutdown(boost::thread_group* threadGroup) { @@ -76,23 +72,18 @@ void WaitForShutdown(boost::thread_group* threadGroup) LogPrintf("error: earlytx must be before block height %d or tx does not exist\n",KOMODO_EARLYTXID_HEIGHT); StartShutdown(); } - /*if ( ASSETCHAINS_STAKED == 0 && ASSETCHAINS_ADAPTIVEPOW == 0 && (pindex= komodo_chainactive(1)) != 0 ) - { - if ( pindex->nTime > ADAPTIVEPOW_CHANGETO_DEFAULTON ) - { - ASSETCHAINS_ADAPTIVEPOW = 1; - fprintf(stderr,"default activate adaptivepow\n"); - } else fprintf(stderr,"height1 time %u vs %u\n",pindex->nTime,ADAPTIVEPOW_CHANGETO_DEFAULTON); - } //else fprintf(stderr,"cant find height 1\n");*/ + if ( ASSETCHAINS_CBOPRET != 0 ) komodo_pricesinit(); while (!fShutdown) { - //LogPrintf("call passport iteration\n"); - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + /* TODO: move to ThreadUpdateKomodoInternals */ + if ( chainName.isKMD() ) { - if ( KOMODO_NSPV_FULLNODE ) - komodo_passport_iteration(); + if ( KOMODO_NSPV_FULLNODE ) { + komodo_update_interest(); + komodo_longestchain(); + } for (i=0; i<10; i++) { fShutdown = ShutdownRequested(); @@ -103,10 +94,7 @@ void WaitForShutdown(boost::thread_group* threadGroup) } else { - //komodo_interestsum(); - //komodo_longestchain(); - if ( ASSETCHAINS_CBOPRET != 0 ) - komodo_cbopretupdate(0); + /* for ACs we do nothing at present */ for (i=0; i<=ASSETCHAINS_BLOCKTIME/5; i++) { fShutdown = ShutdownRequested(); @@ -128,12 +116,6 @@ void WaitForShutdown(boost::thread_group* threadGroup) // // Start // -extern bool IS_KOMODO_NOTARY; -extern int32_t USE_EXTERNAL_PUBKEY; -extern uint32_t ASSETCHAIN_INIT; -extern std::string NOTARY_PUBKEY; -int32_t komodo_is_issuer(); -void komodo_passport_iteration(); bool AppInit(int argc, char* argv[]) { @@ -182,7 +164,7 @@ bool AppInit(int argc, char* argv[]) chainparams_commandline(); LogPrintf("call komodo_args.(%s) NOTARY_PUBKEY.(%s)\n",argv[0],NOTARY_PUBKEY.c_str()); - LogPrintf("initialized %s at %u\n",ASSETCHAINS_SYMBOL,(uint32_t)time(NULL)); + LogPrintf("initialized %s at %u\n",chainName.symbol().c_str(),(uint32_t)time(NULL)); if (!boost::filesystem::is_directory(GetDataDir(false))) { LogPrintf("Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); @@ -230,7 +212,7 @@ bool AppInit(int argc, char* argv[]) fDaemon = GetBoolArg("-daemon", false); if (fDaemon) { - fprintf(stdout, "Komodo %s server starting\n",ASSETCHAINS_SYMBOL); + LogPrintf("Komodo %s server starting\n",chainName.symbol().c_str()); // Daemonize pid_t pid = fork(); diff --git a/src/cc/CC made easy.md b/src/cc/CC made easy.md index 2d108100..ff5886c8 100644 --- a/src/cc/CC made easy.md +++ b/src/cc/CC made easy.md @@ -98,8 +98,6 @@ EVAL(EVAL_LOTTO, 0xe9) \ EVAL(EVAL_HEIR, 0xea) \ EVAL(EVAL_CHANNELS, 0xeb) \ EVAL(EVAL_ORACLES, 0xec) \ -EVAL(EVAL_PRICES, 0xed) \ -EVAL(EVAL_PEGS, 0xee) \ EVAL(EVAL_TRIGGERS, 0xef) \ EVAL(EVAL_PAYMENTS, 0xf0) \ EVAL(EVAL_GATEWAYS, 0xf1) diff --git a/src/cc/CCGateways.h b/src/cc/CCGateways.h index 8793c0dc..a92a1bea 100644 --- a/src/cc/CCGateways.h +++ b/src/cc/CCGateways.h @@ -37,4 +37,6 @@ UniValue GatewaysExternalAddress(uint256 bindtxid,CPubKey pubkey); UniValue GatewaysDumpPrivKey(uint256 bindtxid,CKey privkey); UniValue GatewaysList(); +uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,uint256 &tokenid,std::string &coin,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector &gatewaypubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2,uint8_t &wiftype); + #endif diff --git a/src/cc/CCImportGateway.h b/src/cc/CCImportGateway.h index 9be54f23..545d9148 100644 --- a/src/cc/CCImportGateway.h +++ b/src/cc/CCImportGateway.h @@ -34,4 +34,8 @@ UniValue ImportGatewayExternalAddress(uint256 bindtxid,CPubKey pubkey); UniValue ImportGatewayDumpPrivKey(uint256 bindtxid,CKey key); UniValue ImportGatewayList(); UniValue ImportGatewayInfo(uint256 bindtxid); -#endif \ No newline at end of file + +uint8_t DecodeImportGatewayBindOpRet(char *burnaddr,const CScript &scriptPubKey,std::string &coin,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector &importgatewaypubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2,uint8_t &wiftype); +int64_t ImportGatewayVerify(char *refburnaddr,uint256 oracletxid,int32_t claimvout,std::string refcoin,uint256 burntxid,const std::string deposithex,std::vectorproof,uint256 merkleroot,CPubKey destpub,uint8_t taddr,uint8_t prefix,uint8_t prefix2); + +#endif diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index ac5f22c4..fad55840 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -18,12 +18,11 @@ #define CC_PAYMENTS_H #include "CCinclude.h" -#include #include #define PAYMENTS_TXFEE 10000 #define PAYMENTS_MERGEOFSET 60 // 1H extra. -extern std::vector > vAddressSnapshot; +extern std::vector > vAddressSnapshot; // daily snapshot extern int32_t lastSnapShotHeight; bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h deleted file mode 100644 index 3779111a..00000000 --- a/src/cc/CCPrices.h +++ /dev/null @@ -1,62 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - - -#ifndef CC_PRICES_H -#define CC_PRICES_H - -#include "komodo_defs.h" -#include "CCinclude.h" -int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); -extern void GetKomodoEarlytxidScriptPub(); -extern CScript KOMODO_EARLYTXID_SCRIPTPUB; - -// #define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) // defined in komodo_defs.h -#define PRICES_TXFEE 10000 -#define PRICES_MAXLEVERAGE 777 -#define PRICES_SMOOTHWIDTH 1 -#define KOMODO_MAXPRICES 2048 // must be power of 2 and less than 8192 -#define KOMODO_PRICEMASK (~(KOMODO_MAXPRICES - 1)) // actually 1111 1000 0000 0000 -#define PRICES_WEIGHT (KOMODO_MAXPRICES * 1) // 0000 1000 0000 0000 -#define PRICES_MULT (KOMODO_MAXPRICES * 2) // 0001 0000 0000 0000 -#define PRICES_DIV (KOMODO_MAXPRICES * 3) // 0001 1000 0000 0000 -#define PRICES_INV (KOMODO_MAXPRICES * 4) // 0010 0000 0000 0000 -#define PRICES_MDD (KOMODO_MAXPRICES * 5) // 0010 1000 0000 0000 -#define PRICES_MMD (KOMODO_MAXPRICES * 6) // 0011 0000 0000 0000 -#define PRICES_MMM (KOMODO_MAXPRICES * 7) // 0011 1000 0000 0000 -#define PRICES_DDD (KOMODO_MAXPRICES * 8) // 0100 0000 0000 0000 - -//#define PRICES_NORMFACTOR (int64_t)(SATOSHIDEN) -//#define PRICES_POINTFACTOR (int64_t)10000 - -#define PRICES_REVSHAREDUST 10000 -#define PRICES_SUBREVSHAREFEE(amount) ((amount) * 199 / 200) // revshare fee percentage == 0.005 -#define PRICES_MINAVAILFUNDFRACTION 0.1 // leveraged bet limit < fund fraction - -bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); - -// CCcustom -UniValue PricesBet(int64_t txfee,int64_t amount,int16_t leverage,std::vector synthetic); -UniValue PricesAddFunding(int64_t txfee,uint256 bettxid,int64_t amount); -UniValue PricesSetcostbasis(int64_t txfee,uint256 bettxid); -UniValue PricesRekt(int64_t txfee,uint256 bettxid,int32_t rektheight); -UniValue PricesCashout(int64_t txfee,uint256 bettxid); -UniValue PricesInfo(uint256 bettxid,int32_t refheight); -UniValue PricesList(uint32_t filter, CPubKey mypk); -UniValue PricesGetOrderbook(); -UniValue PricesRefillFund(int64_t amount); - - -#endif diff --git a/src/cc/CCassetstx.cpp b/src/cc/CCassetstx.cpp index c2b0ad93..72f0af68 100644 --- a/src/cc/CCassetstx.cpp +++ b/src/cc/CCassetstx.cpp @@ -15,7 +15,7 @@ #include "CCassets.h" #include "CCtokens.h" - +#include "komodo_bitcoind.h" UniValue AssetOrders(uint256 refassetid, CPubKey pk, uint8_t additionalEvalCode) { diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index b0aebd36..8d1a12db 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -25,8 +25,6 @@ #include "CCHeir.h" #include "CCchannels.h" #include "CCOracles.h" -#include "CCPrices.h" -#include "CCPegs.h" #include "CCPayments.h" #include "CCGateways.h" #include "CCtokens.h" @@ -168,28 +166,6 @@ uint8_t OraclesCCpriv[32] = { 0xf7, 0x4b, 0x5b, 0xa2, 0x7a, 0x5e, 0x9c, 0xda, 0x #undef FUNCNAME #undef EVALCODE -// Prices -#define FUNCNAME IsPricesInput -#define EVALCODE EVAL_PRICES -const char *PricesCCaddr = "RAL5Vh8NXmFqEKJRKrk1KjKaUckK7mM1iS"; -const char *PricesNormaladdr = "RBunXCsMHk5NPd6q8SQfmpgre3x133rSwZ"; -char PricesCChexstr[67] = { "039894cb054c0032e99e65e715b03799607aa91212a16648d391b6fa2cc52ed0cf" }; -uint8_t PricesCCpriv[32] = { 0x0a, 0x3b, 0xe7, 0x5d, 0xce, 0x06, 0xed, 0xb7, 0xc0, 0xb1, 0xbe, 0xe8, 0x7b, 0x5a, 0xd4, 0x99, 0xb8, 0x8d, 0xde, 0xac, 0xb2, 0x7e, 0x7a, 0x52, 0x96, 0x15, 0xd2, 0xa0, 0xc6, 0xb9, 0x89, 0x61 }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Pegs -#define FUNCNAME IsPegsInput -#define EVALCODE EVAL_PEGS -const char *PegsCCaddr = "RHnkVb7vHuHnjEjhkCF1bS6xxLLNZPv5fd"; -const char *PegsNormaladdr = "RMcCZtX6dHf1fz3gpLQhUEMQ8cVZ6Rzaro"; -char PegsCChexstr[67] = { "03c75c1de29a35e41606363b430c08be1c2dd93cf7a468229a082cc79c7b77eece" }; -uint8_t PegsCCpriv[32] = { 0x52, 0x56, 0x4c, 0x78, 0x87, 0xf7, 0xa2, 0x39, 0xb0, 0x90, 0xb7, 0xb8, 0x62, 0x80, 0x0f, 0x83, 0x18, 0x9d, 0xf4, 0xf4, 0xbd, 0x28, 0x09, 0xa9, 0x9b, 0x85, 0x54, 0x16, 0x0f, 0x3f, 0xfb, 0x65 }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - // Payments #define FUNCNAME IsPaymentsInput #define EVALCODE EVAL_PAYMENTS @@ -376,22 +352,6 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode) cp->validate = OraclesValidate; cp->ismyvin = IsOraclesInput; break; - case EVAL_PRICES: - strcpy(cp->unspendableCCaddr,PricesCCaddr); - strcpy(cp->normaladdr,PricesNormaladdr); - strcpy(cp->CChexstr,PricesCChexstr); - memcpy(cp->CCpriv,PricesCCpriv,32); - cp->validate = PricesValidate; - cp->ismyvin = IsPricesInput; - break; - case EVAL_PEGS: - strcpy(cp->unspendableCCaddr,PegsCCaddr); - strcpy(cp->normaladdr,PegsNormaladdr); - strcpy(cp->CChexstr,PegsCChexstr); - memcpy(cp->CCpriv,PegsCCpriv,32); - cp->validate = PegsValidate; - cp->ismyvin = IsPegsInput; - break; case EVAL_PAYMENTS: strcpy(cp->unspendableCCaddr,PaymentsCCaddr); strcpy(cp->normaladdr,PaymentsNormaladdr); diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 6b5fde79..e06abe66 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -79,9 +79,9 @@ Details. #define CC_MAXVINS 1024 #define CC_REQUIREMENTS_MSG (KOMODO_NSPV_SUPERLITE?"to use CC contracts you need to nspv_login first\n":"to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n") -#define SMALLVAL 0.000000000000001 -#define SATOSHIDEN ((uint64_t)100000000L) -#define dstr(x) ((double)(x) / SATOSHIDEN) +//#define SMALLVAL 0.000000000000001 +//#define SATOSHIDEN ((uint64_t)100000000L) +//#define dstr(x) ((double)(x) / SATOSHIDEN) #define CCDISABLEALL memset(ASSETCHAINS_CCDISABLES,1,sizeof(ASSETCHAINS_CCDISABLES)) #define CCENABLE(x) ASSETCHAINS_CCDISABLES[((uint8_t)x)] = 0 @@ -235,8 +235,6 @@ extern CWallet* pwalletMain; //!< global wallet object pointer to access wallet /// @private seems old-style bool GetAddressUnspent(uint160 addressHash, int type,std::vector > &unspentOutputs); -//CBlockIndex *komodo_getblockindex(uint256 hash); //moved to komodo_def.h -//int32_t komodo_nextheight(); //moved to komodo_def.h /// CCgetspenttxid finds the txid of the transaction which spends a transaction output. The function does this without loading transactions from the chain, by using spent index /// @param[out] spenttxid transaction id of the spending transaction @@ -252,11 +250,6 @@ void CCclearvars(struct CCcontract_info *cp); UniValue CClib(struct CCcontract_info *cp,char *method,char *jsonstr); UniValue CClib_info(struct CCcontract_info *cp); -//CBlockIndex *komodo_blockindex(uint256 hash); //moved to komodo_def.h -//CBlockIndex *komodo_chainactive(int32_t height); //moved to komodo_def.h -//int32_t komodo_blockheight(uint256 hash); //moved to komodo_def.h -//void StartShutdown(); - static const uint256 zeroid; //!< null uint256 constant /// \cond INTERNAL @@ -264,10 +257,13 @@ static uint256 ignoretxid; static int32_t ignorevin; /// \endcond -/// myGetTransaction is non-locking version of GetTransaction -/// @param hash hash of transaction to get (txid) -/// @param[out] txOut returned transaction object -/// @param[out] hashBlock hash of the block where the tx resides +/***** + * @brief get a transaction by its hash (without locks) + * @param[in] hash what to look for + * @param[out] txOut the found transaction + * @param[out] hashBlock the hash of the block (all zeros if still in mempool) + * @returns true if found + */ bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock); /// NSPV_myGetTransaction is called in NSPV mode @@ -288,7 +284,14 @@ int64_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag,int32_t lockfla /// \cond INTERNAL bool myIsutxo_spentinmempool(uint256 &spenttxid,int32_t &spentvini,uint256 txid,int32_t vout); -bool myAddtomempool(CTransaction &tx, CValidationState *pstate = NULL, bool fSkipExpiry = false); +/**** + * @brief add a transaction to the mempool + * @param[in] tx the transaction + * @param pstate where to store any error (can be nullptr) + * @param fSkipExpiry + * @returns true on success + */ +bool myAddtomempool(const CTransaction &tx, CValidationState *pstate = nullptr, bool fSkipExpiry = false); bool mytxid_inmempool(uint256 txid); int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout); int32_t myGet_mempool_txs(std::vector &txs,uint8_t evalcode,uint8_t funcid); @@ -368,11 +371,8 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys, struct CCcontract_info *c /// returns true if success bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); -//void komodo_sendmessage(int32_t minpeers,int32_t maxpeers,const char *message,std::vector payload); // moved to komodo_defs.h - /// @private int32_t payments_parsehexdata(std::vector &hexdata,cJSON *item,int32_t len); -// int32_t komodo_blockload(CBlock& block,CBlockIndex *pindex); // this def in komodo_defs.h /// Makes opreturn scriptPubKey for token creation transaction. Normally this function is called internally by the tokencreate rpc. You might need to call this function to create a customized token. /// The total opreturn length should not exceed 10001 byte @@ -689,7 +689,6 @@ uint64_t stringbits(char *str); uint256 revuint256(uint256 txid); char *uint256_str(char *dest,uint256 txid); char *pubkey33_str(char *dest,uint8_t *pubkey33); -//uint256 Parseuint256(const char *hexstr); // located in komodo_defs /// \endcond /// converts public key as array of uint8_t to normal address @@ -783,8 +782,6 @@ int32_t CCCointxidExists(char const *logcategory,uint256 cointxid); /// @private uint256 BitcoinGetProofMerkleRoot(const std::vector &proofData, std::vector &txids); -// bool komodo_txnotarizedconfirmed(uint256 txid); //moved to komodo_defs.h - /// @private CPubKey check_signing_pubkey(CScript scriptSig); @@ -988,6 +985,9 @@ UniValue report_ccerror(const char *category, int level, T print_to_stream) return err; } +bool komodo_txnotarizedconfirmed(uint256 txid); +uint32_t GetLatestTimestamp(int32_t height); + /// @private #define CCERR_RESULT(category,level,logoperator) return report_ccerror(category, level, [=](std::ostringstream &stream) {logoperator;}) #endif // #ifndef LOGSTREAM_DEFINED diff --git a/src/cc/CCrewards.h b/src/cc/CCrewards.h index d9f9edf6..4d6cc80f 100644 --- a/src/cc/CCrewards.h +++ b/src/cc/CCrewards.h @@ -18,7 +18,6 @@ #define CC_REWARDS_H #include "CCinclude.h" -#include #define EVAL_REWARDS 0xe5 #define REWARDSCC_MAXAPR (COIN * 25) diff --git a/src/cc/CCtokens.cpp b/src/cc/CCtokens.cpp index 19a5f786..1266f9cd 100644 --- a/src/cc/CCtokens.cpp +++ b/src/cc/CCtokens.cpp @@ -15,6 +15,7 @@ #include "CCtokens.h" #include "importcoin.h" +#include "komodo_bitcoind.h" /* TODO: correct this: ----------------------------- @@ -56,7 +57,7 @@ bool TokensValidate(struct CCcontract_info *cp, Eval* eval, const CTransaction & char destaddr[64], origaddr[64], CCaddr[64]; std::vector voutTokenPubkeys, vinTokenPubkeys; - if (strcmp(ASSETCHAINS_SYMBOL, "ROGUE") == 0 && chainActive.Height() <= 12500) + if ( chainName.isSymbol("ROGUE") && chainActive.Height() <= 12500) return true; numvins = tx.vin.size(); diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 12755a9e..8fd49ce2 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -16,18 +16,19 @@ /* CCutils has low level functions that are universally useful for all contracts. */ + #include "CCinclude.h" #include "komodo_structs.h" +#include "komodo_bitcoind.h" +#include "komodo_utils.h" #include "key_io.h" +#include "komodo_bitcoind.h" -#ifdef TESTMODE +#ifdef TESTMODE #define MIN_NON_NOTARIZED_CONFIRMS 2 #else #define MIN_NON_NOTARIZED_CONFIRMS 101 #endif // TESTMODE -int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); -struct komodo_state *komodo_stateptr(char *symbol,char *dest); -extern uint32_t KOMODO_DPOWCONFS; void endiancpy(uint8_t *dest,uint8_t *src,int32_t len) { @@ -159,7 +160,7 @@ bool CheckTxFee(const CTransaction &tx, uint64_t txfee, uint32_t height, uint64_ int64_t interest; uint64_t valuein; CCoinsViewMemPool viewMemPool(pcoinsTip, mempool); view.SetBackend(viewMemPool); - valuein = view.GetValueIn(height,&interest,tx,blocktime); + valuein = view.GetValueIn(height,interest,tx); actualtxfee = valuein-tx.GetValueOut(); if ( actualtxfee > txfee ) { @@ -173,7 +174,7 @@ uint32_t GetLatestTimestamp(int32_t height) { if ( KOMODO_NSPV_SUPERLITE ) return ((uint32_t)NSPV_blocktime(height)); return(komodo_heightstamp(height)); -} // :P +} void CCaddr2set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr) { @@ -381,7 +382,7 @@ bool ConstrainVout(CTxOut vout, int32_t CCflag, char *cmpaddr, int64_t nValue) } else if ( cmpaddr != 0 && (Getscriptaddress(destaddr, vout.scriptPubKey) == 0 || strcmp(destaddr, cmpaddr) != 0) ) { - LogPrintf("constrain vout error: check addr %s vs script addr %s\n", cmpaddr!=0?cmpaddr:"", destaddr!=0?destaddr:""); + LogPrintf("constrain vout error: check addr %s vs script addr %s\n", cmpaddr!=0?cmpaddr:"", destaddr); return(false); } else if ( nValue != 0 && nValue != vout.nValue ) //(nValue == 0 && vout.nValue < 10000) || ( @@ -433,7 +434,6 @@ bool priv2addr(char *coinaddr,uint8_t *buf33,uint8_t priv32[32]) std::vector Mypubkey() { - extern uint8_t NOTARY_PUBKEY33[33]; std::vector pubkey; int32_t i; uint8_t *dest,*pubkey33; pubkey33 = NOTARY_PUBKEY33; pubkey.resize(33); @@ -443,8 +443,6 @@ std::vector Mypubkey() return(pubkey); } -extern char NSPV_wifstr[],NSPV_pubkeystr[]; -extern uint32_t NSPV_logintime; #define NSPV_AUTOLOGOUT 777 bool Myprivkey(uint8_t myprivkey[]) @@ -452,16 +450,15 @@ bool Myprivkey(uint8_t myprivkey[]) char coinaddr[64],checkaddr[64]; std::string strAddress; char *dest; int32_t i,n; CBitcoinAddress address; CKeyID keyID; CKey vchSecret; uint8_t buf33[33]; if ( KOMODO_NSPV_SUPERLITE ) { + extern uint32_t NSPV_logintime; if ( NSPV_logintime == 0 || time(NULL) > NSPV_logintime+NSPV_AUTOLOGOUT ) { LogPrintf("need to be logged in to get myprivkey\n"); return false; } + extern char *NSPV_wifstr; vchSecret = DecodeSecret(NSPV_wifstr); memcpy(myprivkey,vchSecret.begin(),32); - //for (i=0; i<32; i++) - // fprintf(stderr,"%02x",myprivkey[i]); - //fprintf(stderr," myprivkey %s\n",NSPV_wifstr); memset((uint8_t *)vchSecret.begin(),0,32); return true; } @@ -821,39 +818,27 @@ int64_t TotalPubkeyCCInputs(const CTransaction &tx, const CPubKey &pubkey) bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector paramsNull,const CTransaction &ctx, unsigned int nIn) { - CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t height,i,n,from_mempool = 0; int64_t amount; std::vector origpubkey; - height = KOMODO_CONNECTING; if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation - return(true); - if ( ASSETCHAINS_CC == 0 || (height & ~(1<<30)) < KOMODO_CCACTIVATE ) + return true; + + if ( ASSETCHAINS_CC == 0 || (KOMODO_CONNECTING & ~(1<<30)) < KOMODO_CCACTIVATE ) return eval->Invalid("CC are disabled or not active yet"); - if ( (KOMODO_CONNECTING & (1<<30)) != 0 ) - { - from_mempool = 1; - height &= ((1<<30) - 1); - } + if (cp->validate == NULL) return eval->Invalid("validation not supported for eval code"); - //LogPrintf("KOMODO_CONNECTING.%d mempool.%d vs CCactive.%d\n",height,from_mempool,KOMODO_CCACTIVATE); - // there is a chance CC tx is valid in mempool, but invalid when in block, so we cant filter duplicate requests. if any of the vins are spent, for example - //txid = ctx.GetHash(); - //if ( txid == cp->prevtxid ) - // return(true); - //LogPrintf("process CC %02x\n",cp->evalcode); + // there is a chance CC tx is valid in mempool, but invalid when in block, so we cant filter duplicate requests. + // if any of the vins are spent, for example + CCclearvars(cp); + if ( paramsNull.size() != 0 ) // Don't expect params return eval->Invalid("Cannot have params"); - //else if ( ctx.vout.size() == 0 ) // spend can go to z-addresses - // return eval->Invalid("no-vouts"); else if ( (*cp->validate)(cp,eval,ctx,nIn) != 0 ) { - //LogPrintf("done CC %02x\n",cp->evalcode); - //cp->prevtxid = txid; - return(true); + return true; } - //LogPrintf("invalid CC %02x\n",cp->evalcode); - return(false); + return false; } extern struct CCcontract_info CCinfos[0x100]; @@ -862,38 +847,41 @@ bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C bool CClib_Dispatch(const CC *cond,Eval *eval,std::vector paramsNull,const CTransaction &txTo,unsigned int nIn) { - uint8_t evalcode; int32_t height,from_mempool; struct CCcontract_info *cp; if ( ASSETCHAINS_CCLIB != MYCCLIBNAME ) { LogPrintf("-ac_cclib=%s vs myname %s\n",ASSETCHAINS_CCLIB.c_str(),MYCCLIBNAME.c_str()); return eval->Invalid("-ac_cclib name mismatches myname"); } - height = KOMODO_CONNECTING; + if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation - return(true); + return true; + + // chain height calc and check + int32_t height = KOMODO_CONNECTING; if ( ASSETCHAINS_CC == 0 || (height & ~(1<<30)) < KOMODO_CCACTIVATE ) return eval->Invalid("CC are disabled or not active yet"); if ( (KOMODO_CONNECTING & (1<<30)) != 0 ) { - from_mempool = 1; height &= ((1<<30) - 1); } - evalcode = cond->code[0]; + + uint8_t evalcode = cond->code[0]; if ( evalcode >= EVAL_FIRSTUSER && evalcode <= EVAL_LASTUSER ) { - cp = &CCinfos[(int32_t)evalcode]; + CCcontract_info *cp = &CCinfos[(int32_t)evalcode]; if ( cp->didinit == 0 ) { if ( CClib_initcp(cp,evalcode) == 0 ) cp->didinit = 1; - else return eval->Invalid("unsupported CClib evalcode"); + else + return eval->Invalid("unsupported CClib evalcode"); } CCclearvars(cp); if ( paramsNull.size() != 0 ) // Don't expect params return eval->Invalid("Cannot have params"); else if ( CClib_validate(cp,height,eval,txTo,nIn) != 0 ) - return(true); - return(false); //eval->Invalid("error in CClib_validate"); + return true; + return false; //eval->Invalid("error in CClib_validate"); } return eval->Invalid("cclib CC must have evalcode between 16 and 127"); } diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 49890435..49fade28 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -148,17 +148,17 @@ bool AssetsValidate(struct CCcontract_info *cpAssets,Eval* eval,const CTransacti preventCCvins = preventCCvouts = -1; // add specific chains exceptions for old token support: - if (strcmp(ASSETCHAINS_SYMBOL, "SEC") == 0 && chainActive.Height() <= 144073) + if ( chainName.isSymbol("SEC") && chainActive.Height() <= 144073) return true; - if (strcmp(ASSETCHAINS_SYMBOL, "MGNX") == 0 && chainActive.Height() <= 210190) + if ( chainName.isSymbol("MGNX") && chainActive.Height() <= 210190) return true; // add specific chains exceptions for old token support: - if (strcmp(ASSETCHAINS_SYMBOL, "SEC") == 0 && chainActive.Height() <= 144073) + if ( chainName.isSymbol("SEC") && chainActive.Height() <= 144073) return true; - if (strcmp(ASSETCHAINS_SYMBOL, "MGNX") == 0 && chainActive.Height() <= 210190) + if ( chainName.isSymbol("MGNX") && chainActive.Height() <= 210190) return true; if (numvouts == 0) diff --git a/src/cc/auction.cpp b/src/cc/auction.cpp index 8e9eabbf..4839a5f7 100644 --- a/src/cc/auction.cpp +++ b/src/cc/auction.cpp @@ -15,6 +15,7 @@ #include "CCauction.h" #include "../txmempool.h" +#include "komodo_bitcoind.h" /* */ diff --git a/src/cc/betprotocol.cpp b/src/cc/betprotocol.cpp index ae4211eb..da817a85 100644 --- a/src/cc/betprotocol.cpp +++ b/src/cc/betprotocol.cpp @@ -24,8 +24,7 @@ #include "cc/eval.h" #include "cc/utils.h" #include "primitives/transaction.h" - -int32_t komodo_nextheight(); +#include "komodo_bitcoind.h" std::vector BetProtocol::PlayerConditions() { diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 2c0fc48d..fff221ca 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -27,6 +27,7 @@ #include "core_io.h" #include "crosschain.h" #include "hex.h" +#include "komodo_bitcoind.h" #define FAUCET2SIZE COIN #define EVAL_FAUCET2 EVAL_FIRSTUSER diff --git a/src/cc/channels.cpp b/src/cc/channels.cpp index 256112cd..ff70d29c 100644 --- a/src/cc/channels.cpp +++ b/src/cc/channels.cpp @@ -14,6 +14,7 @@ ******************************************************************************/ #include "CCchannels.h" +#include "komodo_bitcoind.h" /* The idea here is to allow instant (mempool) payments that are secured by dPoW. In order to simplify things, channels CC will require creating reserves for each payee locked in the destination user's CC address. This will look like the payment is already made, but it is locked until further released. The dPoW protection comes from the cancel channel having a delayed effect until the next notarization. This way, if a payment release is made and the chain reorged, the same payment release will still be valid when it is re-broadcast into the mempool. diff --git a/src/cc/crypto777/OS_portable.h b/src/cc/crypto777/OS_portable.h index 5dd8f388..e1028fd3 100644 --- a/src/cc/crypto777/OS_portable.h +++ b/src/cc/crypto777/OS_portable.h @@ -115,10 +115,10 @@ int32_t hseek(HUFF *hp,int32_t offset,int32_t mode); #define GENESIS_PRIVKEYSTR "88a71671a6edd987ad9e9097428fc3f169decba3ac8f10da7b24e0ca16803b70" #define GENESIS_SECRET "It was a bright cold day in April, and the clocks were striking thirteen." -#define SATOSHIDEN ((uint64_t)100000000L) -#define dstr(x) ((double)(x) / SATOSHIDEN) +//#define SATOSHIDEN ((uint64_t)100000000L) +//#define dstr(x) ((double)(x) / SATOSHIDEN) -#define SMALLVAL 0.000000000000001 +//#define SMALLVAL 0.000000000000001 #define SETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] |= (1 << ((bitoffset) & 7))) #define GETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] & (1 << ((bitoffset) & 7))) @@ -130,20 +130,8 @@ int32_t hseek(HUFF *hp,int32_t offset,int32_t mode); #define portable_mutex_unlock pthread_mutex_unlock #define OS_thread_create pthread_create -#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0,0) #define issue_curlt(cmdstr,timeout) bitcoind_RPC(0,"curl",cmdstr,0,0,0,timeout) -struct allocitem { uint32_t allocsize,type; } PACKED; -struct queueitem { struct queueitem *next,*prev; uint32_t allocsize,type; } PACKED; -struct stritem { struct queueitem DL; void **retptrp; uint32_t expiration; char str[]; }; - -typedef struct queue -{ - struct queueitem *list; - portable_mutex_t mutex; - char name[64],initflag; -} queue_t; - struct rpcrequest_info { struct rpcrequest_info *next,*prev; @@ -270,13 +258,6 @@ void *myrealloc(uint8_t type,void *oldptr,long oldsize,long newsize); void *myaligned_alloc(uint64_t allocsize); int32_t myaligned_free(void *ptr,long size); -struct queueitem *queueitem(char *str); -void queue_enqueue(char *name,queue_t *queue,struct queueitem *origitem);//,int32_t offsetflag); -void *queue_dequeue(queue_t *queue);//,int32_t offsetflag); -void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize,int32_t freeitem); -void *queue_free(queue_t *queue); -void *queue_clone(queue_t *clone,queue_t *queue,int32_t size); -int32_t queue_size(queue_t *queue); char *mbstr(char *str,double n); void iguana_memreset(struct OS_memspace *mem); @@ -337,7 +318,6 @@ void calc_sha224(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_sha384(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_sha512(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_sha224(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); -void calc_rmd160(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_rmd128(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_rmd256(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_rmd320(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); diff --git a/src/cc/customcc.cpp b/src/cc/customcc.cpp index 8ea1ab7f..0e917f36 100644 --- a/src/cc/customcc.cpp +++ b/src/cc/customcc.cpp @@ -9,6 +9,8 @@ The above will rebuild komodod and get it running again */ +#include "komodo_bitcoind.h" + CScript custom_opret(uint8_t funcid,CPubKey pk) { diff --git a/src/cc/dapps/dappstd.c b/src/cc/dapps/dappstd.c index 38f7a75f..539673f1 100644 --- a/src/cc/dapps/dappstd.c +++ b/src/cc/dapps/dappstd.c @@ -38,7 +38,8 @@ char whoami[MAXSTR]; #define SATOSHIDEN ((uint64_t)100000000L) #define dstr(x) ((double)(x) / SATOSHIDEN) #define KOMODO_ASSETCHAIN_MAXLEN 65 -char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],IPADDRESS[100]; +char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; +char IPADDRESS[100]; #ifdef _WIN32 #ifdef _MSC_VER @@ -536,7 +537,7 @@ uint16_t _komodo_userpass(char *username, char *password, FILE *fp) return(port); } -uint16_t komodo_userpass(char *userpass,char *symbol) +uint16_t komodo_userpass(char *userpass,const char *symbol) { FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[KOMODO_ASSETCHAIN_MAXLEN]; userpass[0] = 0; @@ -549,7 +550,6 @@ uint16_t komodo_userpass(char *userpass,char *symbol) #endif } else sprintf(confname,"%s.conf",symbol); - //komodo_statefname(fname,symbol,confname); if ( (fp= fopen(confname,"rb")) != 0 ) { port = _komodo_userpass(username,password,fp); @@ -573,9 +573,7 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) { sprintf(url,(char *)"http://%s:%u",IPADDRESS,port); sprintf(postdata,"{\"method\":\"%s\",\"params\":%s}",method,params); - //printf("[%s] (%s) postdata.(%s) params.(%s) USERPASS.(%s)\n",ASSETCHAINS_SYMBOL,url,postdata,params,USERPASS); retstr2 = bitcoind_RPC(&retstr,(char *)"debug",url,userpass,method,params); - //retstr = curl_post(&cHandle,url,USERPASS,postdata,0,0,0,0); } return(retstr2); } diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 7a03215d..a1d92cfb 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -14,6 +14,7 @@ ******************************************************************************/ #include "hex.h" #include "CCdice.h" +#include "komodo_bitcoind.h" // timeout @@ -99,7 +100,6 @@ What is needed is for the dealer node to track the entropy tx that was already b #define MAX_ENTROPYUSED 8192 #define DICE_MINUTXOS 15000 -extern int32_t KOMODO_INSYNC; pthread_mutex_t DICE_MUTEX,DICEREVEALED_MUTEX; @@ -1760,7 +1760,7 @@ void *dealer0_loop(void *_arg) if ( num < DICE_MINUTXOS ) // this deadlocks, need to put it in a different thread { char *cmd = (char *)malloc(100 * 128); - sprintf(cmd,"./komodo-cli -ac_name=%s sendmany \"\" \"{\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002}\"",ASSETCHAINS_SYMBOL,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr); + sprintf(cmd,"./komodo-cli -ac_name=%s sendmany \"\" \"{\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002}\"",chainName.symbol().c_str(),coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr); n = sqrt((DICE_MINUTXOS - num) / 100)*2 + 1; LogPrintf("num normal 0.0002 utxos.%d < %d -> n.%d\n",num,DICE_MINUTXOS,n); for (i=0; i> (64-offset))) diff --git a/src/cc/eval.cpp b/src/cc/eval.cpp index 5bedc730..f0c822a7 100644 --- a/src/cc/eval.cpp +++ b/src/cc/eval.cpp @@ -26,6 +26,9 @@ #include "chain.h" #include "core_io.h" #include "crosschain.h" +#include "komodo_structs.h" +#include "komodo_notary.h" +#include "komodo_globals.h" #include "consensus/merkle.h" bool CClib_Dispatch(const CC *cond,Eval *eval,std::vector paramsNull,const CTransaction &txTo,unsigned int nIn); @@ -161,9 +164,6 @@ bool Eval::GetBlock(uint256 hash, CBlockIndex& blockIdx) const return false; } -extern int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); - - int32_t Eval::GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const { return komodo_notaries(pubkeys, height, timestamp); @@ -178,7 +178,7 @@ bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t t auth.requiredSigs = 11; auth.size = GetNotaries(auth.notaries, height, timestamp); - return CheckTxAuthority(tx, auth); + return CrossChain::CheckTxAuthority(tx, auth); } @@ -203,7 +203,7 @@ uint32_t Eval::GetAssetchainsCC() const std::string Eval::GetAssetchainsSymbol() const { - return std::string(ASSETCHAINS_SYMBOL); + return chainName.symbol(); } diff --git a/src/cc/eval.h b/src/cc/eval.h index 2534338b..9583bc67 100644 --- a/src/cc/eval.h +++ b/src/cc/eval.h @@ -51,8 +51,6 @@ EVAL(EVAL_HEIR, 0xea) \ EVAL(EVAL_CHANNELS, 0xeb) \ EVAL(EVAL_ORACLES, 0xec) \ - EVAL(EVAL_PRICES, 0xed) \ - EVAL(EVAL_PEGS, 0xee) \ EVAL(EVAL_PAYMENTS, 0xf0) \ EVAL(EVAL_GATEWAYS, 0xf1) \ EVAL(EVAL_TOKENS, 0xf2) \ @@ -152,8 +150,6 @@ class AppVM }; -extern char ASSETCHAINS_SYMBOL[65]; - /* * Data from notarisation OP_RETURN from chain being notarised @@ -219,7 +215,8 @@ class NotarisationData template bool DetectBackNotarisation(Stream& s, CSerActionUnserialize act) { - if (ASSETCHAINS_SYMBOL[0]) return 1; + if (!chainName.isKMD()) + return 1; if (s.size() >= 72) { if (strcmp("BTC", &s[68]) == 0) return 1; if (strcmp("KMD", &s[68]) == 0) return 1; diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp index 0dcdcb82..f44162e6 100644 --- a/src/cc/faucet.cpp +++ b/src/cc/faucet.cpp @@ -15,6 +15,7 @@ #include "hex.h" #include "CCfaucet.h" #include "../txmempool.h" +#include "komodo_bitcoind.h" /* This file implements a simple CC faucet as an example of how to make a new CC contract. It wont have any fancy sybil protection but will serve the purpose of a fully automated faucet. diff --git a/src/cc/fsm.cpp b/src/cc/fsm.cpp index d786b621..64e958c5 100644 --- a/src/cc/fsm.cpp +++ b/src/cc/fsm.cpp @@ -15,6 +15,7 @@ #include "CCfsm.h" #include "../txmempool.h" +#include "komodo_bitcoind.h" /* FSM CC is a highlevel CC contract that mostly uses other CC contracts. A finite state machine is defined, which combines triggers, payments and whatever other events/actions into a state machine diff --git a/src/cc/games/prices.cpp b/src/cc/games/prices.cpp index 5c8437e5..7e3e7168 100644 --- a/src/cc/games/prices.cpp +++ b/src/cc/games/prices.cpp @@ -13,12 +13,13 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ +#include "komodo_bitcoind.h" +#include "cc/gamescc.h" std::string MYCCLIBNAME = (char *)"prices"; #define PRICES_BETPERIOD 3 UniValue games_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag); -extern uint8_t ASSETCHAINS_OVERRIDE_PUBKEY33[33]; #define bstr(x) ((double)((uint32_t)x) / 10000.) diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index cc8d2ac4..9cf17ea0 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -19,6 +19,8 @@ #else #include "games/tetris.c" #endif +#include "komodo_bitcoind.h" +#include "miner.h" // for komodo_sendmessage int32_t GAMEDATA(struct games_player *P,void *ptr); @@ -165,11 +167,7 @@ int32_t games_replay2(uint8_t *newdata,uint64_t seed,gamesevent *keystrokes,int3 } #ifndef STANDALONE -#ifdef BUILD_PRICES -#include "games/prices.cpp" -#else #include "games/tetris.cpp" -#endif void GAMEJSON(UniValue &obj,struct games_player *P); @@ -279,8 +277,9 @@ uint8_t games_registeropretdecode(uint256 &gametxid,uint256 &tokenid,uint256 &pl CScript games_finishopret(uint8_t funcid,uint256 gametxid,int32_t regslot,CPubKey pk,std::vectorplayerdata,std::string pname) { - CScript opret; uint8_t evalcode = EVAL_GAMES; std::string symbol(ASSETCHAINS_SYMBOL); - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << gametxid << symbol << pname << regslot << pk << playerdata ); + CScript opret; + uint8_t evalcode = EVAL_GAMES; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << gametxid << chainName.symbol() << pname << regslot << pk << playerdata ); return(opret); } @@ -871,7 +870,7 @@ uint64_t games_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 obj.push_back(Pair("seed",(int64_t)seed)); if ( games_iamregistered(maxplayers,gametxid,tx,mygamesaddr) > 0 ) sprintf(cmd,"cc/%s %llu %s",GAMENAME,(long long)seed,gametxid.ToString().c_str()); - else sprintf(cmd,"./komodo-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",ASSETCHAINS_SYMBOL,EVAL_GAMES,gametxid.ToString().c_str()); + else sprintf(cmd,"./komodo-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",chainName.symbol().c_str(),EVAL_GAMES,gametxid.ToString().c_str()); obj.push_back(Pair("run",cmd)); } } diff --git a/src/cc/gamescc.h b/src/cc/gamescc.h index b804216d..43413532 100644 --- a/src/cc/gamescc.h +++ b/src/cc/gamescc.h @@ -68,6 +68,7 @@ UniValue games_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_bet(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue games_settle(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); +UniValue games_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag); #define CUSTOM_DISPATCH \ if ( cp->evalcode == EVAL_GAMES ) \ diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index 3bb9fc9c..8a11d882 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -15,6 +15,7 @@ #include "CCGateways.h" #include "key_io.h" +#include "komodo_bitcoind.h" /* prevent duplicate bindtxid via mempool scan diff --git a/src/cc/heir.cpp b/src/cc/heir.cpp index 21b29d9a..c6c26f01 100644 --- a/src/cc/heir.cpp +++ b/src/cc/heir.cpp @@ -15,6 +15,8 @@ #include "CCHeir.h" #include "heir_validate.h" +#include "komodo_bitcoind.h" + #include class CoinHelper; @@ -335,7 +337,7 @@ uint8_t _DecodeHeirEitherOpRet(CScript scriptPubKey, uint256 &tokenid, CPubKey& /* if (vopretExtra.size() > 1) { // restore the second opret: - /* unmarshalled in DecodeTokenOpRet: + // unmarshalled in DecodeTokenOpRet: if (!E_UNMARSHAL(vopretExtra, { ss >> vopretStripped; })) { //strip string size if (!noLogging) std::cerr << "_DecodeHeirEitherOpret() could not unmarshal vopretStripped" << std::endl; return (uint8_t)0; diff --git a/src/cc/import.cpp b/src/cc/import.cpp index 0a76a01e..58b64a70 100644 --- a/src/cc/import.cpp +++ b/src/cc/import.cpp @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ - +#include "cc/import.h" #include "cc/eval.h" #include "cc/utils.h" #include "importcoin.h" @@ -21,6 +21,10 @@ #include "cc/CCinclude.h" #include #include "cc/CCtokens.h" +#include "cc/CCImportGateway.h" +#include "komodo_bitcoind.h" +#include "komodo_gateway.h" +#include "notaries_staked.h" #include "key_io.h" #define CODA_BURN_ADDRESS "KPrrRoPfHOnNpZZQ6laHXdQDkSQDkVHaN0V+LizLlHxz7NaA59sBAAAA" @@ -33,21 +37,67 @@ ##### 0xffffffff is a special CCid for single chain/dual daemon imports */ -extern std::string ASSETCHAINS_SELFIMPORT; +/*extern std::string ASSETCHAINS_SELFIMPORT; extern uint16_t ASSETCHAINS_CODAPORT,ASSETCHAINS_BEAMPORT; extern uint8_t ASSETCHAINS_OVERRIDE_PUBKEY33[33]; extern uint256 KOMODO_EARLYTXID; // utilities from gateways.cpp uint256 BitcoinGetProofMerkleRoot(const std::vector &proofData, std::vector &txids); -uint256 GatewaysReverseScan(uint256 &txid, int32_t height, uint256 reforacletxid, uint256 batontxid); -int32_t GatewaysCointxidExists(struct CCcontract_info *cp, uint256 cointxid); uint8_t DecodeImportGatewayBindOpRet(char *burnaddr,const CScript &scriptPubKey,std::string &coin,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector &importgatewaypubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2,uint8_t &wiftype); int64_t ImportGatewayVerify(char *refburnaddr,uint256 oracletxid,int32_t claimvout,std::string refcoin,uint256 burntxid,const std::string deposithex,std::vectorproof,uint256 merkleroot,CPubKey destpub,uint8_t taddr,uint8_t prefix,uint8_t prefix2); -char *nonportable_path(char *str); -char *portable_path(char *str); -void *loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep); -void *filestr(long *allocsizep,char *_fname); +*/ +/** + * @brief For Windows, convert / to \ in paths + * + * @param str the input + * @return the modified str + */ +std::string portable_path(std::string str) +{ +#ifdef _WIN32 + for(size_t i = 0; i < str.size(); ++i) + if ( str[i] == '/' ) + str[i] = '\\'; +#endif + return str; +} + + +/** + * @brief load a file into memory + * + * @param[out] allocsizep the memory buffer size + * @param _fname the file name + * @return the pointer to the allocated buffer + */ +void *filestr(long *allocsizep, std::string fname) +{ + FILE *fp = fopen( portable_path(fname).c_str(), "rb"); + if ( fp != nullptr ) + { + fseek(fp,0,SEEK_END); + size_t filesize = ftell(fp); + if ( filesize == 0 ) + { + fclose(fp); + *allocsizep = 0; + return nullptr; + } + uint8_t *buf = (uint8_t *)malloc(filesize); + rewind(fp); + if ( buf == 0 ) + printf("Null buf ???\n"); + else + { + if ( fread(buf,1,filesize,fp) != filesize ) + printf("error reading filesize.%ld\n",(long)filesize); + } + fclose(fp); + return buf; + } + return nullptr; +} cJSON* CodaRPC(char **retstr,char const *arg0,char const *arg1,char const *arg2,char const *arg3,char const *arg4,char const *arg5) { @@ -69,182 +119,82 @@ cJSON* CodaRPC(char **retstr,char const *arg0,char const *arg1,char const *arg2, return(retjson); } -// makes source tx for self import tx -CMutableTransaction MakeSelfImportSourceTx(CTxDestination &dest, int64_t amount) -{ - const int64_t txfee = 10000; - int64_t inputs, change; - CPubKey myPubKey = Mypubkey(); - struct CCcontract_info *cpDummy, C; - - cpDummy = CCinit(&C, EVAL_TOKENS); // this is just for FinalizeCCTx to work - - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - - if (AddNormalinputs(mtx, myPubKey, 2 * txfee, 4) == 0) { - LOGSTREAM("importcoin", CCLOG_INFO, stream << "MakeSelfImportSourceTx() warning: cannot find normal inputs for txfee" << std::endl); - } - - CScript scriptPubKey = GetScriptForDestination(dest); - mtx.vout.push_back(CTxOut(txfee, scriptPubKey)); - - //make opret with 'burned' amount: - FinalizeCCTx(0, cpDummy, mtx, myPubKey, txfee, CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_IMPORTCOIN << (uint8_t)'A' << amount)); - return mtx; -} - -// make sure vin is signed by pubkey33 -bool CheckVinPubKey(const CTransaction &sourcetx, int32_t i, uint8_t pubkey33[33]) -{ - CTransaction vintx; - uint256 blockHash; - char destaddr[64], pkaddr[64]; - - if (i < 0 || i >= sourcetx.vin.size()) - return false; - - if( !myGetTransaction(sourcetx.vin[i].prevout.hash, vintx, blockHash) ) { - LOGSTREAM("importcoin", CCLOG_INFO, stream << "CheckVinPubKey() could not load vintx" << sourcetx.vin[i].prevout.hash.GetHex() << std::endl); - return false; - } - if( sourcetx.vin[i].prevout.n < vintx.vout.size() && Getscriptaddress(destaddr, vintx.vout[sourcetx.vin[i].prevout.n].scriptPubKey) != 0 ) - { - pubkey2addr(pkaddr, pubkey33); - if (strcmp(pkaddr, destaddr) == 0) { - return true; - } - LOGSTREAM("importcoin", CCLOG_INFO, stream << "CheckVinPubKey() mismatched vin[" << i << "].prevout.n=" << sourcetx.vin[i].prevout.n << " -> destaddr=" << destaddr << " vs pkaddr=" << pkaddr << std::endl); - } - return false; -} - -// ac_import=PUBKEY support: -// prepare a tx for creating import tx and quasi-burn tx -int32_t GetSelfimportProof(const CMutableTransaction sourceMtx, CMutableTransaction &templateMtx, ImportProof &proofNull) // find burnTx with hash from "other" daemon -{ - MerkleBranch newBranch; - CMutableTransaction tmpmtx; - //CTransaction sourcetx; - - tmpmtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - - /* - if (!E_UNMARSHAL(ParseHex(rawsourcetx), ss >> sourcetx)) { - LOGSTREAM("importcoin", CCLOG_INFO, stream << "GetSelfimportProof: could not unmarshal source tx" << std::endl); - return(-1); - } - - if (sourcetx.vout.size() == 0) { - LOGSTREAM("importcoin", CCLOG_INFO, stream << "GetSelfimportProof: vout size is 0" << std::endl); - return -1; - } */ - - /*if (ivout < 0) { // "ivout < 0" means "find" - // try to find vout - CPubKey myPubkey = Mypubkey(); - ivout = 0; - // skip change: - if (sourcetx.vout[ivout].scriptPubKey == (CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG)) - ivout++; - } - - if (ivout >= sourcetx.vout.size()) { - LOGSTREAM("importcoin", CCLOG_INFO, stream << "GetSelfimportProof: needed vout not found" << std::endl); - return -1; - } */ - - int32_t ivout = 0; - - // LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "GetSelfimportProof: using vout[" << ivout << "] of the passed rawtx" << std::endl); - - CScript scriptPubKey = sourceMtx.vout[ivout].scriptPubKey; - - //mtx is template for import tx - templateMtx = sourceMtx; - templateMtx.fOverwintered = tmpmtx.fOverwintered; - - //malleability fix for burn tx: - //mtx.nExpiryHeight = tmpmtx.nExpiryHeight; - templateMtx.nExpiryHeight = sourceMtx.nExpiryHeight; - - templateMtx.nVersionGroupId = tmpmtx.nVersionGroupId; - templateMtx.nVersion = tmpmtx.nVersion; - templateMtx.vout.clear(); - templateMtx.vout.resize(1); - - uint8_t evalCode, funcId; - int64_t burnAmount; - vscript_t vopret; - if( !GetOpReturnData(sourceMtx.vout.back().scriptPubKey, vopret) || - !E_UNMARSHAL(vopret, ss >> evalCode; ss >> funcId; ss >> burnAmount)) { - LOGSTREAM("importcoin", CCLOG_INFO, stream << "GetSelfimportProof() could not unmarshal source tx opret" << std::endl); - return -1; - } - templateMtx.vout[0].nValue = burnAmount; - templateMtx.vout[0].scriptPubKey = scriptPubKey; - - // not sure we need this now as we create sourcetx ourselves: - /*if (sourcetx.GetHash() != sourcetxid) { - LOGSTREAM("importcoin", CCLOG_INFO, stream << "GetSelfimportProof: passed source txid incorrect" << std::endl); - return(-1); - }*/ - - // check ac_pubkey: - if (!CheckVinPubKey(sourceMtx, 0, ASSETCHAINS_OVERRIDE_PUBKEY33)) { - return -1; - } - proofNull = ImportProof(std::make_pair(sourceMtx.GetHash(), newBranch)); - return 0; -} - -// make import tx with burntx and dual daemon -std::string MakeCodaImportTx(uint64_t txfee, std::string receipt, std::string srcaddr, std::vector vouts) +/**** + * @brief make import tx with burntx and dual daemon + * @param txfee fee + * @param receipt + * @param srcaddr source address + * @param vouts collection of vouts + * @returns the hex string of the import transaction + */ +std::string MakeCodaImportTx(uint64_t txfee, const std::string& receipt, const std::string& srcaddr, + const std::vector& vouts) { - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()),burntx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - CPubKey mypk; uint256 codaburntxid; std::vector dummyproof; - int32_t i,numvouts,n,m; std::string coin,error; struct CCcontract_info *cp, C; - cJSON *result,*tmp,*tmp1; unsigned char hash[SHA256_DIGEST_LENGTH+1]; - char out[SHA256_DIGEST_LENGTH*2+1],*retstr,*destaddr,*receiver; TxProof txProof; uint64_t amount; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction( + Params().GetConsensus(), komodo_nextheight()); + CMutableTransaction burntx = CreateNewContextualCMutableTransaction( + Params().GetConsensus(), komodo_nextheight()); + CCcontract_info *cp; + CCcontract_info C; cp = CCinit(&C, EVAL_GATEWAYS); + if (txfee == 0) txfee = 10000; - mypk = pubkey2pk(Mypubkey()); + CPubKey mypk = pubkey2pk(Mypubkey()); + SHA256_CTX sha256; SHA256_Init(&sha256); SHA256_Update(&sha256, receipt.c_str(), receipt.size()); + unsigned char hash[SHA256_DIGEST_LENGTH+1]; SHA256_Final(hash, &sha256); - for(i = 0; i < SHA256_DIGEST_LENGTH; i++) + char out[SHA256_DIGEST_LENGTH*2+1]; + for(int32_t i = 0; i < SHA256_DIGEST_LENGTH; i++) { sprintf(out + (i * 2), "%02x", hash[i]); } - out[65]='\0'; + out[SHA256_DIGEST_LENGTH*2]='\0'; LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "MakeCodaImportTx: hash=" << out << std::endl); + uint256 codaburntxid; codaburntxid.SetHex(out); - LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "MakeCodaImportTx: receipt=" << receipt << " codaburntxid=" << codaburntxid.GetHex().data() << " amount=" << (double)amount / COIN << std::endl); - result=CodaRPC(&retstr,"prove-payment","-address",srcaddr.c_str(),"-receipt-chain-hash",receipt.c_str(),""); - if (result==0) + LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "MakeCodaImportTx: receipt=" + << receipt << " codaburntxid=" << codaburntxid.GetHex().data() + << std::endl); + + char *retstr; + cJSON *result = CodaRPC(&retstr,"prove-payment","-address",srcaddr.c_str(), + "-receipt-chain-hash",receipt.c_str(),""); + if (result == nullptr) { - if (retstr!=0) + if (retstr != nullptr) { - CCerror=std::string("CodaRPC: ")+retstr; + CCerror = std::string("CodaRPC: ") + retstr; free(retstr); } - return(""); + return ""; } else { - if ((tmp=jobj(jitem(jarray(&n,result,(char *)"payments"),0),(char *)"payload"))!=0 && (destaddr=jstr(jobj(tmp,(char *)"common"),(char *)"memo"))!=0 && - (receiver=jstr(jitem(jarray(&m,tmp,(char *)"body"),1),(char *)"receiver"))!=0 && (amount=j64bits(jitem(jarray(&m,tmp,(char *)"body"),1),(char *)"amount"))!=0) + int32_t n; + int32_t m; + cJSON *tmp = jobj(jitem(jarray(&n,result,(char *)"payments"),0),(char *)"payload"); + char *destaddr; + char *receiver; + uint64_t amount; + if ( tmp != nullptr + && (destaddr=jstr(jobj(tmp,(char *)"common"),(char *)"memo")) != nullptr + && (receiver=jstr(jitem(jarray(&m,tmp,(char *)"body"),1),(char *)"receiver")) != nullptr + && (amount=j64bits(jitem(jarray(&m,tmp,(char *)"body"),1),(char *)"amount")) != 0 ) { - LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "MakeCodaImportTx: receiver=" << receiver << " destaddr=" << destaddr << " amount=" << amount << std::endl); + LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "MakeCodaImportTx: receiver=" + << receiver << " destaddr=" << destaddr << " amount=" << amount << std::endl); if (strcmp(receiver,CODA_BURN_ADDRESS)!=0) { CCerror="MakeCodaImportTx: invalid burn address, coins do not go to predefined burn address - "; CCerror+=CODA_BURN_ADDRESS; LOGSTREAM("importcoin", CCLOG_INFO, stream << CCerror << std::endl); free(result); - return(""); + return ""; } CTxDestination dest = DecodeDestination(destaddr); CScript scriptPubKey = GetScriptForDestination(dest); @@ -253,17 +203,20 @@ std::string MakeCodaImportTx(uint64_t txfee, std::string receipt, std::string sr CCerror="MakeCodaImportTx: invalid destination address, burnTx memo!=importTx destination"; LOGSTREAM("importcoin", CCLOG_INFO, stream << CCerror << std::endl); free(result); - return(""); + return ""; } if (amount*COIN!=vouts[0].nValue) { CCerror="MakeCodaImportTx: invalid amount, burnTx amount!=importTx amount"; LOGSTREAM("importcoin", CCLOG_INFO, stream << CCerror << std::endl); free(result); - return(""); + return ""; } burntx.vin.push_back(CTxIn(codaburntxid,0,CScript())); + std::vector dummyproof; burntx.vout.push_back(MakeBurnOutput(amount*COIN,0xffffffff,"CODA",vouts,dummyproof,srcaddr,receipt)); + + TxProof txProof; return HexStr(E_MARSHAL(ss << MakeImportCoinTransaction(txProof,burntx,vouts))); } else @@ -271,7 +224,7 @@ std::string MakeCodaImportTx(uint64_t txfee, std::string receipt, std::string sr CCerror="MakeCodaImportTx: invalid Coda burn tx"; LOGSTREAM("importcoin", CCLOG_INFO, stream << CCerror << std::endl); free(result); - return(""); + return ""; } } @@ -291,8 +244,10 @@ int32_t CheckBEAMimport(TxProof proof,std::vector rawproof,CTransaction int32_t CheckCODAimport(CTransaction importTx,CTransaction burnTx,std::vector payouts,std::string srcaddr,std::string receipt) { - cJSON *result,*tmp,*tmp1; char *retstr,out[SHA256_DIGEST_LENGTH*2+1]; unsigned char hash[SHA256_DIGEST_LENGTH+1]; int i,n,m; - SHA256_CTX sha256; uint256 codaburntxid; char *destaddr,*receiver; uint64_t amount; + cJSON *result,*tmp,*tmp1; char *retstr,out[SHA256_DIGEST_LENGTH*2+1]; int i,n,m; + uint256 codaburntxid; char *destaddr,*receiver; uint64_t amount; + unsigned char hash[SHA256_DIGEST_LENGTH+1]; + SHA256_CTX sha256; // check with dual-CODA daemon via ASSETCHAINS_CODAPORT for validity of burnTx SHA256_Init(&sha256); @@ -322,7 +277,7 @@ int32_t CheckCODAimport(CTransaction importTx,CTransaction burnTx,std::vectorInvalid("no-tokens-migrate-on-LABS"); struct CCcontract_info *cpTokens, CCtokens_info; std::vector> oprets; @@ -620,11 +575,9 @@ bool CheckMigration(Eval *eval, const CTransaction &importTx, const CTransaction return eval->Invalid("import-tx-token-params-incorrect"); } - // Check burntx shows correct outputs hash -// if (payoutsHash != SerializeHash(payouts)) // done in ImportCoin -// return eval->Invalid("wrong-payouts"); - + // if (payoutsHash != SerializeHash(payouts)) // done in ImportCoin + // return eval->Invalid("wrong-payouts"); TxProof merkleBranchProof; std::vector notaryTxids; @@ -633,13 +586,13 @@ bool CheckMigration(Eval *eval, const CTransaction &importTx, const CTransaction if (proof.IsMerkleBranch(merkleBranchProof)) { uint256 target = merkleBranchProof.second.Exec(burnTx.GetHash()); LOGSTREAM("importcoin", CCLOG_DEBUG2, stream << "Eval::ImportCoin() momom target=" << target.GetHex() << " merkleBranchProof.first=" << merkleBranchProof.first.GetHex() << std::endl); - if (!CheckMoMoM(merkleBranchProof.first, target)) { + if (!CrossChain::CheckMoMoM(merkleBranchProof.first, target)) { LOGSTREAM("importcoin", CCLOG_INFO, stream << "MoMoM check failed for importtx=" << importTx.GetHash().GetHex() << std::endl); return eval->Invalid("momom-check-fail"); } } else if (proof.IsNotaryTxids(notaryTxids)) { - if (!CheckNotariesApproval(burnTx.GetHash(), notaryTxids)) { + if (!CrossChain::CheckNotariesApproval(burnTx.GetHash(), notaryTxids)) { return eval->Invalid("notaries-approval-check-fail"); } } @@ -671,7 +624,7 @@ bool Eval::ImportCoin(const std::vector params, const CTransaction &imp LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "Validating import tx..., txid=" << importTx.GetHash().GetHex() << std::endl); - if (strcmp(ASSETCHAINS_SYMBOL, "CFEKDIMXY6") == 0 && chainActive.Height() <= 44693) + if ( chainName.isSymbol("CFEKDIMXY6") && chainActive.Height() <= 44693) return true; if (importTx.vout.size() < 2) @@ -708,7 +661,9 @@ bool Eval::ImportCoin(const std::vector params, const CTransaction &imp return Invalid("wrong-payouts"); if (targetCcid < KOMODO_FIRSTFUNGIBLEID) return Invalid("chain-not-fungible"); - + if (targetSymbol.empty()) + return Invalid("target-chain-not-specified"); + if ( targetCcid != 0xffffffff ) { @@ -767,4 +722,115 @@ bool Eval::ImportCoin(const std::vector params, const CTransaction &imp return Valid(); } +/***** + * @brief makes source tx for self import tx + * @param dest the tx destination + * @param amount the amount + * @returns a transaction based on the inputs + */ +CMutableTransaction MakeSelfImportSourceTx(const CTxDestination &dest, int64_t amount) +{ + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + + const int64_t txfee = 10000; + CPubKey myPubKey = Mypubkey(); + if (AddNormalinputs(mtx, myPubKey, 2 * txfee, 4) == 0) { + LOGSTREAM("importcoin", CCLOG_INFO, stream + << "MakeSelfImportSourceTx() warning: cannot find normal inputs for txfee" << std::endl); + } + + CScript scriptPubKey = GetScriptForDestination(dest); + mtx.vout.push_back(CTxOut(txfee, scriptPubKey)); + + //make opret with 'burned' amount: + CCcontract_info *cpDummy; + CCcontract_info C; + cpDummy = CCinit(&C, EVAL_TOKENS); // this is just for FinalizeCCTx to work + FinalizeCCTx(0, cpDummy, mtx, myPubKey, txfee, CScript() + << OP_RETURN + << E_MARSHAL(ss << (uint8_t)EVAL_IMPORTCOIN << (uint8_t)'A' << amount)); + return mtx; +} + +/****** + * @brief make sure vin is signed by a particular key + * @param sourcetx the source transaction + * @param i the index of the input to check + * @param pubkey33 the key + * @returns true if the vin of i was signed by the given key + */ +bool CheckVinPubKey(const CTransaction &sourcetx, int32_t i, uint8_t pubkey33[33]) +{ + CTransaction vintx; + uint256 blockHash; + char destaddr[64], pkaddr[64]; + + if (i < 0 || i >= sourcetx.vin.size()) + return false; + + if( !myGetTransaction(sourcetx.vin[i].prevout.hash, vintx, blockHash) ) { + LOGSTREAM("importcoin", CCLOG_INFO, stream << "CheckVinPubKey() could not load vintx" << sourcetx.vin[i].prevout.hash.GetHex() << std::endl); + return false; + } + if( sourcetx.vin[i].prevout.n < vintx.vout.size() && Getscriptaddress(destaddr, vintx.vout[sourcetx.vin[i].prevout.n].scriptPubKey) != 0 ) + { + pubkey2addr(pkaddr, pubkey33); + if (strcmp(pkaddr, destaddr) == 0) { + return true; + } + LOGSTREAM("importcoin", CCLOG_INFO, stream << "CheckVinPubKey() mismatched vin[" << i << "].prevout.n=" << sourcetx.vin[i].prevout.n << " -> destaddr=" << destaddr << " vs pkaddr=" << pkaddr << std::endl); + } + return false; +} + +/***** + * @brief generate a self import proof + * @note this prepares a tx for creating an import tx and quasi-burn tx + * @note find burnTx with hash from "other" daemon + * @param[in] sourceMtx the original transaction + * @param[out] templateMtx the resultant transaction + * @param[out] proofNull the import proof + * @returns true on success + */ +bool GetSelfimportProof(const CMutableTransaction sourceMtx, CMutableTransaction &templateMtx, + ImportProof &proofNull) +{ + + CMutableTransaction tmpmtx = CreateNewContextualCMutableTransaction( + Params().GetConsensus(), komodo_nextheight()); + + CScript scriptPubKey = sourceMtx.vout[0].scriptPubKey; + + //mtx is template for import tx + templateMtx = sourceMtx; + templateMtx.fOverwintered = tmpmtx.fOverwintered; + + //malleability fix for burn tx: + //mtx.nExpiryHeight = tmpmtx.nExpiryHeight; + templateMtx.nExpiryHeight = sourceMtx.nExpiryHeight; + templateMtx.nVersionGroupId = tmpmtx.nVersionGroupId; + templateMtx.nVersion = tmpmtx.nVersion; + templateMtx.vout.clear(); + templateMtx.vout.resize(1); + + uint8_t evalCode, funcId; + int64_t burnAmount; + vscript_t vopret; + if( !GetOpReturnData(sourceMtx.vout.back().scriptPubKey, vopret) || + !E_UNMARSHAL(vopret, ss >> evalCode; ss >> funcId; ss >> burnAmount)) { + LOGSTREAM("importcoin", CCLOG_INFO, stream << "GetSelfimportProof() could not unmarshal source tx opret" << std::endl); + return false; + } + templateMtx.vout[0].nValue = burnAmount; + templateMtx.vout[0].scriptPubKey = scriptPubKey; + + // check ac_pubkey: + if (!CheckVinPubKey(sourceMtx, 0, ASSETCHAINS_OVERRIDE_PUBKEY33)) { + return false; + } + + MerkleBranch newBranch; + proofNull = ImportProof(std::make_pair(sourceMtx.GetHash(), newBranch)); + return true; +} diff --git a/src/cc/import.h b/src/cc/import.h new file mode 100644 index 00000000..29ed9de5 --- /dev/null +++ b/src/cc/import.h @@ -0,0 +1,59 @@ +#pragma once +/****************************************************************************** + * Copyright © 2021 Komodo Core developers * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "primitives/transaction.h" // CTransaction +#include "script/standard.h" // CTxDestination +#include "importcoin.h" // ImportProof +#include + +/**** + * @brief make import tx with burntx and dual daemon + * @param txfee fee + * @param receipt + * @param srcaddr source address + * @param vouts collection of vouts + * @returns the hex string of the import transaction + */ +std::string MakeCodaImportTx(uint64_t txfee, const std::string& receipt, + const std::string& srcaddr, const std::vector& vouts); + +/****** + * @brief make sure vin is signed by a particular key + * @param sourcetx the source transaction + * @param i the index of the input to check + * @param pubkey33 the key + * @returns true if the vin of i was signed by the given key + */ +bool CheckVinPubKey(const CTransaction &sourcetx, int32_t i, uint8_t pubkey33[33]); + +/***** + * @brief makes source tx for self import tx + * @param dest the tx destination + * @param amount the amount + * @returns a transaction based on the inputs + */ +CMutableTransaction MakeSelfImportSourceTx(const CTxDestination &dest, int64_t amount); + +/***** + * @brief generate a self import proof + * @note this prepares a tx for creating an import tx and quasi-burn tx + * @note find burnTx with hash from "other" daemon + * @param[in] sourceMtx the original transaction + * @param[out] templateMtx the resultant transaction + * @param[out] proofNull the import proof + * @returns true on success + */ +bool GetSelfimportProof(const CMutableTransaction sourceMtx, CMutableTransaction &templateMtx, ImportProof &proofNull); diff --git a/src/cc/importgateway.cpp b/src/cc/importgateway.cpp index 7e4b6195..f7d134e3 100644 --- a/src/cc/importgateway.cpp +++ b/src/cc/importgateway.cpp @@ -16,6 +16,7 @@ #include "CCImportGateway.h" #include "key_io.h" #include "../importcoin.h" +#include "komodo_bitcoind.h" // start of consensus code @@ -25,8 +26,6 @@ #define KMD_TADDR 0 #define CC_MARKER_VALUE 10000 -extern uint256 KOMODO_EARLYTXID; - CScript EncodeImportGatewayBindOpRet(uint8_t funcid,std::string coin,uint256 oracletxid,uint8_t M,uint8_t N,std::vector importgatewaypubkeys,uint8_t taddr,uint8_t prefix,uint8_t prefix2,uint8_t wiftype) { CScript opret; uint8_t evalcode = EVAL_IMPORTGATEWAY; diff --git a/src/cc/includes/cJSON.h b/src/cc/includes/cJSON.h index d919a47a..a9588025 100644 --- a/src/cc/includes/cJSON.h +++ b/src/cc/includes/cJSON.h @@ -48,8 +48,11 @@ #include "../crypto777/OS_portable.h" -#define SATOSHIDEN ((uint64_t)100000000L) -#define dstr(x) ((double)(x) / SATOSHIDEN) + +// todo remove +//#define SATOSHIDEN ((uint64_t)100000000L) +//#define dstr(x) ((double)(x) / SATOSHIDEN) + #define MAX_JSON_FIELD 4096 // on the big side #ifdef __cplusplus diff --git a/src/cc/lotto.cpp b/src/cc/lotto.cpp index 7427fe9b..5b100529 100644 --- a/src/cc/lotto.cpp +++ b/src/cc/lotto.cpp @@ -15,6 +15,7 @@ #include "CClotto.h" #include "../txmempool.h" +#include "komodo_bitcoind.h" /* A blockchain lotto has the problem of generating the deterministic random numbers needed to get a winner in a way that doesnt allow cheating. If we save the entropy for later publishing and display the hash of the entropy, it is true that the players wont know what the entropy value is, however the creator of the lotto funds will be able to know and simply create a winning ticket when the jackpot is large enough. diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index e117da23..ee667b1c 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -185,6 +185,7 @@ a10001ffffffff0200e1f5050000000023210255c46dbce584e3751081b39d7fc054fc807100557e #include "../secp256k1/include/secp256k1.h" #include "../secp256k1/src/ecmult.h" #include "../secp256k1/src/ecmult_gen.h" +#include "komodo_bitcoind.h" typedef struct { unsigned char data[64]; } secp256k1_schnorrsig; struct secp256k1_context_struct { diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp index 42dc88a9..1db6e531 100644 --- a/src/cc/oracles.cpp +++ b/src/cc/oracles.cpp @@ -14,6 +14,9 @@ ******************************************************************************/ #include "CCOracles.h" +#include "komodo.h" +#include "komodo_bitcoind.h" + #include /* @@ -639,12 +642,6 @@ bool OraclesDataValidate(struct CCcontract_info *cp,Eval* eval,const CTransactio else return(true); } -/*nt32_t GetLatestTimestamp(int32_t height) -{ - if ( KOMODO_NSPV_SUPERLITE ) return (NSPV_blocktime(height)); - return(komodo_heightstamp(height)); -} */ - bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) { uint256 oracletxid,batontxid,txid; uint64_t txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts; int64_t amount; uint256 hashblock; diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 8dbc5df8..e874c879 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -14,6 +14,8 @@ ******************************************************************************/ #include "hex.h" #include "CCPayments.h" +#include "komodo_bitcoind.h" +#include /* 0) txidopret <- allocation, scriptPubKey, opret @@ -350,9 +352,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & Paymentspk = GetUnspendable(cp,0); txidpk = CCtxidaddr(txidaddr,createtxid); GetCCaddress1of2(cp,txidaddr,Paymentspk,txidpk); - //LogPrintf( "lockedblocks.%i minrelease.%i totalallocations.%i txidopret1.%s txidopret2.%s\n",lockedblocks, minrelease, totalallocations, txidoprets[0].ToString().c_str(), txidoprets[1].ToString().c_str() ); - if ( !CheckTxFee(tx, PAYMENTS_TXFEE+1, chainActive.Tip()->nHeight, - chainActive.Tip()->nTime, actualtxfee) ) + if ( !CheckTxFee(tx, PAYMENTS_TXFEE+1, chainActive.Tip()->nHeight, chainActive.Tip()->nTime, actualtxfee) ) return eval->Invalid("txfee is too high"); // Check that the change vout is playing the txid address. if ( IsPaymentsvout(cp,tx,0,txidaddr,ccopret) == 0 ) diff --git a/src/cc/pegs.cpp b/src/cc/pegs.cpp deleted file mode 100644 index 4e6b4dd1..00000000 --- a/src/cc/pegs.cpp +++ /dev/null @@ -1,1284 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "CCPegs.h" -#include "../importcoin.h" -#include "key_io.h" -#include - - -/* -pegs CC is able to create a coin backed (by any supported coin with gateways CC deposits) and pegged to any synthetic price that is able to be calculated based on prices CC - - First, the prices CC needs to be understood, so the extensive comments at the top of ~/src/cc/prices.cpp needs to be understood. - - The second aspect is the ability to import coins, as used by the crosschain burn/import and the -ac_import chains. - - - - OK, now we are ready to describe the pegs CC. Let us imagine an -ac_import sidechain with KMD gateways CC. Now we have each native coin fungible with the real KMD via the gateways deposit/withdraw mechanism. Let us start with that and make a pegged and backed USD chain. - - - - Here the native coin is KMD, but we want USD, so there needs to be a way to convert the KMD amounts into USD amounts. Something like "KMDBTC, BTCUSD, *, 1" which is the prices CC syntax to calculate KMD/USD, which is exactly what we need. So now we can assume that we have a block by block usable KMD/USD price. implementationwise, there can be an -ac option like -ac_peg="KMDBTC, BTCUSD, *, 1" and in conjunction with -ac_import=KMD gateways CC sidechain, we now have a chain where deposit of KMD issues the correct USD coins and redeem of USD coins releases the correct number of KMD coins. - - Are we done yet? - - Not quite, as the prices of KMD will be quite volatile relative to USD, which is good during bull markets, not so happy during bear markets. There are 2 halves to this problem, how to deal with massive price increase (easy to solve), how to solve 90% price drop (a lot harder). - - In order to solve both, what is needed is an "account" based tracking which updates based on both price change, coins issued, payments made. So let us create an account that is based on a specific pubkey, where all relevant deposits, issuances, withdraws are tracked via appropriate vin/vout markers. - - Let us modify the USD chain above so that only 80% of the possible USD is issued and 20% held in reserve. This 80% should be at least some easily changeable #define, or even an -ac parameter. We want the issued coins to be released without any encumberances, but the residual 20% value is still controlled (owned) but the depositor. This account has the amount of KMD deposited and USD issued. At the moment of deposit, there will still be 20% equity left. Let us start with 1000 KMD deposit, $1.5 per KMD -> 800 KMD converted to 1200 USD into depositor pubkey and the account of (1000 KMD, -1200 USD) = 200 KMD or $300 equity. - - Now it becomes easy for the bull market case, which is to allow (for a fee like 1%) issuance of more USD as the equity increases, so let us imagine KMD at $10: - - (1000 KMD, -1200 USD, 200KMD reserve) -> $2000 equity, issue 80% -> $1600 using 160 KMD - (1000 KMD, -1200 USD, 200KMD reserve, -160KMD, issue $1600 USD, 40 KMD reserve) - - we have $2800 USD in circulation, 40 KMD reserve left against $10000 marketcap of the original deposit. It it easy to see that there are never any problems with lack of KMD to redeem the issued USD in a world where prices only go up. Total USD issuance can be limited by using a decentralized account tracking based on each deposit. - - What is evident though is that with the constantly changing price and the various times that all the various deposits issue USD, the global reserves are something that will be hard to predict and in fact needs to be specifically tracked. Let us combine all accounts exposure in to a global reserves factor. This factor will control various max/min/ allowed and fee percentages. - - Now we are prepared to handle the price goes down scenario. We can rely on the global equity/reserve ratio to be changing relatively slowly as the reference price is the smooted trustless oracles price. This means there will be enough blocks to adjust the global reserves percentage. What we need to do is liquidate specific positions that have the least reserves. - - What does liquidation mean? It means a specific account will be purchased at below its current value and the KMD withdrawn. Let us assume the price drops to $5: - - (1000 KMD, -1200 USD, 200KMD reserve, -160KMD, issue $1600 USD, 40 KMD reserve) 1000 KMD with 2800 USD issued so $2200 reserves. Let us assume it can be liquidated at a 10% discount, so for $2000 in addition to the $2800, the 5000 KMD is able to be withdrawn. This removes 4800 USD coins for 1000 KMD, which is a very low reserve amount of 4%. If a low reserve amount is removed from the system, then the global reserve amount must be improved. - - In addition to the global reserves calculation, there needs to be a trigger percentage that enables positions to be liquidated. We also want to liquidate the worst positions, so in addition to the trigger percentage, there should be a liquidation threshold, and the liquidator would need to find 3 or more better positions that are beyond the liquidation threshold, to be able to liquidate. This will get us to at most 3 accounts that could be liquidated but are not able to, so some method to allow those to also be liquidated. The liquidating nodes are making instant profits, so they should be expected to do whatever blockchain scanning and proving to make things easy for the rest of the nodes. - - One last issue is the normal redemption case where we are not liquidating. In this case, it should be done at the current marketprice, should improve the global reserves metrics and not cause anybody whose position was modified to have cause for complaint. Ideally, there would be an account that has the identical to the global reserve percentage and also at the same price as current marketprice, but this is not realistic, so we need to identify classes of accounts and consider which ones can be fully or partially liquidated to satisfy the constraints. - - looking at our example account: - (1000 KMD, -1200 USD, 200KMD reserve, -160KMD, issue $1600 USD, 40 KMD reserve) - - what sort of non-liquidation withdraw would be acceptable? if the base amount 1000 KMD is reduced along with USD owed, then the reserve status will go up for the account. but that would seem to allow extra USD to be able to be issued. there should be no disadvantage from funding a withdraw, but also not any large advantage. it needs to be a neutral event.... - - One solution is to allow for the chance for any account to be liquidated, but the equity compensated for with a premium based on the account reserves. So in the above case, a premium of 5% on the 40KMD reserve is paid to liquidate its account. Instead of 5% premium, a lower 1% can be done if based on the MAX(correlated[daywindow],smoothed) so we get something that is close to the current marketprice. To prevent people taking advantage of the slowness of the smoothed price to adjust, there would need to be a one day delay in the withdraw. - - From a practical sense, it seems a day is a long time, so maybe having a way to pay a premium like 10%, or wait a day to get the MAX(correlated[daywindow],smoothed) price. This price "jumping" might also be taken advantage of in the deposit side, so similar to prices CC it seems good to have the MAX(correlated[daywindow],smoothed) method. - - Now, we have a decentralized mechanism to handle the price going lower! Combined with the fully decentralized method new USD coins are issued, makes this argubably the first decentralized blockchain that is both backed and pegged. There is the reliance on the gateways CC multisig signers, so there is a fundamental federated trust for chains without intrinsic value. - - Also, notice that the flexibly syntax of prices CC allows to define pegs easily for virtually any type of synthetic, and all the ECB fiats can easily get a backed and pegged coin. - - Let us now consider how to enforce a peg onto a specific gateways CC token. If this can also be achieved, then a full DEX for all the different gateways CC supported coins can be created onto a single fiat denominated chain. - - I think just having a pegscreate rpc call that binds an existing gateways create to a price CC syntax price will be almost enough to support this. Let us assume a USD stablechain and we have a BTC token, then pegscreate "BTCUSD, 1" - that will specify using the BTCUSD price, so now we need to create a based way to do tokenbid/tokenask. For a based price, the smoothed price is substituted. - - There is the issue of the one day delay, so it might make sense to allow specific bid/ask to be based on some simple combinations of the three possible prices. it might even be possible to go a bit overboard and make a forth like syntax to define the dynamic price for a bid, which maybe at times wont be valid, like it is only valid if the three prices are within 1% of each other. But all that seems over complex and for initial release it can just use the mined, correlated or smoothed price, with some specified percentage offset - - Implementation notes: - make sure that fees and markers that can be sent to an unspendable address are sent to: RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P, this is the address for BOTS - - - */ - -// start of consensus code -#ifndef PEGS_THRESHOLDS -#define PEGS_THRESHOLDS -#define PEGS_ACCOUNT_MAX_DEBT 80 -#define PEGS_GLOBAL_RED_ZONE 60 -#define PEGS_ACCOUNT_YELLOW_ZONE 60 -#define PEGS_ACCOUNT_RED_ZONE 90 -#endif // PEGS_THRESHOLDS -#define CC_MARKER_VALUE 10000 - -extern uint64_t ASSETCHAINS_PEGSCCPARAMS[3]; - -extern uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,uint256 &tokenid,std::string &coin,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector &gatewaypubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2,uint8_t &wiftype); -extern int64_t GetTokenBalance(CPubKey pk, uint256 tokenid); -extern int32_t komodo_currentheight(); -extern int32_t prices_syntheticvec(std::vector &vec, std::vector synthetic); -extern int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t minmax, int16_t leverage); - -CScript EncodePegsCreateOpRet(std::vector bindtxids) -{ - CScript opret; uint8_t evalcode = EVAL_PEGS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'C' << bindtxids); - return(opret); -} - -uint8_t DecodePegsCreateOpRet(const CScript &scriptPubKey,std::vector &bindtxids) -{ - std::vector vopret; uint8_t *script,e,f; - - GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && script[0] == EVAL_PEGS && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> bindtxids) != 0 ) - { - return(f); - } - return(0); -} - -CScript EncodePegsFundOpRet(uint256 tokenid,uint256 pegstxid,CPubKey srcpub,int64_t amount,std::pair account) -{ - CScript opret; uint8_t evalcode=EVAL_PEGS,funcid='F'; struct CCcontract_info *cp,C; CPubKey pegspk; - std::vector pubkeys; vscript_t vopret; - - cp = CCinit(&C,EVAL_PEGS); - pegspk = GetUnspendable(cp,0); - pubkeys.push_back(srcpub); - pubkeys.push_back(pegspk); - LOGSTREAM("pegscc", CCLOG_DEBUG1, stream << "EncodePegsFundOpRet [" << account.first << "," << account.second << "]" << std::endl); - vopret = E_MARSHAL(ss << evalcode << funcid << pegstxid << srcpub << amount << account); - return(EncodeTokenOpRet(tokenid,pubkeys,make_pair(OPRETID_PEGSDATA, vopret))); -} - -uint8_t DecodePegsFundOpRet(const CScript &scriptPubKey,uint256 &tokenid,uint256 &pegstxid,CPubKey &srcpub,int64_t &amount,std::pair &account) -{ - std::vector> oprets; - std::vector vopret,vOpretExtra; uint8_t *script,e,f,tokenevalcode; std::vector pubkeys; - - if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys, oprets)!=0 && GetOpretBlob(oprets, OPRETID_PEGSDATA, vOpretExtra) && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0) - { - vopret=vOpretExtra; - } - else GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && script[0] == EVAL_PEGS && E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> pegstxid; ss >> srcpub; ss >> amount; ss >> account) != 0 ) - { - return(f); - } - return(0); -} - -uint8_t DecodePegsGetOpRet(const CTransaction tx,uint256& pegstxid,uint256 &tokenid,CPubKey &srcpub,int64_t &amount,std::pair &account) -{ - std::vector vopret; uint8_t *script; - ImportProof proof; CTransaction burntx; std::vector payouts; - - GetOpReturnData(tx.vout[tx.vout.size()-1].scriptPubKey, vopret); - - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && script[0] == EVAL_IMPORTCOIN && UnmarshalImportTx(tx,proof,burntx,payouts) && UnmarshalBurnTx(burntx,pegstxid,tokenid,srcpub,amount,account)) - { - return('G'); - } - return(0); -} - -CScript EncodePegsReedemOpRet(uint256 tokenid,uint256 pegstxid,CPubKey srcpub,int64_t amount,std::pair account) -{ - CScript opret; uint8_t evalcode=EVAL_PEGS,funcid='R'; struct CCcontract_info *cp,C; - std::vector pubkeys; vscript_t vopret; - - cp = CCinit(&C,EVAL_PEGS); - pubkeys.push_back(srcpub); - vopret = E_MARSHAL(ss << evalcode << funcid << pegstxid << srcpub << amount << account); - return(EncodeTokenOpRet(tokenid,pubkeys,make_pair(OPRETID_PEGSDATA, vopret))); -} - -uint8_t DecodePegsRedeemOpRet(const CScript &scriptPubKey,uint256 &tokenid,uint256 &pegstxid,CPubKey &srcpub,int64_t &amount,std::pair &account) -{ - std::vector> oprets; - std::vector vopret,vOpretExtra; uint8_t *script,e,f,tokenevalcode; std::vector pubkeys; - - if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys, oprets)!=0 && GetOpretBlob(oprets, OPRETID_PEGSDATA, vOpretExtra) && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0) - { - vopret=vOpretExtra; - } - else GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && script[0] == EVAL_PEGS && E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> pegstxid; ss >> srcpub; ss >> amount; ss >> account) != 0 ) - { - return(f); - } - return(0); -} - -CScript EncodePegsExchangeOpRet(uint256 tokenid,uint256 pegstxid,CPubKey pk1,CPubKey pk2,int64_t amount,std::pair account) -{ - CScript opret; uint8_t evalcode=EVAL_PEGS,funcid='E'; struct CCcontract_info *cp,C; - std::vector pubkeys; vscript_t vopret; CPubKey pegspk; - - cp = CCinit(&C,EVAL_PEGS); - pegspk = GetUnspendable(cp,0); - pubkeys.push_back(pk1); - pubkeys.push_back(pk2); - vopret = E_MARSHAL(ss << evalcode << funcid << pegstxid << pk1 << amount << account); - return(EncodeTokenOpRet(tokenid,pubkeys,make_pair(OPRETID_PEGSDATA, vopret))); -} - -uint8_t DecodePegsExchangeOpRet(const CScript &scriptPubKey,uint256 &tokenid,uint256 &pegstxid,CPubKey &srcpub,int64_t &amount,std::pair &account) -{ - std::vector> oprets; - std::vector vopret,vOpretExtra; uint8_t *script,e,f,tokenevalcode; std::vector pubkeys; - - if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys, oprets)!=0 && GetOpretBlob(oprets, OPRETID_PEGSDATA, vOpretExtra) && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0) - { - vopret=vOpretExtra; - } - else GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && script[0] == EVAL_PEGS && E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> pegstxid; ss >> srcpub; ss >> amount; ss >> account) != 0 ) - { - return(f); - } - return(0); -} - -CScript EncodePegsLiquidateOpRet(uint256 tokenid,uint256 pegstxid,CPubKey srcpub,int64_t amount,std::pair account) -{ - CScript opret; uint8_t evalcode=EVAL_PEGS,funcid='L'; struct CCcontract_info *cp,C; - std::vector pubkeys; vscript_t vopret; - - cp = CCinit(&C,EVAL_PEGS); - pubkeys.push_back(srcpub); - vopret = E_MARSHAL(ss << evalcode << funcid << pegstxid << srcpub << amount << account); - return(EncodeTokenOpRet(tokenid,pubkeys,make_pair(OPRETID_PEGSDATA, vopret))); -} - -uint8_t DecodePegsLiquidateOpRet(const CScript &scriptPubKey,uint256 &tokenid,uint256 &pegstxid,CPubKey &srcpub,int64_t &amount,std::pair &account) -{ - std::vector> oprets; - std::vector vopret,vOpretExtra; uint8_t *script,e,f,tokenevalcode; std::vector pubkeys; - - if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys, oprets)!=0 && GetOpretBlob(oprets, OPRETID_PEGSDATA, vOpretExtra) && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0) - { - vopret=vOpretExtra; - } - else GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && script[0] == EVAL_PEGS && E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> pegstxid; ss >> srcpub; ss >> amount; ss >> account) != 0 ) - { - return(f); - } - return(0); -} - -uint8_t DecodePegsOpRet(CTransaction tx,uint256& pegstxid,uint256& tokenid) -{ - std::vector> oprets; int32_t numvouts=tx.vout.size(); - std::vector vopret,vOpretExtra; uint8_t *script,e,f,tokenevalcode; std::vector pubkeys; - ImportProof proof; CTransaction burntx; std::vector payouts; uint256 tmppegstxid; CPubKey srcpub; int64_t amount; std::pair account; - - if (DecodeTokenOpRet(tx.vout[numvouts-1].scriptPubKey,tokenevalcode,tokenid,pubkeys, oprets)!=0 && GetOpretBlob(oprets, OPRETID_PEGSDATA, vOpretExtra) && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0) - { - vopret=vOpretExtra; - } - else GetOpReturnData(tx.vout[numvouts-1].scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if (tx.IsPegsImport()) - return(DecodePegsGetOpRet(tx,pegstxid,tokenid,srcpub,amount,account)); - else if ( vopret.size() > 2 && script[0] == EVAL_PEGS) - { - E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> pegstxid); - return(f); - } - return(0); -} - -int64_t IsPegsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) -{ - char destaddr[64]; - if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) - { - if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) - return(tx.vout[v].nValue); - } - return(0); -} - -bool PegsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) -{ - static uint256 zerohash; - CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) - { - //LogPrintf("vini.%d check mempool\n",i); - if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) - return eval->Invalid("cant find vinTx"); - else - { - //LogPrintf("vini.%d check hash and vout\n",i); - if ( hashBlock == zerohash ) - return eval->Invalid("cant Pegs from mempool"); - if ( (assetoshis= IsPegsvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) - inputs += assetoshis; - } - } - } - for (i=0; iInvalid("mismatched inputs != outputs + txfee"); - } - else return(true); -} - -bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) -{ - int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64]; - return (true); - std::vector > txids; - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - preventCCvins = preventCCvouts = -1; - if ( numvouts < 1 ) - return eval->Invalid("no vouts"); - else - { - for (i=0; iInvalid("illegal normal vini"); - } - } - //LogPrintf("check amounts\n"); - if ( PegsExactAmounts(cp,eval,tx,1,10000) == false ) - { - LogPrintf("Pegsget invalid amount\n"); - return false; - } - else - { - txid = tx.GetHash(); - memcpy(hash,&txid,sizeof(hash)); - retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); - if ( retval != 0 ) - LogPrintf("Pegsget validated\n"); - else LogPrintf("Pegsget invalid\n"); - return(retval); - } - } -} -// end of consensus code - -// helper functions for rpc calls in rpcwallet.cpp - -int64_t AddPegsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk1,CPubKey pk2,int64_t total,int32_t maxinputs) -{ - // add threshold check - char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout,n = 0; - std::vector > unspentOutputs; - - if (pk2.IsValid()) GetCCaddress1of2(cp,coinaddr,pk1,pk2); - else GetCCaddress(cp,coinaddr,pk1); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - // no need to prevent dup - if ( myGetTransaction(txid,vintx,hashBlock) != 0 ) - { - if (myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) - { - if ( total != 0 && maxinputs != 0 ) - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; - n++; - if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) - break; - } - } - } - return(totalinputs); -} - -int64_t AddPegsTokenInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,uint256 pegstxid, uint256 tokenid, CPubKey pk1,CPubKey pk2, int64_t total,int32_t maxinputs) -{ - // add threshold check - char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout,n = 0; - std::vector > unspentOutputs; uint256 tmppegstxid,tmptokenid; CPubKey mypk; - - if (pk2.IsValid()) GetTokensCCaddress1of2(cp,coinaddr,pk1,pk2); - else GetTokensCCaddress(cp,coinaddr,pk1); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - // no need to prevent dup - if ( myGetTransaction(txid,vintx,hashBlock) != 0 ) - { - if (myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 && DecodePegsOpRet(vintx,tmppegstxid,tmptokenid)!=0 && tmppegstxid==pegstxid && tmptokenid==tokenid) - { - if ( total != 0 && maxinputs != 0 ) - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; - n++; - if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) - break; - } - } - } - if (pk2.IsValid()) - { - mypk = pubkey2pk(Mypubkey()); - if (mypk!=pk1 && mypk!=pk2) - { - CCaddrTokens1of2set(cp,pk1,pk2,cp->CCpriv,coinaddr); - } - else - { - uint8_t mypriv[32]; - Myprivkey(mypriv); - CCaddrTokens1of2set(cp,pk1,pk2,mypriv,coinaddr); - memset(mypriv,0,sizeof(mypriv)); - } - } - return(totalinputs); -} - -std::string PegsDecodeAccountTx(CTransaction tx,CPubKey& pk,int64_t &amount,std::pair &account) -{ - uint256 hashBlock,tokenid,pegstxid; int32_t numvouts=tx.vout.size(); char funcid; - - if ((funcid=DecodePegsOpRet(tx,pegstxid,tokenid))!=0) - { - switch(funcid) - { - case 'F': if (DecodePegsFundOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,pegstxid,pk,amount,account)=='F') return("fund"); - break; - case 'G': if (DecodePegsGetOpRet(tx,pegstxid,tokenid,pk,amount,account)=='G') return("get"); - break; - case 'R': if (DecodePegsRedeemOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,pegstxid,pk,amount,account)=='R') return("redeem"); - break; - case 'E': if (DecodePegsExchangeOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,pegstxid,pk,amount,account)=='R') return("exchange"); - break; - case 'L': if (DecodePegsLiquidateOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,pegstxid,pk,amount,account)=='L') return("liquidate"); - break; - } - } - return (""); -} - -char PegsFindAccount(struct CCcontract_info *cp,CPubKey pk,uint256 pegstxid, uint256 tokenid, uint256 &accounttxid, std::pair &account) -{ - char coinaddr[64]; int64_t nValue,tmpamount; uint256 txid,spenttxid,hashBlock,tmptokenid,tmppegstxid; - CTransaction tx,acctx; int32_t numvouts,vout,ratio; char funcid,f; CPubKey pegspk,tmppk; - std::vector > unspentOutputs; - ImportProof proof; CTransaction burntx; std::vector payouts; - - accounttxid=zeroid; - pegspk = GetUnspendable(cp,0); - GetCCaddress1of2(cp,coinaddr,pk,pegspk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - nValue = (int64_t)it->second.satoshis; - LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "txid=" << txid.GetHex() << ", vout=" << vout << ", nValue=" << nValue << std::endl); - if (vout == 1 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size())>0 && - (f=DecodePegsOpRet(tx,tmppegstxid,tmptokenid))!=0 && pegstxid==tmppegstxid && tokenid==tmptokenid) - { - accounttxid=txid; - funcid=f; - acctx=tx; - } - } - if (accounttxid!=zeroid && myIsutxo_spentinmempool(spenttxid,ignorevin,accounttxid,1) != 0) - { - accounttxid=zeroid; - if (myGetTransaction(spenttxid,tx,hashBlock)!=0 && (numvouts=tx.vout.size()) > 0 && - (f=DecodePegsOpRet(tx,tmppegstxid,tmptokenid))!=0 && pegstxid==tmppegstxid && tokenid==tmptokenid) - { - funcid=f; - accounttxid=spenttxid; - acctx=tx; - } - } - if (accounttxid!=zeroid) - { - PegsDecodeAccountTx(acctx,tmppk,tmpamount,account); - return(funcid); - } - else return(0); -} - -int64_t PegsGetTokenPrice(uint256 tokenid) -{ - int64_t price; CTransaction tokentx; uint256 hashBlock; std::vector exp; - std::string name,desc; std::vector vorigpubkey; int32_t numvouts; - - if (myGetTransaction(tokenid,tokentx,hashBlock)!=0 && (numvouts=tokentx.vout.size())>0 && DecodeTokenCreateOpRet(tokentx.vout[numvouts-1].scriptPubKey,vorigpubkey,name,desc)=='c') - { - std::vector vexpr; - SplitStr(desc, vexpr); - if (prices_syntheticvec(exp, vexpr)>=0 && (price = prices_syntheticprice(exp, komodo_currentheight(), 0, 1))>=0) - return (price); - } - return (0); -} - -std::string PegsGetTokenName(uint256 tokenid) -{ - CTransaction tokentx; uint256 hashBlock; std::string name,desc; std::vector vorigpubkey; int32_t numvouts; - - if (myGetTransaction(tokenid,tokentx,hashBlock)!=0 && (numvouts=tokentx.vout.size())>0 && DecodeTokenCreateOpRet(tokentx.vout[numvouts-1].scriptPubKey,vorigpubkey,name,desc)=='c') - { - return (name); - } - CCerror = strprintf("cant find token create or invalid tokenid %s",tokenid.GetHex()); - LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl); - return(""); -} - -int64_t PegsGetTokensAmountPerPrice(int64_t amount,uint256 tokenid) -{ - mpz_t res,a,b; - mpz_init(res); - mpz_init(a); - mpz_init(b); - mpz_set_si(a, amount); - mpz_set_si(b, COIN); - mpz_mul(res, a, b); - mpz_set_si(a, PegsGetTokenPrice(tokenid)); - mpz_tdiv_q(res, res, a); - return (mpz_get_si(res)); -} - -double PegsGetRatio(uint256 tokenid,std::pair account) -{ - mpz_t res,a,b; - mpz_init(res); - mpz_init(a); - mpz_init(b); - mpz_set_si(a, account.first); - mpz_set_si(b, PegsGetTokenPrice(tokenid)); - mpz_mul(res, a, b); - mpz_set_si(a, COIN); - mpz_tdiv_q(res, res, a); - return ((double)account.second)*100/mpz_get_si(res); -} - -double PegsGetAccountRatio(uint256 pegstxid,uint256 tokenid,uint256 accounttxid) -{ - int64_t amount; uint256 hashBlock,tmptokenid,tmppegstxid; - CTransaction tx; int32_t numvouts; char funcid; CPubKey pk; - std::pair account; struct CCcontract_info *cp,C; - - cp = CCinit(&C,EVAL_PEGS); - if (myGetTransaction(accounttxid,tx,hashBlock) != 0 && (numvouts=tx.vout.size())>0 && - (funcid=DecodePegsOpRet(tx,tmppegstxid,tmptokenid))!=0 && pegstxid==tmppegstxid && tokenid==tmptokenid) - { - PegsDecodeAccountTx(tx,pk,amount,account); - return PegsGetRatio(tokenid,account); - } - return (0); -} - -double PegsGetGlobalRatio(uint256 pegstxid) -{ - char coinaddr[64]; int64_t nValue,amount,globaldebt=0; uint256 txid,accounttxid,hashBlock,tmppegstxid,tokenid; - CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey mypk,pegspk,pk; - std::vector > unspentOutputs; std::pair account; - std::map> globalaccounts; - struct CCcontract_info *cp,C; - - cp = CCinit(&C,EVAL_PEGS); - pegspk = GetUnspendable(cp,0); - GetCCaddress1of2(cp,coinaddr,pegspk,pegspk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - nValue = (int64_t)it->second.satoshis; - if (vout == 0 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size())>0 && - (funcid=DecodePegsOpRet(tx,tmppegstxid,tokenid))!=0 && pegstxid==tmppegstxid && (funcid=='F' || funcid=='G' || funcid=='E')) - { - PegsDecodeAccountTx(tx,pk,amount,account); - globalaccounts[tokenid].first+=account.first; - globalaccounts[tokenid].second+=account.second; - } - } - unspentOutputs.clear(); - GetTokensCCaddress(cp,coinaddr,pegspk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - nValue = (int64_t)it->second.satoshis; - if (myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size())>0 && DecodePegsOpRet(tx,tmppegstxid,tokenid)!=0 && pegstxid==tmppegstxid) - { - globalaccounts[tokenid].first+=nValue; - } - } - mpz_t res,globaldeposit,a,b; - mpz_init(res); - mpz_init(globaldeposit); - mpz_init(a); - mpz_init(b); - mpz_set_si(globaldeposit, 0); - for (std::map>::iterator it = globalaccounts.begin(); it != globalaccounts.end(); ++it) - { - mpz_set_si(res, 0); - mpz_set_si(a, globalaccounts[it->first].first); - mpz_set_si(b, PegsGetTokenPrice(it->first)); - mpz_mul(res,a,b); - mpz_add(globaldeposit,globaldeposit,res); - globaldebt+=globalaccounts[it->first].second; - } - if (globaldebt>0) - { - mpz_set_si(res, 0); - mpz_set_si(a, COIN); - mpz_tdiv_q(res, globaldeposit, a); - printf("%lu %lu\n",globaldebt,mpz_get_si(res)); - return ((double)globaldebt)*100/mpz_get_si(res); - } - return (0); -} - -std::string PegsFindBestAccount(struct CCcontract_info *cp,uint256 pegstxid, uint256 tokenid, int64_t tokenamount,uint256 &accounttxid, std::pair &account) -{ - char coinaddr[64]; int64_t nValue,tmpamount; uint256 txid,hashBlock,tmptokenid,tmppegstxid; - CTransaction tx,acctx; int32_t numvouts,vout; char funcid,f; CPubKey pegspk,tmppk; - std::vector > unspentOutputs; - ImportProof proof; CTransaction burntx; std::vector payouts; double ratio,maxratio=0; - std::pair tmpaccount; - - accounttxid=zeroid; - pegspk = GetUnspendable(cp,0); - GetCCaddress1of2(cp,coinaddr,pegspk,pegspk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - nValue = (int64_t)it->second.satoshis; - LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "txid=" << txid.GetHex() << ", vout=" << vout << ", nValue=" << nValue << std::endl); - if (vout == 0 && nValue == CC_MARKER_VALUE && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,0) == 0 && - (ratio=PegsGetAccountRatio(pegstxid,tokenid,txid))>(ASSETCHAINS_PEGSCCPARAMS[2]?ASSETCHAINS_PEGSCCPARAMS[2]:PEGS_ACCOUNT_YELLOW_ZONE) && ratio>maxratio) - { - if (myGetTransaction(txid,tx,hashBlock)!=0 && !PegsDecodeAccountTx(tx,tmppk,tmpamount,tmpaccount).empty() && tmpaccount.first>=tokenamount) - { - accounttxid=txid; - acctx=tx; - maxratio=ratio; - } - } - } - if (accounttxid!=zeroid) - { - return(PegsDecodeAccountTx(acctx,tmppk,tmpamount,account)); - } - else return(""); -} - -UniValue PegsCreate(const CPubKey& pk,uint64_t txfee,int64_t amount, std::vector bindtxids) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - CPubKey mypk,pegspk; struct CCcontract_info *cp,C; CTransaction tx; int32_t numvouts; int64_t totalsupply; std::string coin; - char depositaddr[64]; uint256 txid,hashBlock,tmptokenid,oracletxid; uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector pubkeys; - - cp = CCinit(&C,EVAL_PEGS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - pegspk = GetUnspendable(cp,0); - for(auto txid : bindtxids) - { - if (myGetTransaction(txid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find bindtxid " << txid.GetHex()); - if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tmptokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)!='B') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid bindtxid " << txid.GetHex()); - } - if ( AddNormalinputs(mtx,mypk,amount,64,pk.IsValid()) >= amount ) - { - for (int i=0; i<100; i++) mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,(amount-txfee)/100,pegspk)); - return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodePegsCreateOpRet(bindtxids))); - } - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "error adding normal inputs"); -} - -UniValue PegsFund(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid,int64_t amount) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); std::string coin; - CTransaction pegstx,tx; int32_t numvouts; int64_t totalsupply,balance=0,funds=0,tokenfunds=0; uint256 accounttxid=zeroid,hashBlock,txid,tmptokenid,oracletxid; - CPubKey mypk,pegspk,tmppk; struct CCcontract_info *cp,*cpTokens,CTokens,C; char depositaddr[64],coinaddr[64]; std::pair account(0,0); - uint8_t M,N,taddr,prefix,prefix2,wiftype,mypriv[32]; std::vector pubkeys; bool found=false; std::vector bindtxids; - - cp = CCinit(&C,EVAL_PEGS); - cpTokens = CCinit(&CTokens,EVAL_TOKENS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - pegspk = GetUnspendable(cp,0); - if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex()); - if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex()); - for(auto txid : bindtxids) - { - if (myGetTransaction(txid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find bindtxid " << txid.GetHex()); - if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tmptokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)!='B') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid bindtxid " << txid.GetHex()); - if (tmptokenid==tokenid) - { - found=true; - break; - } - } - if (!found) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid tokenid " << tokenid.GetHex()); - if ((balance=GetTokenBalance(mypk,tokenid))>=amount) - { - PegsFindAccount(cp,mypk,pegstxid,tokenid,accounttxid,account); - LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "current accounttxid=" << accounttxid.GetHex() << " [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl); - if (accounttxid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,accounttxid,1) != 0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "previous account tx not yet confirmed"); - if (accounttxid!=zeroid && (funds=AddPegsInputs(cp,mtx,pegspk,CPubKey(),txfee,1))>=txfee) - { - funds+=2*CC_MARKER_VALUE; - mtx.vin.push_back(CTxIn(accounttxid,0,CScript())); - Myprivkey(mypriv); - mtx.vin.push_back(CTxIn(accounttxid,1,CScript())); - GetCCaddress1of2(cp,coinaddr,mypk,pegspk); - CCaddr1of2set(cp,mypk,pegspk,mypriv,coinaddr); - memset(mypriv,0,sizeof(mypriv)); - } - else funds=AddPegsInputs(cp,mtx,pegspk,CPubKey(),txfee+2*CC_MARKER_VALUE,3); - if (funds>=txfee+2*CC_MARKER_VALUE) - { - if ((tokenfunds=AddTokenCCInputs(cpTokens,mtx,mypk,tokenid,amount,64))>=amount) - { - mtx.vout.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,pegspk,pegspk)); - mtx.vout.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,mypk,pegspk)); - mtx.vout.push_back(MakeTokensCC1of2vout(EVAL_PEGS,amount,mypk,pegspk)); - if (tokenfunds-amount>0) mtx.vout.push_back(MakeTokensCC1vout(EVAL_TOKENS,tokenfunds-amount,mypk)); - if (funds>txfee+2*CC_MARKER_VALUE) mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,funds-(txfee+2*CC_MARKER_VALUE),pegspk)); - account.first+=amount; - LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "new account [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl); - return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodePegsFundOpRet(tokenid,pegstxid,mypk,amount,account))); - } - } - else - CCERR_RESULT("pegscc",CCLOG_INFO, stream <<"not enough balance in pegs global CC address"); - } - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance (" << balance << ") for this amount of tokens " << amount); -} - -UniValue PegsGet(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount) -{ - CMutableTransaction burntx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()),mtx; - CTransaction pegstx,tx; int32_t numvouts; int64_t funds=0; uint256 accounttxid=zeroid,hashBlock,pricestxid; char coinaddr[64]; - CPubKey mypk,pegspk,tmppk; struct CCcontract_info *cp,C; std::pair account(0,0); uint8_t mypriv[32]; - std::vector dummyproof; std::vector vouts; std::vector bindtxids; CScript opret; - - cp = CCinit(&C,EVAL_PEGS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - pegspk = GetUnspendable(cp,0); - if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex()); - if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex()); - if (PegsFindAccount(cp,mypk,pegstxid,tokenid,accounttxid,account)==0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cannot find account from which to issue coins, fund account first with pegsfund!"); - if (accounttxid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,accounttxid,1) != 0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "previous account tx not yet confirmed"); - LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "current accounttxid=" << accounttxid.GetHex() << " [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl); - // spending markers - vouts.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,pegspk,pegspk)); - vouts.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,mypk,pegspk)); - // coin issue - vouts.push_back(CTxOut(amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - account.second+=amount; - if (PegsGetRatio(tokenid,account)>PEGS_ACCOUNT_MAX_DEBT) - { - CCerror = strprintf("not possible to take more than %d%% of the deposit",PEGS_ACCOUNT_MAX_DEBT); - LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl); - return(""); - } - LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "new account [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl); - // burn tx does not exist in pegs method but it must be created in order for import validation to pass - // fictive burntx input of previous account state tx - burntx.vin.push_back(CTxIn(accounttxid,0,CScript())); - // fictive output of coins in burn tx - burntx.vout.push_back(MakeBurnOutput(amount,0xffffffff,"PEGSCC",vouts,dummyproof,pegstxid,tokenid,mypk,amount,account)); - std::vector leaftxids; - BitcoinGetProofMerkleRoot(dummyproof, leaftxids); - MerkleBranch newBranch(0, leaftxids); - TxProof txProof = std::make_pair(burntx.GetHash(), newBranch); - mtx=MakePegsImportCoinTransaction(txProof,burntx,vouts); - Myprivkey(mypriv); - GetCCaddress1of2(cp,coinaddr,mypk,pegspk); - CCaddr1of2set(cp,mypk,pegspk,mypriv,coinaddr); - UniValue retstr = FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,opret); - memset(mypriv,0,sizeof(mypriv)); - return(retstr); -} - -UniValue PegsRedeem(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); std::string coin; - CTransaction pegstx,tx; int32_t numvouts; int64_t totalsupply,pegsfunds=0,funds=0,tokenfunds=0,amount; uint256 accounttxid=zeroid,hashBlock,txid,tmptokenid,oracletxid; - CPubKey mypk,pegspk,tmppk; struct CCcontract_info *cp,*cpTokens,CTokens,C; char depositaddr[64],coinaddr[64]; std::pair account(0,0); - uint8_t M,N,taddr,prefix,prefix2,wiftype,mypriv[32]; std::vector pubkeys; bool found=false; std::vector bindtxids; - - cp = CCinit(&C,EVAL_PEGS); - cpTokens = CCinit(&CTokens,EVAL_TOKENS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - pegspk = GetUnspendable(cp,0); - if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex()); - if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex()); - for(auto txid : bindtxids) - { - if (myGetTransaction(txid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find bindtxid " << txid.GetHex()); - if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tmptokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)!='B') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid bindtxid " << txid.GetHex()); - if (tmptokenid==tokenid) - { - found=true; - break; - } - } - if (!found) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid tokenid " << tokenid.GetHex()); - if (PegsFindAccount(cp,mypk,pegstxid,tokenid,accounttxid,account)==0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cannot find account from which to redeem tokens!"); - if (accounttxid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,accounttxid,1) != 0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "previous account tx not yet confirmed"); - LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "current accounttxid=" << accounttxid.GetHex() << " [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl); - if ((funds=AddNormalinputs(mtx,mypk,account.second,64,pk.IsValid()))>=account.second ) - { - if (accounttxid!=zeroid && (pegsfunds=AddPegsInputs(cp,mtx,pegspk,CPubKey(),txfee,1))>=txfee) - { - pegsfunds+=2*CC_MARKER_VALUE; - mtx.vin.push_back(CTxIn(accounttxid,0,CScript())); - mtx.vin.push_back(CTxIn(accounttxid,1,CScript())); - Myprivkey(mypriv); - GetCCaddress1of2(cp,coinaddr,mypk,pegspk); - CCaddr1of2set(cp,mypk,pegspk,mypriv,coinaddr); - amount=account.first; - if ((tokenfunds=AddPegsTokenInputs(cp,mtx,pegstxid,tokenid,mypk,pegspk,amount,64))>=amount) - { - if (pegsfunds>=txfee+2*CC_MARKER_VALUE) - { - mtx.vout.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,pegspk,pegspk)); - mtx.vout.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,mypk,pegspk)); - mtx.vout.push_back(MakeTokensCC1vout(EVAL_TOKENS,amount,mypk)); - mtx.vout.push_back(CTxOut(account.second,CScript() << ParseHex(HexStr(CCtxidaddr(coinaddr,pegstxid))) << OP_CHECKSIG)); - if (pegsfunds>txfee+2*CC_MARKER_VALUE) mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,pegsfunds-(txfee+2*CC_MARKER_VALUE),pegspk)); - account.first=0; - account.second=0; - LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "new account [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl); - UniValue retstr = FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodePegsReedemOpRet(tokenid,pegstxid,mypk,amount,account)); - memset(mypriv,0,32); - return(retstr); - } - else - { - memset(mypriv,0,32); - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address"); - } - } - memset(mypriv,0,32); - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough tokens in pegs account (" << tokenfunds << ") to redeem this amount of tokens " << account.first); - } - else - { - memset(mypriv,0,32); - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address"); - } - } - memset(mypriv,0,32); - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "to redeem from account and close it you must redeem full debt ammount " << account.second << " instead of " << funds); -} - - -UniValue PegsExchange(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); std::string coin; - CTransaction pegstx,tx; int32_t numvouts; int64_t totalsupply,pegsfunds=0,funds=0,tokenfunds=0,tokenamount,tmpamount; uint256 accounttxid=zeroid,hashBlock,txid,tmptokenid,oracletxid; - CPubKey mypk,pegspk,tmppk; struct CCcontract_info *cp,*cpTokens,CTokens,C; char depositaddr[64],coinaddr[64]; std::pair account(0,0); - uint8_t M,N,taddr,prefix,prefix2,wiftype,mypriv[32]; std::vector pubkeys; bool found=false; std::vector bindtxids; - - cp = CCinit(&C,EVAL_PEGS); - cpTokens = CCinit(&CTokens,EVAL_TOKENS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - pegspk = GetUnspendable(cp,0); - if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex()); - if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex()); - for(auto txid : bindtxids) - { - if (myGetTransaction(txid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find bindtxid " << txid.GetHex()); - if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tmptokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)!='B') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid bindtxid " << txid.GetHex()); - if (tmptokenid==tokenid) - { - found=true; - break; - } - } - if (!found) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid tokenid " << tokenid.GetHex()); - if (PegsFindAccount(cp,mypk,pegstxid,tokenid,accounttxid,account)!=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "you have active account, please close account first before exchanging other coins!"); - if ((funds=AddNormalinputs(mtx,mypk,amount,64,pk.IsValid()))>=amount ) - { - if ((pegsfunds=AddPegsInputs(cp,mtx,pegspk,CPubKey(),txfee,1))>=txfee) - { - tokenamount=PegsGetTokensAmountPerPrice(amount,tokenid); - tokenfunds=AddPegsTokenInputs(cp,mtx,pegstxid,tokenid,pegspk,CPubKey(),tokenamount,64); - if (tokenfundsCCpriv,coinaddr); - pegsfunds+=2*CC_MARKER_VALUE; - } - if (tokenfunds>=tokenamount) - { - if (accounttxid!=zeroid) - { - mtx.vout.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,pegspk,pegspk)); - mtx.vout.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,tmppk,pegspk)); - } - if ((accounttxid!=zeroid && pegsfunds>=txfee+2*CC_MARKER_VALUE) || pegsfunds>=txfee) - { - mtx.vout.push_back(MakeTokensCC1vout(EVAL_TOKENS,tokenamount,mypk)); - mtx.vout.push_back(CTxOut(amount,CScript() << ParseHex(HexStr(CCtxidaddr(coinaddr,pegstxid))) << OP_CHECKSIG)); - if (tokenfunds>tokenamount) mtx.vout.push_back(MakeTokensCC1of2vout(EVAL_PEGS,tokenfunds-tokenamount,tmppk,pegspk)); - if (accounttxid!=zeroid) - { - if (pegsfunds>txfee+2*CC_MARKER_VALUE) mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,pegsfunds-(txfee+2*CC_MARKER_VALUE),pegspk)); - account.first=account.first-tokenamount; - account.second=account.second-amount; - } - else if (pegsfunds>txfee) mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,pegsfunds-txfee,pegspk)); - LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "modified account [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl); - return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodePegsExchangeOpRet(tokenid,pegstxid,mypk,tmppk,amount,account))); - } - else - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address"); - } - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough tokens in pegs account (" << tokenfunds << ") to exchange to this amount of tokens " << tokenamount); - } - else - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address"); - } - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough funds to exchange " << amount << " coins to tokens - balance " << funds); -} - -UniValue PegsLiquidate(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, uint256 liquidatetxid) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); std::string coin; - CTransaction pegstx,tx; int32_t numvouts; int64_t totalsupply,pegsfunds=0,funds=0,tokenfunds=0,amount,tmpamount,tokenamount,burnamount; - CPubKey mypk,pegspk,tmppk; struct CCcontract_info *cp,*cpTokens,CTokens,C; char depositaddr[64],coinaddr[64]; std::pair account(0,0),myaccount(0,0); - uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector pubkeys; bool found=false; std::vector bindtxids; - uint256 hashBlock,txid,tmptokenid,oracletxid,accounttxid; - - cp = CCinit(&C,EVAL_PEGS); - cpTokens = CCinit(&CTokens,EVAL_TOKENS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - pegspk = GetUnspendable(cp,0); - if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex()); - if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex()); - for(auto txid : bindtxids) - { - if (myGetTransaction(txid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find bindtxid " << txid.GetHex()); - if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tmptokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)!='B') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid bindtxid " << txid.GetHex()); - if (tmptokenid==tokenid) - { - found=true; - break; - } - } - if (!found) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid tokenid " << tokenid.GetHex()); - if (PegsFindAccount(cp,mypk,pegstxid,tokenid,accounttxid,myaccount)==0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cannot find account, you must have an account to liquidate another account!"); - if (accounttxid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,accounttxid,1) != 0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "previous account tx not yet confirmed"); - if (PegsGetAccountRatio(pegstxid,tokenid,liquidatetxid)<(ASSETCHAINS_PEGSCCPARAMS[0]?ASSETCHAINS_PEGSCCPARAMS[0]:PEGS_ACCOUNT_RED_ZONE) || PegsGetGlobalRatio(pegstxid)<(ASSETCHAINS_PEGSCCPARAMS[1]?ASSETCHAINS_PEGSCCPARAMS[1]:PEGS_ACCOUNT_RED_ZONE)) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not able to liquidate account until account ratio > " << (ASSETCHAINS_PEGSCCPARAMS[0]?ASSETCHAINS_PEGSCCPARAMS[0]:PEGS_ACCOUNT_RED_ZONE) << "% and global ratio > " << (ASSETCHAINS_PEGSCCPARAMS[1]?ASSETCHAINS_PEGSCCPARAMS[1]:PEGS_ACCOUNT_RED_ZONE) << "%"); - if (liquidatetxid!=zeroid && myGetTransaction(liquidatetxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0 || PegsDecodeAccountTx(tx,tmppk,amount,account).empty()) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cannot find account to liquidate or invalid tx " << liquidatetxid.GetHex()); - if (liquidatetxid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,liquidatetxid,1) != 0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "previous liquidate account tx not yet confirmed"); - LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "current accounttxid=" << accounttxid.GetHex() << " [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl); - tokenamount=account.first; - burnamount=account.second; - tmpamount=PegsGetTokensAmountPerPrice(burnamount,tokenid)*105/100; - amount=tmpamount+((tokenamount-tmpamount)*10/100); - if ((funds=AddNormalinputs(mtx,mypk,account.second,64))>=burnamount) - { - if (liquidatetxid!=zeroid && (pegsfunds=AddPegsInputs(cp,mtx,pegspk,CPubKey(),txfee,1))>=txfee) - { - pegsfunds+=2*CC_MARKER_VALUE; - mtx.vin.push_back(CTxIn(liquidatetxid,0,CScript())); - mtx.vin.push_back(CTxIn(liquidatetxid,1,CScript())); - GetCCaddress1of2(cp,coinaddr,tmppk,pegspk); - CCaddr1of2set(cp,tmppk,pegspk,cp->CCpriv,coinaddr); - if ((tokenfunds=AddPegsTokenInputs(cp,mtx,pegstxid,tokenid,tmppk,pegspk,tokenamount,64))==tokenamount) - { - if (pegsfunds>=txfee+2*CC_MARKER_VALUE) - { - mtx.vout.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,pegspk,pegspk)); - mtx.vout.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,tmppk,pegspk)); - mtx.vout.push_back(MakeTokensCC1vout(EVAL_TOKENS,amount,mypk)); - mtx.vout.push_back(MakeTokensCC1vout(EVAL_PEGS,tokenamount-amount,pegspk)); - mtx.vout.push_back(CTxOut(burnamount,CScript() << ParseHex(HexStr(CCtxidaddr(coinaddr,pegstxid))) << OP_CHECKSIG)); - if (pegsfunds>txfee+2*CC_MARKER_VALUE) mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,pegsfunds-(txfee+2*CC_MARKER_VALUE),pegspk)); - account.first=0; - account.second=0; - LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "new account [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl); - return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodePegsLiquidateOpRet(tokenid,pegstxid,mypk,amount,account))); - } - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address"); - } - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "tokens amount in pegs account " << tokenfunds << " not matching amount in account " << account.first); // this shouldn't happen - } - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address"); - } - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough funds to liquidate account, you must liquidate full debt ammount " << txfee+account.second << " instead of " << funds); -} - -UniValue PegsAccountHistory(const CPubKey& pk,uint256 pegstxid) -{ - char coinaddr[64]; int64_t nValue,amount; uint256 txid,accounttxid,hashBlock,tmptokenid,tmppegstxid; - CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey mypk,pegspk,tmppk; std::map> accounts; - std::vector txids; std::pair account; std::vector bindtxids; - UniValue result(UniValue::VOBJ),acc(UniValue::VARR); struct CCcontract_info *cp,C; - - if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex()); - if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex()); - result.push_back(Pair("result","success")); - result.push_back(Pair("name","pegsaccounthistory")); - cp = CCinit(&C,EVAL_PEGS); - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - pegspk = GetUnspendable(cp,0); - GetCCaddress1of2(cp,coinaddr,mypk,pegspk); - SetCCtxids(txids,coinaddr,true,EVAL_PEGS,pegstxid,0); - for (std::vector::const_iterator it=txids.begin(); it!=txids.end(); it++) - { - txid = *it; - if (myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size())>0 && - (funcid=DecodePegsOpRet(tx,tmppegstxid,tmptokenid))!=0 && pegstxid==tmppegstxid) - { - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("action",PegsDecodeAccountTx(tx,tmppk,amount,account))); - obj.push_back(Pair("amount",amount)); - obj.push_back(Pair("accounttxid",txid.GetHex())); - obj.push_back(Pair("token",PegsGetTokenName(tmptokenid))); - obj.push_back(Pair("deposit",account.first)); - obj.push_back(Pair("debt",account.second)); - acc.push_back(obj); - } - } - result.push_back(Pair("account history",acc)); - return(result); -} - -UniValue PegsAccountInfo(const CPubKey& pk,uint256 pegstxid) -{ - char coinaddr[64]; int64_t nValue,amount; uint256 txid,accounttxid,hashBlock,tmptokenid,tmppegstxid; std::map> accounts; - CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey mypk,pegspk,tmppk; std::vector bindtxids; - std::vector > unspentOutputs; std::pair account; - UniValue result(UniValue::VOBJ),acc(UniValue::VARR); struct CCcontract_info *cp,C; - - if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex()); - if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex()); - result.push_back(Pair("result","success")); - result.push_back(Pair("name","pegsaccountinfo")); - cp = CCinit(&C,EVAL_PEGS); - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - pegspk = GetUnspendable(cp,0); - GetCCaddress1of2(cp,coinaddr,mypk,pegspk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - nValue = (int64_t)it->second.satoshis; - //LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "txid=" << txid.GetHex() << ", vout=" << vout << ", nValue=" << nValue << std::endl); - if (vout == 1 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size())>0 && - (funcid=DecodePegsOpRet(tx,tmppegstxid,tmptokenid))!=0 && pegstxid==tmppegstxid) - { - //LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "txid=" << txid.GetHex() << ", vout=" << vout << ", nValue=" << nValue << ", tokenid=" << tmptokenid.GetHex() << std::endl); - PegsDecodeAccountTx(tx,tmppk,amount,account); - accounts[tmptokenid].first=account.first; - accounts[tmptokenid].second=account.second; - } - } - for (std::map>::iterator it = accounts.begin(); it != accounts.end(); ++it) - { - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("token",PegsGetTokenName(it->first))); - obj.push_back(Pair("deposit",accounts[it->first].first)); - obj.push_back(Pair("debt",accounts[it->first].second)); - if (accounts[it->first].first==0 || accounts[it->first].second==0 || PegsGetTokenPrice(it->first)<=0) obj.push_back(Pair("ratio",0)); - else obj.push_back(Pair("ratio",strprintf("%.2f%%",PegsGetRatio(it->first,accounts[it->first])))); - acc.push_back(obj); - } - result.push_back(Pair("account info",acc)); - return(result); -} - -UniValue PegsWorstAccounts(uint256 pegstxid) -{ - char coinaddr[64]; int64_t nValue,amount; uint256 txid,accounttxid,hashBlock,tmppegstxid,tokenid,prev; - CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey pegspk,pk; double ratio; std::vector bindtxids; - std::vector > unspentOutputs; std::pair account; - UniValue result(UniValue::VOBJ),acc(UniValue::VARR); struct CCcontract_info *cp,C; std::multimap map; - - if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex()); - if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex()); - result.push_back(Pair("result","success")); - result.push_back(Pair("name","pegsworstaccounts")); - cp = CCinit(&C,EVAL_PEGS); - pegspk = GetUnspendable(cp,0); - GetCCaddress1of2(cp,coinaddr,pegspk,pegspk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - nValue = (int64_t)it->second.satoshis; - if (vout == 0 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size())>0 && - (funcid=DecodePegsOpRet(tx,tmppegstxid,tokenid))!=0 && pegstxid==tmppegstxid) - { - PegsDecodeAccountTx(tx,pk,amount,account); - if (account.first==0 || account.second==0 || PegsGetTokenPrice(tokenid)<=0) ratio=0; - else ratio=PegsGetRatio(tokenid,account); - if (ratio>PEGS_ACCOUNT_RED_ZONE) - { - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("accounttxid",txid.GetHex())); - obj.push_back(Pair("deposit",account.first)); - obj.push_back(Pair("debt",account.second)); - obj.push_back(Pair("ratio",strprintf("%.2f%%",ratio))); - map.insert(std::pair(tokenid,obj)); - } - } - } - std::multimap::iterator it = map.begin(); - for (prev=it->first; it != map.end(); ++it) - { - if (it->first!=prev) - { - result.push_back(Pair(PegsGetTokenName(prev),acc)); - acc.clear(); - prev=it->first; - } - acc.push_back(it->second); - } - result.push_back(Pair(PegsGetTokenName(prev),acc)); - return(result); -} - -UniValue PegsInfo(uint256 pegstxid) -{ - char coinaddr[64]; int64_t nValue,amount; uint256 txid,accounttxid,hashBlock,tmppegstxid,tokenid; - CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey pegspk,pk; std::vector bindtxids; - std::vector > unspentOutputs; std::pair account; - std::map> globalaccounts; double globaldeposit=0; - UniValue result(UniValue::VOBJ),acc(UniValue::VARR); struct CCcontract_info *cp,C; - - if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex()); - if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C') - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex()); - result.push_back(Pair("result","success")); - result.push_back(Pair("name","pegsinfo")); - cp = CCinit(&C,EVAL_PEGS); - pegspk = GetUnspendable(cp,0); - GetCCaddress1of2(cp,coinaddr,pegspk,pegspk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - nValue = (int64_t)it->second.satoshis; - if (vout == 0 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size())>0 && - (funcid=DecodePegsOpRet(tx,tmppegstxid,tokenid))!=0 && pegstxid==tmppegstxid) - { - PegsDecodeAccountTx(tx,pk,amount,account); - globalaccounts[tokenid].first+=account.first; - globalaccounts[tokenid].second+=account.second; - } - } - unspentOutputs.clear(); - GetTokensCCaddress(cp,coinaddr,pegspk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - nValue = (int64_t)it->second.satoshis; - if (myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size())>0 && DecodePegsOpRet(tx,tmppegstxid,tokenid)!=0 && pegstxid==tmppegstxid) - { - globalaccounts[tokenid].first+=nValue; - } - } - for (std::map>::iterator it = globalaccounts.begin(); it != globalaccounts.end(); ++it) - { - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("token",PegsGetTokenName(it->first))); - obj.push_back(Pair("total deposit",globalaccounts[it->first].first)); - obj.push_back(Pair("total debt",globalaccounts[it->first].second)); - if (globalaccounts[it->first].first==0 || globalaccounts[it->first].second==0 || PegsGetTokenPrice(it->first)<=0) obj.push_back(Pair("total ratio",0)); - else obj.push_back(Pair("total ratio",strprintf("%.2f%%",PegsGetRatio(it->first,globalaccounts[it->first])))); - acc.push_back(obj); - } - result.push_back(Pair("info",acc)); - result.push_back(Pair("global ratio",strprintf("%.2f%%",PegsGetGlobalRatio(pegstxid)))); - return(result); -} diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp deleted file mode 100644 index 059a8d05..00000000 --- a/src/cc/prices.cpp +++ /dev/null @@ -1,2510 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - *****************************************************************************/ - - /* - CBOPRET creates trustless oracles, which can be used for making a synthetic cash settlement system based on real world prices; - - 0.5% fee based on betamount, NOT leveraged betamount!! - 0.1% collected by price basis determinant - 0.2% collected by rekt tx - - PricesBet -> +/-leverage, amount, synthetic -> opreturn includes current price - funds are locked into 1of2 global CC address - for first day, long basis is MAX(correlated,smoothed), short is MIN() - reference price is the smoothed of the previous block - if synthetic value + amount goes negative, then anybody can rekt it to collect a rektfee, proof of rekt must be included to show cost basis, rekt price - original creator can liquidate at anytime and collect (synthetic value + amount) from globalfund - 0.5% of bet -> globalfund - - PricesStatus -> bettxid maxsamples returns initial params, cost basis, amount left, rekt:true/false, rektheight, initial synthetic price, current synthetic price, net gain - - PricesRekt -> bettxid height -> 0.1% to miner, rest to global CC - - PricesClose -> bettxid returns (synthetic value + amount) - - PricesList -> all bettxid -> list [bettxid, netgain] - - */ - -/* -To create payments plan start a chain with the following ac_params: - -ac_snapshot=1440 (or for test chain something smaller, if you like.) - - this enables the payments airdrop cc to work. - -ac_earlytxidcontract=237 (Eval code for prices cc.) - - this allows to know what contract this chain is paying with the scriptpubkey in the earlytxid op_return. - -./komodod -ac_name=TESTPRC -ac_supply=100000000 -ac_reward=1000000000 -ac_nk=96,5 -ac_blocktime=20 -ac_cc=2 -ac_snapshot=50 -ac_sapling=1 -ac_earlytxidcontract=237 -testnode=1 -gen -genproclimit=1 - -Then in very early block < 10 or so, do paymentsairdrop eg. - `./komodo-cli -ac_name=TESTPRC paymentsairdrop '[10,10,0,3999,0,0]' -Once this tx is confirmed, do `paymentsfund` and decode the raw hex. You can edit the source to not send the tx if requried. -Get the full `hex` of the vout[0] that pays to CryptoCondition. then place it on chain with the following command: with the hex you got in place of the hex below. - './komodo-cli -ac_name=TESTPRC opreturn_burn 1 2ea22c8020292ba5c8fd9cc89b12b35bf8f5d00196990ecbb06102b84d9748d11d883ef01e81031210008203000401cc' -copy the hex, and sendrawtransaction, copy the txid returned. -this places the scriptpubkey that pays the plan into an op_return before block 100, allowing us to retreive it, and nobody to change it. -Restart the daemon with -earlytxid= eg: - -./komodod -ac_name=TESTPRC -ac_supply=100000000 -ac_reward=1000000000 -ac_nk=96,5 -ac_blocktime=20 -ac_cc=2 -ac_snapshot=50 -ac_sapling=1 -ac_earlytxidcontract=237 -earlytxid=cf89d17fb11037f65c160d0749dddd74dc44d9893b0bb67fe1f96c1f59786496 -testnode=1 -gen -genproclimit=1 - -mine the chain past block 100, preventing anyone else, creating another payments plan on chain before block 100. - -We call the following in Validation and RPC where the address is needed. -if ( ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_EARLYTXID_SCRIPTPUB.size() == 0 ) - GetKomodoEarlytxidScriptPub(); - -This will fetch the op_return, calculate the scriptPubKey and save it to the global. -On daemon restart as soon as validation for BETTX happens the global will be filled, after this the transaction never needs to be looked up again. -GetKomodoEarlytxidScriptPub is on line #2080 of komodo_bitcoind.h - */ - -#include "CCassets.h" -#include "CCPrices.h" - -#include -#include - -#define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) - -#define NVOUT_CCMARKER 1 -#define NVOUT_NORMALMARKER 3 - -typedef struct OneBetData { - int64_t positionsize; - int32_t firstheight; - int64_t costbasis; - int64_t profits; - - OneBetData() { positionsize = 0; firstheight = 0; costbasis = 0; profits = 0; } // it is important to clear costbasis as it will be calculated as minmax from inital value 0 -} onebetdata; - -typedef struct BetInfo { - uint256 txid; - int64_t averageCostbasis, firstprice, lastprice, liquidationprice, equity; - int64_t exitfee; - int32_t lastheight; - int16_t leverage; - bool isOpen, isRekt; - uint256 tokenid; - - std::vector vecparsed; - std::vector bets; - CPubKey pk; - - bool isUp; - - BetInfo() { - averageCostbasis = firstprice = lastprice = liquidationprice = equity = 0; - lastheight = 0; - leverage = 0; - exitfee = 0; - isOpen = isRekt = isUp = false; - } -} BetInfo; - -typedef struct MatchedBookTotal { - - int64_t diffLeveragedPosition; - -} MatchedBookTotal; - -typedef struct TotalFund { - int64_t totalFund; - int64_t totalActiveBets; - int64_t totalCashout; - int64_t totalRekt; - int64_t totalEquity; - - TotalFund() { - totalFund = totalActiveBets = totalCashout = totalRekt = totalEquity = 0; - } - -} TotalFund; - -int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t &profits, int64_t &outprice); -static bool prices_isacceptableamount(const std::vector &vecparsed, int64_t amount, int16_t leverage); - -// helpers: - -// returns true if there are only digits and no alphas or slashes in 's' -inline bool is_weight_str(std::string s) { - return - std::count_if(s.begin(), s.end(), [](unsigned char c) { return std::isdigit(c); } ) > 0 && - std::count_if(s.begin(), s.end(), [](unsigned char c) { return std::isalpha(c) || c == '/'; } ) == 0; -} - - -// start of consensus code - -CScript prices_betopret(CPubKey mypk,int32_t height,int64_t amount,int16_t leverage,int64_t firstprice,std::vector vec,uint256 tokenid) -{ - CScript opret; - opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << 'B' << mypk << height << amount << leverage << firstprice << vec << tokenid); - return(opret); -} - -uint8_t prices_betopretdecode(CScript scriptPubKey,CPubKey &pk,int32_t &height,int64_t &amount,int16_t &leverage,int64_t &firstprice,std::vector &vec,uint256 &tokenid) -{ - std::vector vopret; uint8_t e,f; - - GetOpReturnData(scriptPubKey,vopret); - if (vopret.size() > 2 && E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> pk; ss >> height; ss >> amount; ss >> leverage; ss >> firstprice; ss >> vec; ss >> tokenid) != 0 && e == EVAL_PRICES && f == 'B') - { - return(f); - } - return(0); -} - -CScript prices_addopret(uint256 bettxid,CPubKey mypk,int64_t amount) -{ - CScript opret; - opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << 'A' << bettxid << mypk << amount); - return(opret); -} - -uint8_t prices_addopretdecode(CScript scriptPubKey,uint256 &bettxid,CPubKey &pk,int64_t &amount) -{ - std::vector vopret; uint8_t e,f; - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> bettxid; ss >> pk; ss >> amount) != 0 && e == EVAL_PRICES && f == 'A' ) - { - return(f); - } - return(0); -} - -CScript prices_costbasisopret(uint256 bettxid,CPubKey mypk,int32_t height,int64_t costbasis) -{ - CScript opret; - opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << 'C' << bettxid << mypk << height << costbasis); - return(opret); -} - -uint8_t prices_costbasisopretdecode(CScript scriptPubKey,uint256 &bettxid,CPubKey &pk,int32_t &height,int64_t &costbasis) -{ - std::vector vopret; uint8_t e,f; - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> bettxid; ss >> pk; ss >> height; ss >> costbasis) != 0 && e == EVAL_PRICES && f == 'C' ) - { - return(f); - } - return(0); -} - -CScript prices_finalopret(bool isRekt, uint256 bettxid, CPubKey pk, int32_t lastheight, int64_t costbasis, int64_t lastprice, int64_t liquidationprice, int64_t equity, int64_t exitfee, uint32_t nonce) -{ - CScript opret; - opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << (isRekt ? 'R' : 'F') << bettxid << pk << lastheight << costbasis << lastprice << liquidationprice << equity << exitfee << nonce); - return(opret); -} - -uint8_t prices_finalopretdecode(CScript scriptPubKey, uint256 &bettxid, CPubKey &pk, int32_t &lastheight, int64_t &costbasis, int64_t &lastprice, int64_t &liquidationprice, int64_t &equity, int64_t &exitfee) -{ - std::vector vopret; uint8_t e,f; - uint32_t nonce; - - GetOpReturnData(scriptPubKey,vopret); - if (vopret.size() > 2 && E_UNMARSHAL(vopret, ss >> e; ss >> f; ss >> bettxid; ss >> pk; ss >> lastheight; ss >> costbasis; ss >> lastprice; ss >> liquidationprice; ss >> equity; ss >> exitfee; if (!ss.eof()) ss >> nonce; ) != 0 && e == EVAL_PRICES && (f == 'F' || f == 'R')) - { - return(f); - } - return(0); -} - -// price opret basic validation and retrieval -static uint8_t PricesCheckOpret(const CTransaction & tx, vscript_t &opret) -{ - if (tx.vout.size() > 0 && GetOpReturnData(tx.vout.back().scriptPubKey, opret) && opret.size() > 2 && opret.begin()[0] == EVAL_PRICES && IS_CHARINSTR(opret.begin()[1], "BACFR")) - return opret.begin()[1]; - else - return (uint8_t)0; -} - -// validate bet tx helper -static bool ValidateBetTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & bettx) -{ - uint256 tokenid; - int64_t positionsize, firstprice; - int32_t firstheight; - int16_t leverage; - CPubKey pk, pricespk; - std::vector vec; - - // check payment cc config: - if ( ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_EARLYTXID_SCRIPTPUB.size() == 0 ) - GetKomodoEarlytxidScriptPub(); - - if (bettx.vout.size() < 6 || bettx.vout.size() > 7) - return eval->Invalid("incorrect vout number for bet tx"); - - vscript_t opret; - if( prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) != 'B') - return eval->Invalid("cannot decode opreturn for bet tx"); - - pricespk = GetUnspendable(cp, 0); - - if (MakeCC1vout(cp->evalcode, bettx.vout[0].nValue, pk) != bettx.vout[0]) - return eval->Invalid("cannot validate vout0 in bet tx with pk from opreturn"); - if (MakeCC1vout(cp->evalcode, bettx.vout[1].nValue, pricespk) != bettx.vout[1]) - return eval->Invalid("cannot validate vout1 in bet tx with global pk"); - if (MakeCC1vout(cp->evalcode, bettx.vout[2].nValue, pricespk) != bettx.vout[2] ) - return eval->Invalid("cannot validate vout2 in bet tx with pk from opreturn"); - // This should be all you need to verify it, maybe also check amount? - if ( bettx.vout[4].scriptPubKey != KOMODO_EARLYTXID_SCRIPTPUB ) - return eval->Invalid("the fee was paid to wrong address."); - - int64_t betamount = bettx.vout[2].nValue; - if (betamount != PRICES_SUBREVSHAREFEE(positionsize)) { - return eval->Invalid("invalid position size in the opreturn"); - } - - // validate if normal inputs are really signed by originator pubkey (someone not cheating with originator pubkey) - CAmount ccOutputs = 0; - for (auto vout : bettx.vout) - if (vout.scriptPubKey.IsPayToCryptoCondition()) - ccOutputs += vout.nValue; - CAmount normalInputs = TotalPubkeyNormalInputs(bettx, pk); - if (normalInputs < ccOutputs) { - return eval->Invalid("bettx normal inputs not signed with pubkey in opret"); - } - - if (leverage > PRICES_MAXLEVERAGE || leverage < -PRICES_MAXLEVERAGE) { - return eval->Invalid("invalid leverage"); - } - - return true; -} - -// validate add funding tx helper -static bool ValidateAddFundingTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & addfundingtx, const CTransaction & vintx) -{ - uint256 bettxid; - int64_t amount; - CPubKey pk, pricespk; - vscript_t vintxOpret; - - // check payment cc config: - if (ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_EARLYTXID_SCRIPTPUB.size() == 0) - GetKomodoEarlytxidScriptPub(); - - if (addfundingtx.vout.size() < 4 || addfundingtx.vout.size() > 5) - return eval->Invalid("incorrect vout number for add funding tx"); - - vscript_t opret; - if (prices_addopretdecode(addfundingtx.vout.back().scriptPubKey, bettxid, pk, amount) != 'A') - return eval->Invalid("cannot decode opreturn for add funding tx"); - - pricespk = GetUnspendable(cp, 0); - uint8_t vintxFuncId = PricesCheckOpret(vintx, vintxOpret); - if (vintxFuncId != 'A' && vintxFuncId != 'B') { // if vintx is bettx - return eval->Invalid("incorrect vintx funcid"); - } - - if (vintxFuncId == 'B' && vintx.GetHash() != bettxid) {// if vintx is bettx - return eval->Invalid("incorrect bet txid in opreturn"); - } - - if (MakeCC1vout(cp->evalcode, addfundingtx.vout[0].nValue, pk) != addfundingtx.vout[0]) - return eval->Invalid("cannot validate vout0 in add funding tx with pk from opreturn"); - if (MakeCC1vout(cp->evalcode, addfundingtx.vout[1].nValue, pricespk) != addfundingtx.vout[1]) - return eval->Invalid("cannot validate vout1 in add funding tx with global pk"); - - // This should be all you need to verify it, maybe also check amount? - if (addfundingtx.vout[2].scriptPubKey != KOMODO_EARLYTXID_SCRIPTPUB) - return eval->Invalid("the fee was paid to wrong address."); - - int64_t betamount = addfundingtx.vout[1].nValue; - if (betamount != PRICES_SUBREVSHAREFEE(amount)) { - return eval->Invalid("invalid bet position size in the opreturn"); - } - - return true; -} - -// validate costbasis tx helper (deprecated) -/* -static bool ValidateCostbasisTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & costbasistx, const CTransaction & bettx) -{ - uint256 bettxid; - int64_t costbasisInOpret; - CPubKey pk, pricespk; - int32_t height; - - return true; //deprecated - - // check basic structure: - if (costbasistx.vout.size() < 3 || costbasistx.vout.size() > 4) - return eval->Invalid("incorrect vout count for costbasis tx"); - - vscript_t opret; - if (prices_costbasisopretdecode(costbasistx.vout.back().scriptPubKey, bettxid, pk, height, costbasisInOpret) != 'C') - return eval->Invalid("cannot decode opreturn for costbasis tx"); - - pricespk = GetUnspendable(cp, 0); - if (CTxOut(costbasistx.vout[0].nValue, CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG) != costbasistx.vout[0]) //might go to any pk who calculated costbasis - return eval->Invalid("cannot validate vout0 in costbasis tx with pk from opreturn"); - if (MakeCC1vout(cp->evalcode, costbasistx.vout[1].nValue, pricespk) != costbasistx.vout[1]) - return eval->Invalid("cannot validate vout1 in costbasis tx with global pk"); - - if (bettx.GetHash() != bettxid) - return eval->Invalid("incorrect bettx id"); - - if (bettx.vout.size() < 1) // for safety and for check encapsulation - return eval->Invalid("incorrect bettx no vouts"); - - // check costbasis rules: - if (costbasistx.vout[0].nValue > bettx.vout[1].nValue / 10) { - return eval->Invalid("costbasis myfee too big"); - } - - uint256 tokenid; - int64_t positionsize, firstprice; - int32_t firstheight; - int16_t leverage; - CPubKey betpk; - std::vector vec; - if (prices_betopretdecode(bettx.vout.back().scriptPubKey, betpk, firstheight, positionsize, leverage, firstprice, vec, tokenid) != 'B') - return eval->Invalid("cannot decode opreturn for bet tx"); - - if (firstheight + PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH > chainActive.Height()) { - return eval->Invalid("cannot calculate costbasis yet"); - } - - int64_t costbasis = 0, profits, lastprice; - int32_t retcode = prices_syntheticprofits(costbasis, firstheight, firstheight + PRICES_DAYWINDOW, leverage, vec, positionsize, profits, lastprice); - if (retcode < 0) - return eval->Invalid("cannot calculate costbasis yet"); - std::cerr << "ValidateCostbasisTx() costbasis=" << costbasis << " costbasisInOpret=" << costbasisInOpret << std::endl; - if (costbasis != costbasisInOpret) { - //std::cerr << "ValidateBetTx() " << "incorrect costbasis value" << std::endl; - return eval->Invalid("incorrect costbasis value"); - } - - return true; -} -*/ - -// validate final tx helper -static bool ValidateFinalTx(struct CCcontract_info *cp, Eval *eval, const CTransaction & finaltx, const CTransaction & bettx) -{ - uint256 bettxid; - int64_t amount; - CPubKey pk, pricespk; - int64_t profits; - int32_t lastheight; - int64_t firstprice, costbasis, lastprice, liquidationprice, equity, fee; - int16_t leverage; - - if (finaltx.vout.size() < 3 || finaltx.vout.size() > 4) { - //std::cerr << "ValidateFinalTx()" << " incorrect vout number for final tx =" << finaltx.vout.size() << std::endl; - return eval->Invalid("incorrect vout number for final tx"); - } - - vscript_t opret; - uint8_t funcId; - if ((funcId = prices_finalopretdecode(finaltx.vout.back().scriptPubKey, bettxid, pk, lastheight, costbasis, lastprice, liquidationprice, equity, fee)) == 0) - return eval->Invalid("cannot decode opreturn for final tx"); - - // check rekt txid mining: -// if( funcId == 'R' && (finaltx.GetHash().begin()[0] != 0 || finaltx.GetHash().begin()[31] != 0) ) -// return eval->Invalid("incorrect rekt txid"); - - if (bettx.GetHash() != bettxid) - return eval->Invalid("incorrect bettx id"); - - pricespk = GetUnspendable(cp, 0); - - if (CTxOut(finaltx.vout[0].nValue, CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG) != finaltx.vout[0]) - return eval->Invalid("cannot validate vout0 in final tx with pk from opreturn"); - - if( finaltx.vout.size() == 3 && MakeCC1vout(cp->evalcode, finaltx.vout[1].nValue, pricespk) != finaltx.vout[1] ) - return eval->Invalid("cannot validate vout1 in final tx with global pk"); - - // TODO: validate exitfee for 'R' - // TODO: validate amount for 'F' - - return true; -} - -// validate prices tx function -// performed checks: -// basic tx structure (vout num) -// basic tx opret structure -// reference to the bet tx vout -// referenced bet txid in tx opret -// referenced bet tx structure -// non-final tx has only 1 cc vin -// cc vouts to self with mypubkey from opret -// cc vouts to global pk with global pk -// for bet tx that normal inputs digned with my pubkey from the opret >= cc outputs - disable betting for other pubkeys (Do we need this rule?) -// TODO: -// opret params (firstprice,positionsize...) -// costbasis calculation -// cashout balance (PricesExactAmounts) -// use the special address for 50% fees -bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) -{ - vscript_t vopret; - - if (strcmp(ASSETCHAINS_SYMBOL, "REKT0") == 0 && chainActive.Height() < 5851) - return true; - // check basic opret rules: - if (PricesCheckOpret(tx, vopret) == 0) - return eval->Invalid("tx has no prices opreturn"); - - uint8_t funcId = vopret.begin()[1]; - - CTransaction firstVinTx; - vscript_t firstVinTxOpret; - bool foundFirst = false; - int32_t ccVinCount = 0; - uint32_t prevCCoutN = 0; - - // check basic rules: - - // find first cc vin and load vintx (might be either bet or add funding tx): - for (auto vin : tx.vin) { - if (cp->ismyvin(vin.scriptSig)) { - CTransaction vintx; - uint256 hashBlock; - vscript_t vintxOpret; - - if (!myGetTransaction(vin.prevout.hash, vintx, hashBlock)) - return eval->Invalid("cannot load vintx"); - - if (PricesCheckOpret(vintx, vintxOpret) == 0) { - //return eval->Invalid("cannot find prices opret in vintx"); - std::cerr << "PricesValidate() " << "cannot find prices opret in vintx" << std::endl; - } - - if (!IS_CHARINSTR(funcId, "FR") && vintxOpret.begin()[1] == 'B' && prevCCoutN == 1) { - //return eval->Invalid("cannot spend bet marker"); - std::cerr << "PricesValidate() " << " non-final tx cannot spend cc marker vout=" << prevCCoutN << std::endl; - } - - if (!foundFirst) { - prevCCoutN = vin.prevout.n; - firstVinTx = vintx; - firstVinTxOpret = vintxOpret; - foundFirst = true; - } - ccVinCount++; - } - } - if (!foundFirst) - return eval->Invalid("prices cc vin not found"); - - if (!IS_CHARINSTR(funcId, "FR") && ccVinCount > 1) {// for all prices tx except final tx only one cc vin is allowed - //return eval->Invalid("only one prices cc vin allowed for this tx"); - std::cerr << "PricesValidate() " << "only one prices cc vin allowed for this tx" << std::endl; - } - - switch (funcId) { - case 'B': // bet - return eval->Invalid("unexpected validate for bet funcid"); - - case 'A': // add funding - // check tx structure: - if (!ValidateAddFundingTx(cp, eval, tx, firstVinTx)) { - std::cerr << "PricesValidate() " << "ValidateAddFundingTx = false " << eval->state.GetRejectReason() << std::endl; - return false; // invalid state is already set in the func - } - - if (firstVinTxOpret.begin()[1] == 'B') { - if (!ValidateBetTx(cp, eval, firstVinTx)) {// check tx structure - std::cerr << "PricesValidate() " << "funcId=A ValidatebetTx = false " << eval->state.GetRejectReason() << std::endl; - return false; // invalid state is already set in the func - } - } - - if (prevCCoutN != 0) { // check spending rules - std::cerr << "PricesValidate() " << "addfunding tx incorrect vout to spend=" << prevCCoutN << std::endl; - return eval->Invalid("incorrect vintx vout to spend"); - } - break; - - /* not used: - case 'C': // set costbasis - if (!ValidateCostbasisTx(cp, eval, tx, firstVinTx)) { - //return false; - std::cerr << "PricesValidate() " << "ValidateCostbasisTx=false " << eval->state.GetRejectReason() << std::endl; - } - if (!ValidateBetTx(cp, eval, firstVinTx)) { - //return false; - std::cerr << "PricesValidate() " << "funcId=C ValidateBetTx=false " << eval->state.GetRejectReason() << std::endl; - } - if (prevoutN != 1) { // check spending rules - // return eval->Invalid("incorrect vout to spend"); - std::cerr << "PricesValidate() " << "costbasis tx incorrect vout to spend=" << prevoutN << std::endl; - } - //return eval->Invalid("test: costbasis is good"); - break; */ - - case 'F': // final tx - case 'R': - if (!ValidateFinalTx(cp, eval, tx, firstVinTx)) { - std::cerr << "PricesValidate() " << "ValidateFinalTx=false " << eval->state.GetRejectReason() << std::endl; - return false; - } - if (!ValidateBetTx(cp, eval, firstVinTx)) { - std::cerr << "PricesValidate() " << "ValidateBetTx=false " << eval->state.GetRejectReason() << std::endl; - return false; - } - if (prevCCoutN != 1) { // check spending rules - std::cerr << "PricesValidate() "<< "final tx incorrect vout to spend=" << prevCCoutN << std::endl; - return eval->Invalid("incorrect vout to spend"); - } - break; - - default: - return eval->Invalid("invalid funcid"); - } - - eval->state = CValidationState(); - return true; -} -// end of consensus code - -// helper functions for rpc calls in rpcwallet.cpp - -int64_t AddPricesInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, char *destaddr, int64_t total, int32_t maxinputs) -{ - int64_t nValue, price, totalinputs = 0; uint256 txid, hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout, n = 0; - std::vector > unspentOutputs; - - SetCCunspents(unspentOutputs, destaddr); - for (std::vector >::const_iterator it = unspentOutputs.begin(); it != unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - //if (vout == exclvout && txid == excltxid) // exclude vout which is added directly to vins outside this function - // continue; - if (myGetTransaction(txid, vintx, hashBlock) != 0 && vout < vintx.vout.size()) - { - vscript_t vopret; - uint8_t funcId = PricesCheckOpret(vintx, vopret); - if (funcId == 'B' && vout == 1) // skip cc marker - continue; - - if ((nValue = vintx.vout[vout].nValue) >= total / maxinputs && myIsutxo_spentinmempool(ignoretxid, ignorevin, txid, vout) == 0) - { - if (total != 0 && maxinputs != 0) - mtx.vin.push_back(CTxIn(txid, vout, CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; - n++; - if ((total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs)) - break; - } - } - } - return(totalinputs); -} - -// return min equity percentage depending on leverage value -// for lev=1 2% -// for lev>=100 10% -double prices_minmarginpercent(int16_t leverage) -{ - int16_t absleverage = std::abs(leverage); - if (absleverage < 100) - return (absleverage * 0.080808 + 1.9191919) / 100.0; - else - return 0.1; -} - - -UniValue prices_rawtxresult(UniValue &result, std::string rawtx, int32_t broadcastflag) -{ - CTransaction tx; - if (rawtx.size() > 0) - { - result.push_back(Pair("hex", rawtx)); - if (DecodeHexTx(tx, rawtx) != 0) - { - if (broadcastflag != 0 && myAddtomempool(tx) != 0) - RelayTransaction(tx); - result.push_back(Pair("txid", tx.GetHash().ToString())); - result.push_back(Pair("result", "success")); - } - else - result.push_back(Pair("error", "decode hex")); - } - else - result.push_back(Pair("error", "couldnt finalize CCtx")); - return(result); -} - -static std::string prices_getsourceexpression(const std::vector &vec) { - - std::string expr; - - for (int32_t i = 0; i < vec.size(); i++) - { - char name[65]; - std::string operand; - uint16_t opcode = vec[i]; - int32_t value = (opcode & (KOMODO_MAXPRICES - 1)); // index or weight - - switch (opcode & KOMODO_PRICEMASK) - { - case 0: // indices - komodo_pricename(name, value); - operand = std::string(name); - break; - - case PRICES_WEIGHT: // multiply by weight and consume top of stack by updating price - operand = std::to_string(value); - break; - - case PRICES_MULT: // "*" - operand = std::string("*"); - break; - - case PRICES_DIV: // "/" - operand = std::string("/"); - break; - - case PRICES_INV: // "!" - operand = std::string("!"); - break; - - case PRICES_MDD: // "*//" - operand = std::string("*//"); - break; - - case PRICES_MMD: // "**/" - operand = std::string("**/"); - break; - - case PRICES_MMM: // "***" - operand = std::string("***"); - break; - - case PRICES_DDD: // "///" - operand = std::string("///"); - break; - - default: - return "invalid opcode"; - break; - } - - if (expr.size() > 0) - expr += std::string(", "); - expr += operand; - } - return expr; -} - -// helper functions to get synthetic expression reduced: - -// return s true and needed operand count if string is opcode -static bool prices_isopcode(const std::string &s, int &need) -{ - if (s == "!") { - need = 1; - return true; - } - else if (s == "*" || s == "/") { - need = 2; - return true; - } - else if (s == "***" || s == "///" || s == "*//" || s == "**/") { - need = 3; - return true; - } - else - return false; -} - -// split pair onto two quotes divided by "_" -static void prices_splitpair(const std::string &pair, std::string &upperquote, std::string &bottomquote) -{ - size_t pos = pair.find('_'); // like BTC_USD - if (pos != std::string::npos) { - upperquote = pair.substr(0, pos); - bottomquote = pair.substr(pos + 1); - } - else { - upperquote = pair; - bottomquote = ""; - } - //std::cerr << "prices_splitpair: upperquote=" << upperquote << " bottomquote=" << bottomquote << std::endl; -} - -// invert pair like BTS_USD -> USD_BTC -static std::string prices_invertpair(const std::string &pair) -{ - std::string upperquote, bottomquote; - prices_splitpair(pair, upperquote, bottomquote); - return bottomquote + std::string("_") + upperquote; -} - -// invert pairs in operation accordingly to "/" operator, convert operator to * or *** -static void prices_invertoperation(const std::vector &vexpr, int p, std::vector &voperation) -{ - int need; - - voperation.clear(); - if (prices_isopcode(vexpr[p], need)) { - if (need > 1) { - if (need == 2) { - voperation.push_back(vexpr[p - 2]); - if (vexpr[p] == "/") - voperation.push_back(prices_invertpair(vexpr[p - 1])); - else - voperation.push_back(vexpr[p - 1]); - voperation.push_back("*"); - } - - if (need == 3) { - int i; - std::string::const_iterator c; - for (c = vexpr[p].begin(), i = -3; c != vexpr[p].end(); c++, i++) { - if (*c == '/') - voperation.push_back(prices_invertpair(vexpr[p + i])); - else - voperation.push_back(vexpr[p + i]); - } - voperation.push_back("***"); - } - } - else if (vexpr[p] == "!") { - voperation.push_back(prices_invertpair(vexpr[p - 1])); - // do not add operator - } - } - - //std::cerr << "prices_invert inverted="; - //for (auto v : voperation) std::cerr << v << " "; - //std::cerr << std::endl; -} - -// reduce pairs in the operation, change or remove opcode if reduced -static int prices_reduceoperands(std::vector &voperation) -{ - int opcount = voperation.size() - 1; - int need = opcount; - //std::cerr << "prices_reduceoperands begin need=" << need << std::endl; - - while (true) { - int i; - //std::cerr << "prices_reduceoperands opcount=" << opcount << std::endl; - for (i = 0; i < opcount; i++) { - std::string upperquote, bottomquote; - bool breaktostart = false; - - //std::cerr << "prices_reduceoperands voperation[i]=" << voperation[i] << " i=" << i << std::endl; - prices_splitpair(voperation[i], upperquote, bottomquote); - if (upperquote == bottomquote) { - std::cerr << "prices_reduceoperands erasing i=" << i << std::endl; - voperation.erase(voperation.begin() + i); - opcount--; - //std::cerr << "prices_reduceoperands erased, size=" << voperation.size() << std::endl; - - if (voperation.size() > 0 && voperation.back() == "*") - voperation.pop_back(); - breaktostart = true; - break; - } - - - int j; - for (j = i + 1; j < opcount; j++) { - - //std::cerr << "prices_reduceoperands voperation[j]=" << voperation[j] << " j=" << j << std::endl; - - std::string upperquotej, bottomquotej; - prices_splitpair(voperation[j], upperquotej, bottomquotej); - if (upperquote == bottomquotej || bottomquote == upperquotej) { - if (upperquote == bottomquotej) - voperation[i] = upperquotej + "_" + bottomquote; - else - voperation[i] = upperquote + "_" + bottomquotej; - //std::cerr << "prices_reduceoperands erasing j=" << j << std::endl; - voperation.erase(voperation.begin() + j); - opcount--; - //std::cerr << "prices_reduceoperands erased, size=" << voperation.size() << std::endl; - - need--; - if (voperation.back() == "***") { - voperation.pop_back(); - voperation.push_back("*"); // convert *** to * - } - else if (voperation.back() == "*") { - voperation.pop_back(); // convert * to nothing - } - breaktostart = true; - break; - } - } - if (breaktostart) - break; - } - if (i >= opcount) // all seen - break; - } - - //std::cerr << "prices_reduceoperands end need=" << need << std::endl; - return need; -} - -// substitute reduced operation in vectored expr -static void prices_substitutereduced(std::vector &vexpr, int p, std::vector voperation) -{ - int need; - if (prices_isopcode(vexpr[p], need)) { - vexpr.erase(vexpr.begin() + p - need, vexpr.begin() + p + 1); - vexpr.insert(vexpr.begin() + p - need, voperation.begin(), voperation.end()); - } -} - -// try to reduce synthetic expression by substituting "BTC_USD, BTC_EUR, 30, /" with "EUR_USD, 30" etc -static std::string prices_getreducedexpr(const std::string &expr) -{ - std::string reduced; - - std::vector vexpr; - SplitStr(expr, vexpr); - - for (size_t i = 0; i < vexpr.size(); i++) { - int need; - - if (prices_isopcode(vexpr[i], need)) { - std::vector voperation; - prices_invertoperation(vexpr, i, voperation); - if (voperation.size() > 0) { - int reducedneed = prices_reduceoperands(voperation); - if (reducedneed < need) { - prices_substitutereduced(vexpr, i, voperation); - } - } - } - } - - for (size_t i = 0; i < vexpr.size(); i++) { - if (reduced.size() > 0) - reduced += std::string(", "); - reduced += vexpr[i]; - } - - //std::cerr << "reduced=" << reduced << std::endl; - return reduced; -} - -// parse synthetic expression into vector of codes -int32_t prices_syntheticvec(std::vector &vec, std::vector synthetic) -{ - int32_t i, need, ind, depth = 0; std::string opstr; uint16_t opcode, weight; - if (synthetic.size() == 0) { - std::cerr << "prices_syntheticvec() expression is empty" << std::endl; - return(-1); - } - for (i = 0; i < synthetic.size(); i++) - { - need = 0; - opstr = synthetic[i]; - if (opstr == "*") - opcode = PRICES_MULT, need = 2; - else if (opstr == "/") - opcode = PRICES_DIV, need = 2; - else if (opstr == "!") - opcode = PRICES_INV, need = 1; - else if (opstr == "**/") - opcode = PRICES_MMD, need = 3; - else if (opstr == "*//") - opcode = PRICES_MDD, need = 3; - else if (opstr == "***") - opcode = PRICES_MMM, need = 3; - else if (opstr == "///") - opcode = PRICES_DDD, need = 3; - else if (!is_weight_str(opstr) && (ind = komodo_priceind(opstr.c_str())) >= 0) - opcode = ind, need = 0; - else if ((weight = atoi(opstr.c_str())) > 0 && weight < KOMODO_MAXPRICES) - { - opcode = PRICES_WEIGHT | weight; - need = 1; - } - else { - std::cerr << "prices_syntheticvec() incorrect opcode=" << opstr << std::endl; - return(-2); - } - if (depth < need) { - std::cerr << "prices_syntheticvec() incorrect not enough operands for opcode=" << opstr << std::endl; - return(-3); - } - depth -= need; - ///std::cerr << "prices_syntheticvec() opcode=" << opcode << " opstr=" << opstr << " need=" << need << " depth=" << depth << std::endl; - if ((opcode & KOMODO_PRICEMASK) != PRICES_WEIGHT) { // skip weight - depth++; // increase operands count - ///std::cerr << "depth++=" << depth << std::endl; - } - if (depth > 3) { - std::cerr << "prices_syntheticvec() too many operands, last=" << opstr << std::endl; - return(-4); - } - vec.push_back(opcode); - } - if (depth != 0) - { - LogPrintf( "prices_syntheticvec() depth.%d not empty\n", depth); - return(-5); - } - return(0); -} - -// calculates price for synthetic expression -int64_t prices_syntheticprice(std::vector vec, int32_t height, int32_t minmax, int16_t leverage) -{ - int32_t i, value, errcode, depth, retval = -1; - uint16_t opcode; - int64_t *pricedata, pricestack[4], a, b, c; - - mpz_t mpzTotalPrice, mpzPriceValue, mpzDen, mpzA, mpzB, mpzC, mpzResult; - - mpz_init(mpzTotalPrice); - mpz_init(mpzPriceValue); - mpz_init(mpzDen); - - mpz_init(mpzA); - mpz_init(mpzB); - mpz_init(mpzC); - mpz_init(mpzResult); - - pricedata = (int64_t *)calloc(sizeof(*pricedata) * 3, 1 + PRICES_DAYWINDOW * 2 + PRICES_SMOOTHWIDTH); - depth = errcode = 0; - mpz_set_si(mpzTotalPrice, 0); - mpz_set_si(mpzDen, 0); - - for (i = 0; i < vec.size(); i++) - { - opcode = vec[i]; - value = (opcode & (KOMODO_MAXPRICES - 1)); // index or weight - - mpz_set_ui(mpzResult, 0); // clear result to test overflow (see below) - - //std::cerr << "prices_syntheticprice" << " i=" << i << " mpzTotalPrice=" << mpz_get_si(mpzTotalPrice) << " value=" << value << " depth=" << depth << " opcode&KOMODO_PRICEMASK=" << (opcode & KOMODO_PRICEMASK) <= 0) - { - //std::cerr << "prices_syntheticprice" << " pricedata[0]=" << pricedata[0] << " pricedata[1]=" << pricedata[1] << " pricedata[2]=" << pricedata[2] << std::endl; - // push price to the prices stack - /*if (!minmax) - pricestack[depth] = pricedata[2]; // use smoothed value if we are over 24h - else - { - // if we are within 24h use min or max price - if (leverage > 0) - pricestack[depth] = (pricedata[1] > pricedata[2]) ? pricedata[1] : pricedata[2]; // MAX - else - pricestack[depth] = (pricedata[1] < pricedata[2]) ? pricedata[1] : pricedata[2]; // MIN - }*/ - pricestack[depth] = pricedata[2]; - } - else - errcode = -1; - - if (pricestack[depth] == 0) - errcode = -14; - - depth++; - break; - - case PRICES_WEIGHT: // multiply by weight and consume top of stack by updating price - if (depth == 1) { - depth--; - // price += pricestack[0] * value; - mpz_set_si(mpzPriceValue, pricestack[0]); - mpz_mul_si(mpzPriceValue, mpzPriceValue, value); - mpz_add(mpzTotalPrice, mpzTotalPrice, mpzPriceValue); // accumulate weight's value - - // den += value; - mpz_add_ui(mpzDen, mpzDen, (uint64_t)value); // accumulate weight's value - } - else - errcode = -2; - break; - - case PRICES_MULT: // "*" - if (depth >= 2) { - b = pricestack[--depth]; - a = pricestack[--depth]; - // pricestack[depth++] = (a * b) / SATOSHIDEN; - mpz_set_si(mpzA, a); - mpz_set_si(mpzB, b); - mpz_mul(mpzResult, mpzA, mpzB); - mpz_tdiv_q_ui(mpzResult, mpzResult, SATOSHIDEN); - pricestack[depth++] = mpz_get_si(mpzResult); - - } - else - errcode = -3; - break; - - case PRICES_DIV: // "/" - if (depth >= 2) { - b = pricestack[--depth]; - a = pricestack[--depth]; - // pricestack[depth++] = (a * SATOSHIDEN) / b; - mpz_set_si(mpzA, a); - mpz_set_si(mpzB, b); - mpz_mul_ui(mpzResult, mpzA, SATOSHIDEN); - mpz_tdiv_q(mpzResult, mpzResult, mpzB); - pricestack[depth++] = mpz_get_si(mpzResult); - } - else - errcode = -4; - break; - - case PRICES_INV: // "!" - if (depth >= 1) { - a = pricestack[--depth]; - // pricestack[depth++] = (SATOSHIDEN * SATOSHIDEN) / a; - mpz_set_si(mpzA, a); - mpz_set_ui(mpzResult, SATOSHIDEN); - mpz_mul_ui(mpzResult, mpzResult, SATOSHIDEN); - mpz_tdiv_q(mpzResult, mpzResult, mpzA); - pricestack[depth++] = mpz_get_si(mpzResult); - } - else - errcode = -5; - break; - - case PRICES_MDD: // "*//" - if (depth >= 3) { - c = pricestack[--depth]; - b = pricestack[--depth]; - a = pricestack[--depth]; - // pricestack[depth++] = (((a * SATOSHIDEN) / b) * SATOSHIDEN) / c; - mpz_set_si(mpzA, a); - mpz_set_si(mpzB, b); - mpz_set_si(mpzC, c); - mpz_mul_ui(mpzResult, mpzA, SATOSHIDEN); - mpz_tdiv_q(mpzResult, mpzResult, mpzB); - mpz_mul_ui(mpzResult, mpzResult, SATOSHIDEN); - mpz_tdiv_q(mpzResult, mpzResult, mpzC); - pricestack[depth++] = mpz_get_si(mpzResult); - } - else - errcode = -6; - break; - - case PRICES_MMD: // "**/" - if (depth >= 3) { - c = pricestack[--depth]; - b = pricestack[--depth]; - a = pricestack[--depth]; - // pricestack[depth++] = (a * b) / c; - mpz_set_si(mpzA, a); - mpz_set_si(mpzB, b); - mpz_set_si(mpzC, c); - mpz_mul(mpzResult, mpzA, mpzB); - mpz_tdiv_q(mpzResult, mpzResult, mpzC); - pricestack[depth++] = mpz_get_si(mpzResult); - } - else - errcode = -7; - break; - - case PRICES_MMM: // "***" - if (depth >= 3) { - c = pricestack[--depth]; - b = pricestack[--depth]; - a = pricestack[--depth]; - // pricestack[depth++] = (((a * b) / SATOSHIDEN ) * c) / SATOSHIDEN; - mpz_set_si(mpzA, a); - mpz_set_si(mpzB, b); - mpz_set_si(mpzC, c); - mpz_mul(mpzResult, mpzA, mpzB); - mpz_tdiv_q_ui(mpzResult, mpzResult, SATOSHIDEN); - mpz_mul(mpzResult, mpzResult, mpzC); - mpz_tdiv_q_ui(mpzResult, mpzResult, SATOSHIDEN); - pricestack[depth++] = mpz_get_si(mpzResult); - } - else - errcode = -8; - break; - - case PRICES_DDD: // "///" - if (depth >= 3) { - c = pricestack[--depth]; - b = pricestack[--depth]; - a = pricestack[--depth]; - //pricestack[depth++] = (((((SATOSHIDEN * SATOSHIDEN) / a) * SATOSHIDEN) / b) * SATOSHIDEN) / c; - mpz_set_si(mpzA, a); - mpz_set_si(mpzB, b); - mpz_set_si(mpzC, c); - mpz_set_ui(mpzResult, SATOSHIDEN); - mpz_mul_ui(mpzResult, mpzResult, SATOSHIDEN); - mpz_tdiv_q(mpzResult, mpzResult, mpzA); - mpz_mul_ui(mpzResult, mpzResult, SATOSHIDEN); - mpz_tdiv_q(mpzResult, mpzResult, mpzB); - mpz_mul_ui(mpzResult, mpzResult, SATOSHIDEN); - mpz_tdiv_q(mpzResult, mpzResult, mpzC); - pricestack[depth++] = mpz_get_si(mpzResult); - } - else - errcode = -9; - break; - - default: - errcode = -10; - break; - } - - // std::cerr << "prices_syntheticprice test mpzResult=" << mpz_get_si(mpzResult) << std::endl; - // check overflow: - if (mpz_cmp_si(mpzResult, std::numeric_limits::max()) > 0) { - errcode = -13; - break; - } - - if (errcode != 0) - break; - - // if( depth > 0 ) - // std::cerr << "prices_syntheticprice top pricestack[depth-1=" << depth-1 << "]=" << pricestack[depth-1] << std::endl; - // else - // std::cerr << "prices_syntheticprice pricestack empty" << std::endl; - - } - free(pricedata); - mpz_clear(mpzResult); - mpz_clear(mpzA); - mpz_clear(mpzB); - mpz_clear(mpzC); - - if( mpz_get_si(mpzDen) != 0 ) - mpz_tdiv_q(mpzTotalPrice, mpzTotalPrice, mpzDen); // price / den - - int64_t den = mpz_get_si(mpzDen); - int64_t priceIndex = mpz_get_si(mpzTotalPrice); - - mpz_clear(mpzDen); - mpz_clear(mpzTotalPrice); - mpz_clear(mpzPriceValue); - - if (errcode != 0) - std::cerr << "prices_syntheticprice errcode in switch=" << errcode << std::endl; - - if( errcode == -1 ) { - std::cerr << "prices_syntheticprice error getting price (could be end of chain)" << std::endl; - return errcode; - } - - if (errcode == -13) { - std::cerr << "prices_syntheticprice overflow in price" << std::endl; - return errcode; - } - if (errcode == -14) { - std::cerr << "prices_syntheticprice price is zero, not enough historic data yet" << std::endl; - return errcode; - } - if (den == 0) { - std::cerr << "prices_syntheticprice den==0 return err=-11" << std::endl; - return(-11); - } - else if (depth != 0) { - std::cerr << "prices_syntheticprice depth!=0 err=-12" << std::endl; - return(-12); - } - else if (errcode != 0) { - std::cerr << "prices_syntheticprice err=" << errcode << std::endl; - return(errcode); - } -// std::cerr << "prices_syntheticprice priceIndex=totalprice/den=" << priceIndex << " den=" << den << std::endl; - - return priceIndex; -} - -// calculates costbasis and profit/loss for the bet -int32_t prices_syntheticprofits(int64_t &costbasis, int32_t firstheight, int32_t height, int16_t leverage, std::vector vec, int64_t positionsize, int64_t &profits, int64_t &outprice) -{ - int64_t price; -#ifndef TESTMODE - const int32_t COSTBASIS_PERIOD = PRICES_DAYWINDOW; -#else - const int32_t COSTBASIS_PERIOD = 7; -#endif - - - if (height < firstheight) { - LogPrintf( "requested height is lower than bet firstheight.%d\n", height); - return -1; - } - - int32_t minmax = (height < firstheight + COSTBASIS_PERIOD); // if we are within 24h then use min or max value - - if ((price = prices_syntheticprice(vec, height, minmax, leverage)) < 0) - { - LogPrintf( "error getting synthetic price at height.%d\n", height); - return -1; - } - - // clear lowest positions: - //price /= PRICES_POINTFACTOR; - //price *= PRICES_POINTFACTOR; - outprice = price; - - if (minmax) { // if we are within day window, set temp costbasis to max (or min) price value - if (leverage > 0 && price > costbasis) { - costbasis = price; // set temp costbasis - //std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << std::endl; - } - else if (leverage < 0 && (costbasis == 0 || price < costbasis)) { - costbasis = price; - //std::cerr << "prices_syntheticprofits() minmax costbasis=" << costbasis << std::endl; - } - //else { //-> use the previous value - // std::cerr << "prices_syntheticprofits() unchanged costbasis=" << costbasis << " price=" << price << " leverage=" << leverage << std::endl; - //} - } - else { - //if (height == firstheight + COSTBASIS_PERIOD) { - // if costbasis not set, just set it - //costbasis = price; - - // use calculated minmax costbasis - //std::cerr << "prices_syntheticprofits() use permanent costbasis=" << costbasis << " at height=" << height << std::endl; - //} - } - - // normalize to 10,000,000 to prevent underflow - //profits = costbasis > 0 ? (((price / PRICES_POINTFACTOR * PRICES_NORMFACTOR) / costbasis) - PRICES_NORMFACTOR / PRICES_POINTFACTOR) * PRICES_POINTFACTOR : 0; - //double dprofits = costbasis > 0 ? ((double)price / (double)costbasis - 1) : 0; - - //std::cerr << "prices_syntheticprofits() test value1 (price/PRICES_POINTFACTOR * PRICES_NORMFACTOR)=" << (price / PRICES_POINTFACTOR * PRICES_NORMFACTOR) << std::endl; - //std::cerr << "prices_syntheticprofits() test value2 (price/PRICES_POINTFACTOR * PRICES_NORMFACTOR)/costbasis=" << (costbasis != 0 ? (price / PRICES_POINTFACTOR * PRICES_NORMFACTOR)/costbasis : 0) << std::endl; - - //std::cerr << "prices_syntheticprofits() fractional profits=" << profits << std::endl; - //std::cerr << "prices_syntheticprofits() profits double=" << (double)price / (double)costbasis -1.0 << std::endl; - //double dprofits = (double)price / (double)costbasis - 1.0; - - //profits *= ((int64_t)leverage * (int64_t)positionsize); - //profits /= (int64_t)PRICES_NORMFACTOR; // de-normalize - - //dprofits *= ((double)leverage * (double)positionsize); - - //dprofits *= leverage * positionsize; - // profits = dprofits; - //std::cerr << "prices_syntheticprofits() dprofits=" << dprofits << std::endl; - - if (costbasis > 0) { - mpz_t mpzProfits; - mpz_t mpzCostbasis; - mpz_t mpzPrice; - mpz_t mpzLeverage; - - mpz_init(mpzProfits); - mpz_init(mpzCostbasis); - mpz_init(mpzPrice); - mpz_init(mpzLeverage); - - mpz_set_si(mpzCostbasis, costbasis); - mpz_set_si(mpzPrice, price); - mpz_mul_ui(mpzPrice, mpzPrice, SATOSHIDEN); // (price*SATOSHIDEN) - - mpz_tdiv_q(mpzProfits, mpzPrice, mpzCostbasis); // profits = (price*SATOSHIDEN)/costbasis // normalization - mpz_sub_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits -= SATOSHIDEN - - mpz_set_si(mpzLeverage, leverage); - mpz_mul(mpzProfits, mpzProfits, mpzLeverage); // profits *= leverage - mpz_mul_ui(mpzProfits, mpzProfits, positionsize); // profits *= positionsize - mpz_tdiv_q_ui(mpzProfits, mpzProfits, SATOSHIDEN); // profits /= SATOSHIDEN // de-normalization - - profits = mpz_get_si(mpzProfits); - - mpz_clear(mpzLeverage); - mpz_clear(mpzProfits); - mpz_clear(mpzCostbasis); - mpz_clear(mpzPrice); - - } - else - profits = 0; - - //std::cerr << "prices_syntheticprofits() profits=" << profits << std::endl; - return 0; // (positionsize + addedbets + profits); -} - -// makes result json object -void prices_betjson(UniValue &result, std::vector bets, int16_t leverage, int32_t endheight, int64_t lastprice) -{ - - UniValue resultbets(UniValue::VARR); - int64_t totalposition = 0; - int64_t totalprofits = 0; - - for (auto b : bets) { - UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("positionsize", ValueFromAmount(b.positionsize))); - entry.push_back(Pair("profits", ValueFromAmount(b.profits))); - entry.push_back(Pair("costbasis", ValueFromAmount(b.costbasis))); - entry.push_back(Pair("firstheight", b.firstheight)); - resultbets.push_back(entry); - totalposition += b.positionsize; - totalprofits += b.profits; - } - int64_t equity = totalposition + totalprofits; - - result.push_back(Pair("bets", resultbets)); - result.push_back(Pair("leverage", (int64_t)leverage)); - result.push_back(Pair("TotalPositionSize", ValueFromAmount(totalposition))); - result.push_back(Pair("TotalProfits", ValueFromAmount(totalprofits))); - result.push_back(Pair("equity", ValueFromAmount(equity))); - result.push_back(Pair("LastPrice", ValueFromAmount(lastprice))); - result.push_back(Pair("LastHeight", endheight)); -} - -// retrieves costbasis from a tx spending bettx vout1 (deprecated) -int64_t prices_costbasis(CTransaction bettx, uint256 &txidCostbasis) -{ - int64_t costbasis = 0; - // if vout1 is spent, follow and extract costbasis from opreturn - //uint8_t prices_costbasisopretdecode(CScript scriptPubKey,uint256 &bettxid,CPubKey &pk,int32_t &height,int64_t &costbasis) - //uint256 txidCostbasis; - int32_t vini; - int32_t height; - txidCostbasis = zeroid; -/* - if (CCgetspenttxid(txidCostbasis, vini, height, bettx.GetHash(), 1) < 0) { - std::cerr << "prices_costbasis() no costbasis txid found" << std::endl; - return 0; - } - - CTransaction txCostbasis; - uint256 hashBlock; - uint256 bettxid; - CPubKey pk; - bool isLoaded = false; - uint8_t funcId = 0; - - if ((isLoaded = myGetTransaction(txidCostbasis, txCostbasis, hashBlock)) && - txCostbasis.vout.size() > 0 && - (funcId = prices_costbasisopretdecode(txCostbasis.vout.back().scriptPubKey, bettxid, pk, height, costbasis)) != 0) { - return costbasis; - } - - std::cerr << "prices_costbasis() cannot load costbasis tx or decode opret" << " isLoaded=" << isLoaded << " funcId=" << (int)funcId << std::endl; */ - return 0; -} - -// enumerates and retrieves added bets, returns the last baton txid -int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, uint256 bettxid) -{ - int64_t addedBetsTotal = 0; - int32_t vini; - int32_t height; - int32_t retcode; - - batontxid = bettxid; // initially set to the source bet tx - uint256 sourcetxid = bettxid; - - // iterate through batons, adding up vout1 -> addedbets - while ((retcode = CCgetspenttxid(batontxid, vini, height, sourcetxid, 0)) == 0) { - - CTransaction txBaton; - CBlockIndex blockIdx; - uint256 bettxidInOpret; - CPubKey pk; - bool isLoaded = false; - uint8_t funcId = 0; - int64_t amount; - EvalRef eval; - - if ((isLoaded = eval->GetTxConfirmed(batontxid, txBaton, blockIdx)) && - blockIdx.IsValid() && - txBaton.vout.size() > 0 && - (funcId = prices_addopretdecode(txBaton.vout.back().scriptPubKey, bettxidInOpret, pk, amount)) != 0) - { - OneBetData added; - - addedBetsTotal += amount; - added.positionsize = amount; - added.firstheight = blockIdx.nHeight; //TODO: check if this is correct (to get height from the block not from the opret) - bets.push_back(added); - //std::cerr << "prices_batontxid() added amount=" << amount << std::endl; - } - else { - std::cerr << "prices_batontxid() cannot load or decode add bet tx, isLoaded=" << isLoaded << " funcId=" << (int)funcId << std::endl; - return -1; - } - sourcetxid = batontxid; - } - - return(addedBetsTotal); -} - -// pricesbet rpc impl: make betting tx -UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector synthetic) -{ - int32_t nextheight = komodo_nextheight(); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp, C; - CPubKey pricespk, mypk; - int64_t betamount, firstprice = 0; - std::vector vec; - //char myaddr[64]; - std::string rawtx; - - if (leverage > PRICES_MAXLEVERAGE || leverage < -PRICES_MAXLEVERAGE) - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "leverage too big")); - return(result); - } - cp = CCinit(&C, EVAL_PRICES); - if (txfee == 0) - txfee = PRICES_TXFEE; - mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp, 0); - //GetCCaddress(cp, myaddr, mypk); - if (prices_syntheticvec(vec, synthetic) < 0 || (firstprice = prices_syntheticprice(vec, nextheight - 1, 1, leverage)) < 0 || vec.size() == 0 || vec.size() > 4096) - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "invalid synthetic")); - return(result); - } - - if (!prices_isacceptableamount(vec, amount, leverage)) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "too big amount and leverage")); - return(result); - } - - if (AddNormalinputs(mtx, mypk, amount + 4 * txfee, 64) >= amount + 4 * txfee) - { - betamount = PRICES_SUBREVSHAREFEE(amount); - - /*if( amount - betamount < PRICES_REVSHAREDUST) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "bet amount too small")); - return(result); - }*/ - - - mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, mypk)); // vout0 baton for total funding - // mtx.vout.push_back(MakeCC1vout(cp->evalcode, (amount - betamount) + 2 * txfee, pricespk)); // vout1, when spent, costbasis is set - mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, pricespk)); // vout1 cc marker (NVOUT_CCMARKER) - mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // vout2 betamount - mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); // vout3 normal marker NVOUT_NORMALMARKER - TODO: remove it as we have cc marker now, when move to the new chain - if ( ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_EARLYTXID_SCRIPTPUB.size() == 0 ) - { - // Lock here, as in validation we cannot call lock in the function itself. - // may not be needed as the validation call to update the global, is called in a LOCK already, and it can only update there and here. - LOCK(cs_main); - GetKomodoEarlytxidScriptPub(); - } - mtx.vout.push_back(CTxOut(amount-betamount, KOMODO_EARLYTXID_SCRIPTPUB)); - //test: mtx.vout.push_back(CTxOut(amount - betamount, CScript() << ParseHex("037c803ec82d12da939ac04379bbc1130a9065c53d8244a61eece1db942cf0efa7") << OP_CHECKSIG)); // vout4 test revshare fee - - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_betopret(mypk, nextheight - 1, amount, leverage, firstprice, vec, zeroid)); - return(prices_rawtxresult(result, rawtx, 0)); - } - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "not enough funds")); - return(result); -} - -// pricesaddfunding rpc impl: add yet another bet -UniValue PricesAddFunding(int64_t txfee, uint256 bettxid, int64_t amount) -{ - int32_t nextheight = komodo_nextheight(); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp, C; - CTransaction bettx; - CPubKey pricespk, mypk, pk; - int64_t positionsize, betamount, firstprice; - int32_t firstheight; - std::vector vecparsed; - uint256 batontxid, tokenid, hashBlock; - int16_t leverage = 0; - std::string rawtx; - //char myaddr[64]; - - cp = CCinit(&C, EVAL_PRICES); - if (txfee == 0) - txfee = PRICES_TXFEE; - mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp, 0); - - if (!myGetTransaction(bettxid, bettx, hashBlock) || - bettx.vout.size() <= 3 || - hashBlock.IsNull() || - prices_betopretdecode(bettx.vout.back().scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vecparsed, tokenid) != 'B') { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "invalid bet tx")); - return(result); - } - - if (!prices_isacceptableamount(vecparsed, amount, leverage)) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "too big amount and leverage")); - return(result); - } - - if (AddNormalinputs(mtx, mypk, amount + 2*txfee, 64) >= amount + 2*txfee) - { - betamount = PRICES_SUBREVSHAREFEE(amount); - /*if (amount - betamount < PRICES_REVSHAREDUST) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "bet amount too small")); - return(result); - }*/ - - std::vector bets; - if (prices_enumaddedbets(batontxid, bets, bettxid) >= 0) - { - mtx.vin.push_back(CTxIn(batontxid, 0, CScript())); - mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, mypk)); // vout0 baton for total funding - mtx.vout.push_back(MakeCC1vout(cp->evalcode, betamount, pricespk)); // vout1 added amount - - if (ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_EARLYTXID_SCRIPTPUB.size() == 0) - { - // Lock here, as in validation we cannot call lock in the function itself. - // may not be needed as the validation call to update the global, is called in a LOCK already, and it can only update there and here. - LOCK(cs_main); - GetKomodoEarlytxidScriptPub(); - } - mtx.vout.push_back(CTxOut(amount - betamount, KOMODO_EARLYTXID_SCRIPTPUB)); - // test: mtx.vout.push_back(CTxOut(amount - betamount, CScript() << ParseHex("037c803ec82d12da939ac04379bbc1130a9065c53d8244a61eece1db942cf0efa7") << OP_CHECKSIG)); //vout2 test revshare fee - - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_addopret(bettxid, mypk, amount)); - return(prices_rawtxresult(result, rawtx, 0)); - } - else - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "couldnt find batonttxid")); - return(result); - } - } - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "not enough funds")); - return(result); -} - -// scan chain from the initial bet's first position upto the chain tip and calculate bet's costbasises and profits, breaks if rekt detected -int32_t prices_scanchain(std::vector &bets, int16_t leverage, std::vector vec, int64_t &lastprice, int32_t &endheight) { - - if (bets.size() == 0) - return -1; - - bool stop = false; - for (int32_t height = bets[0].firstheight+1; ; height++) // the last datum for 24h is the costbasis value - { - int64_t totalposition = 0; - int64_t totalprofits = 0; - - // scan upto the chain tip - for (int i = 0; i < bets.size(); i++) { - - if (height > bets[i].firstheight) { - - int32_t retcode = prices_syntheticprofits(bets[i].costbasis, bets[i].firstheight, height, leverage, vec, bets[i].positionsize, bets[i].profits, lastprice); - if (retcode < 0) { - std::cerr << "prices_scanchain() prices_syntheticprofits returned -1, finishing..." << std::endl; - stop = true; - break; - } - totalposition += bets[i].positionsize; - totalprofits += bets[i].profits; - } - } - - if (stop) - break; - - endheight = height; - int64_t equity = totalposition + totalprofits; - if (equity <= (int64_t)((double)totalposition * prices_minmarginpercent(leverage))) - { // we are in loss - break; - } - } - - return 0; -} - -// pricescostbasis rpc impl: set cost basis (open price) for the bet (deprecated) -UniValue PricesSetcostbasis(int64_t txfee, uint256 bettxid) -{ - int32_t nextheight = komodo_nextheight(); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); - UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp, C; CTransaction bettx; uint256 hashBlock, batontxid, tokenid; - int64_t myfee, positionsize = 0, addedbets, firstprice = 0, lastprice, profits = 0, costbasis = 0, equity; - int32_t i, firstheight = 0, height, numvouts; int16_t leverage = 0; - std::vector vec; - CPubKey pk, mypk, pricespk; std::string rawtx; -/* - cp = CCinit(&C, EVAL_PRICES); - if (txfee == 0) - txfee = PRICES_TXFEE; - - mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp, 0); - if (myGetTransaction(bettxid, bettx, hashBlock) != 0 && (numvouts = bettx.vout.size()) > 3) - { - if (prices_betopretdecode(bettx.vout[numvouts - 1].scriptPubKey, pk, firstheight, positionsize, leverage, firstprice, vec, tokenid) == 'B') - { - if (nextheight <= firstheight + PRICES_DAYWINDOW + 1) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cannot calculate costbasis yet")); - return(result); - } - - addedbets = prices_enumaddedbets(batontxid, bettx, bettxid); - mtx.vin.push_back(CTxIn(bettxid, 1, CScript())); // spend vin1 with betamount - //for (i = 0; i < PRICES_DAYWINDOW + 1; i++) // the last datum for 24h is the actual costbasis value - //{ - int32_t retcode = prices_syntheticprofits(costbasis, firstheight, firstheight + PRICES_DAYWINDOW, leverage, vec, positionsize, addedbets, profits, lastprice); - if (retcode < 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cannot calculate costbasis error getting price")); - return(result); - } - equity = positionsize + addedbets + profits; - //if (equity < 0) - //{ // we are in loss - // result.push_back(Pair("rekt", (int64_t)1)); - // result.push_back(Pair("rektheight", (int64_t)firstheight + i)); - // break; - //} - //} - //if (i == PRICES_DAYWINDOW + 1) - // result.push_back(Pair("rekt", 0)); - - prices_betjson(result, profits, costbasis, positionsize, addedbets, leverage, firstheight, firstprice, lastprice, equity); - - if (AddNormalinputs(mtx, mypk, txfee, 4) >= txfee) - { - myfee = bettx.vout[1].nValue / 10; // fee for setting costbasis - result.push_back(Pair("myfee", myfee)); - - mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[1].nValue - myfee, pricespk)); - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_costbasisopret(bettxid, mypk, firstheight + PRICES_DAYWINDOW , costbasis)); // -1 - return(prices_rawtxresult(result, rawtx, 0)); - } - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "not enough funds")); - return(result); - } - } */ - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "deprecated")); - return(result); -} - - -// pricesaddfunding rpc impl: add yet another bet -UniValue PricesRefillFund(int64_t amount) -{ - int32_t nextheight = komodo_nextheight(); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp, C; - CPubKey pricespk, mypk, pk; - std::string rawtx; - //char myaddr[64]; - - cp = CCinit(&C, EVAL_PRICES); - const int64_t txfee = PRICES_TXFEE; - mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp, 0); - - if (AddNormalinputs(mtx, mypk, amount + txfee, 64) >= amount + txfee) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode, amount, pricespk)); // vout1 added amount - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, CScript()); - return(prices_rawtxresult(result, rawtx, 0)); - - } - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "not enough funds")); - return(result); -} - - -int32_t prices_getbetinfo(uint256 bettxid, BetInfo &betinfo) -{ - CTransaction bettx; - uint256 hashBlock, batontxid, tokenid; - - if (myGetTransaction(bettxid, bettx, hashBlock) && bettx.vout.size() > 3) - { - if (hashBlock.IsNull()) - return -2; - - - // TODO: forget old tx - //CBlockIndex *bi = komodo_getblockindex(hashBlock); - //if (bi && bi->nHeight < 5342) - // return -5; - - OneBetData bet1; - if (prices_betopretdecode(bettx.vout.back().scriptPubKey, betinfo.pk, bet1.firstheight, bet1.positionsize, betinfo.leverage, betinfo.firstprice, betinfo.vecparsed, betinfo.tokenid) == 'B') - { - uint256 finaltxid; - int32_t vini; - int32_t finaltxheight; //, endheight; - //std::vector bets; - betinfo.txid = bettxid; - - if (CCgetspenttxid(finaltxid, vini, finaltxheight, bettxid, NVOUT_CCMARKER) == 0) - betinfo.isOpen = false; - else - betinfo.isOpen = true; - - // override with real amount (TODO: check this) - //bet1.positionsize = bettx.vout[2].nValue; - - betinfo.bets.push_back(bet1); - - prices_enumaddedbets(batontxid, betinfo.bets, bettxid); - - if (!betinfo.isOpen) { - CTransaction finaltx; - uint256 hashBlock; - vscript_t vopret; - if (myGetTransaction(finaltxid, finaltx, hashBlock) && finaltx.vout.size() > 0 && PricesCheckOpret(finaltx, vopret) != 0) { - uint8_t funcId = prices_finalopretdecode(finaltx.vout.back().scriptPubKey, betinfo.txid, betinfo.pk, betinfo.lastheight, betinfo.averageCostbasis, betinfo.lastprice, betinfo.liquidationprice, betinfo.equity, betinfo.exitfee); - if (funcId == 0) - return -3; - - betinfo.isRekt = (funcId == 'R'); - - // return 0; - } - else - return -6; - } - - - if (prices_scanchain(betinfo.bets, betinfo.leverage, betinfo.vecparsed, betinfo.lastprice, betinfo.lastheight) < 0) { - return -4; - } - - mpz_t mpzTotalPosition; - mpz_t mpzTotalprofits; - mpz_t mpzTotalcostbasis; - - mpz_init(mpzTotalPosition); - mpz_init(mpzTotalprofits); - mpz_init(mpzTotalcostbasis); - - int64_t totalposition = 0; - int64_t totalprofits = 0; - - for (auto b : betinfo.bets) { - mpz_t mpzProduct; - mpz_t mpzProfits; - - mpz_init(mpzProduct); - mpz_init(mpzProfits); - - //totalprofits += b.profits; - //dcostbasis += b.amount * (double)b.costbasis; - // costbasis += b.amount * (b.costbasis / PRICES_POINTFACTOR); // prevent int64 overflow (but we have underflow for 1/BTC) - // std::cerr << "PricesInfo() acc dcostbasis=" << dcostbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; - //std::cerr << "PricesInfo() acc dcostbasis=" << dcostbasis << " b.amount=" << b.amount << " b.costbasis/PRICES_POINTFACTOR=" << (b.costbasis / PRICES_POINTFACTOR) << std::endl; - mpz_set_ui(mpzProduct, b.costbasis); - mpz_mul_ui(mpzProduct, mpzProduct, (uint64_t)b.positionsize); // b.costbasis * b.amount - mpz_add(mpzTotalcostbasis, mpzTotalcostbasis, mpzProduct); //averageCostbasis += b.costbasis * b.amount; - - mpz_add_ui(mpzTotalPosition, mpzTotalPosition, (uint64_t)b.positionsize); //totalposition += b.amount; - mpz_add(mpzTotalprofits, mpzTotalprofits, mpzProfits); //totalprofits += b.profits; - - totalposition += b.positionsize; - totalprofits += b.profits; - - mpz_clear(mpzProduct); - mpz_clear(mpzProfits); - } - - betinfo.equity = totalposition + totalprofits; - //int64_t averageCostbasis = 0; - - if (mpz_get_ui(mpzTotalPosition) != 0) { //prevent zero div - mpz_t mpzAverageCostbasis; - mpz_init(mpzAverageCostbasis); - - //averageCostbasis = totalcostbasis / totalposition; - mpz_mul_ui(mpzTotalcostbasis, mpzTotalcostbasis, SATOSHIDEN); // profits *= SATOSHIDEN normalization to prevent loss of significance while division - mpz_tdiv_q(mpzAverageCostbasis, mpzTotalcostbasis, mpzTotalPosition); - - mpz_tdiv_q_ui(mpzAverageCostbasis, mpzAverageCostbasis, SATOSHIDEN); // profits /= SATOSHIDEN de-normalization - - betinfo.averageCostbasis = mpz_get_ui(mpzAverageCostbasis); - mpz_clear(mpzAverageCostbasis); - } - - betinfo.liquidationprice = 0; - if (betinfo.leverage != 0) {// prevent zero div - betinfo.liquidationprice = betinfo.averageCostbasis - (betinfo.averageCostbasis * (1 - prices_minmarginpercent(betinfo.leverage))) / betinfo.leverage; - } - - if (!betinfo.isRekt) { // not set by check for final tx - - if (betinfo.equity > (int64_t)((double)totalposition * prices_minmarginpercent(betinfo.leverage))) - betinfo.isRekt = false; - else - { - betinfo.isRekt = true; - betinfo.exitfee = (int64_t)(((double)totalposition * prices_minmarginpercent(betinfo.leverage)) / 10); // was: totalposition / 500 - } - } - - mpz_clear(mpzTotalPosition); - mpz_clear(mpzTotalprofits); - mpz_clear(mpzTotalcostbasis); - return 0; - } - return -3; - } - return (-1); -} - -// pricesrekt rpc: anyone can rekt a bet at some block where losses reached limit, collecting fee -UniValue PricesRekt(int64_t txfee, uint256 bettxid, int32_t rektheight) -{ - int32_t nextheight = komodo_nextheight(); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp, C; - CTransaction bettx; - int64_t myfee = 0; - CPubKey pk, mypk, pricespk; - std::string rawtx; - char destaddr[64]; - - cp = CCinit(&C, EVAL_PRICES); - if (txfee == 0) // TODO: what did we want to do with txfee in prices? - txfee = PRICES_TXFEE; - mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp, 0); - GetCCaddress(cp, destaddr, pricespk); - - BetInfo betinfo; - int32_t retcode = prices_getbetinfo(bettxid, betinfo); - if (retcode < 0) { - if (retcode == -1) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant find bettxid or incorrect")); - } - else if (retcode == -2) { - throw std::runtime_error("tx still in mempool"); - } - else if (retcode == -3) - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant decode opret")); - return(result); - } - else if (retcode == -4) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "error scanning chain")); - } - return(result); - } - - int64_t totalposition = 0; - int64_t totalprofits = 0; - - for (auto b : betinfo.bets) { - totalposition += b.positionsize; - totalprofits += b.profits; - } - - - if (!betinfo.isOpen) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "position closed")); - return result; - } - - prices_betjson(result, betinfo.bets, betinfo.leverage, betinfo.lastheight, betinfo.lastprice); // fill output - if (betinfo.isRekt) - { - myfee = betinfo.exitfee; // consolation fee for loss - } - if (myfee != 0) - { - int64_t CCchange = 0, inputsum; - - mtx.vin.push_back(CTxIn(bettxid, NVOUT_CCMARKER, CScript())); // spend cc marker - if ((inputsum = AddPricesInputs(cp, mtx, destaddr, myfee + txfee, 64)) > myfee + txfee) // TODO: why do we take txfee from global addr and not from user's addr? - CCchange = (inputsum - myfee); - mtx.vout.push_back(CTxOut(myfee, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - if (CCchange >= txfee) - mtx.vout.push_back(MakeCC1vout(cp->evalcode, CCchange, pricespk)); - - /// mtx.vout.push_back(MakeCC1vout(cp->evalcode, bettx.vout[2].nValue - myfee - txfee, pricespk)); // change - - // make some PoW to get txid=0x00.....00 to 'faucet' rekts - LogPrintf( "start PoW at %u\n", (uint32_t)time(NULL)); - uint32_t nonce = rand() & 0xfffffff; - for (int i = 0; i<1000000; i++, nonce++) - { - CMutableTransaction tmpmtx = mtx; - - rawtx = FinalizeCCTx(0, cp, tmpmtx, mypk, txfee, prices_finalopret(true, bettxid, mypk, betinfo.lastheight, betinfo.averageCostbasis, betinfo.lastprice, betinfo.liquidationprice, betinfo.equity, myfee, nonce)); - uint256 hash = tmpmtx.GetHash(); - if ((hash.begin()[0] & 0xff) == 0 && (hash.begin()[31] & 0xff) == 0) - { - LogPrintf( "found valid txid after %d iterations %u\n", i, (uint32_t)time(NULL)); - return(prices_rawtxresult(result, rawtx, 0)); - } - } - LogPrintf( "couldnt generate valid txid %u\n", (uint32_t)time(NULL)); - - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "could not generate valid txid")); - return(result); - } - else - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "position not rekt")); - return(result); - } -} - -// pricescashout rpc impl: bettor can cashout hit bet if it is not rekt -UniValue PricesCashout(int64_t txfee, uint256 bettxid) -{ - int32_t nextheight = komodo_nextheight(); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); - UniValue result(UniValue::VOBJ); - struct CCcontract_info *cp, C; char destaddr[64]; - int64_t CCchange = 0, inputsum; - CPubKey pk, mypk, pricespk; - std::string rawtx; - - cp = CCinit(&C, EVAL_PRICES); - if (txfee == 0) - txfee = PRICES_TXFEE; - - mypk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp, 0); - GetCCaddress(cp, destaddr, pricespk); - - BetInfo betinfo; - int32_t retcode = prices_getbetinfo(bettxid, betinfo); - if (retcode < 0) { - if (retcode == -1) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant find bettxid or incorrect")); - } - else if (retcode == -2) { - throw std::runtime_error("tx still in mempool"); - } - else if (retcode == -3) - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant decode opret")); - return(result); - } - else if (retcode == -4) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "error scanning chain")); - } - return(result); - } - - int64_t totalposition = 0; - int64_t totalprofits = 0; - - for (auto b : betinfo.bets) { - totalposition += b.positionsize; - totalprofits += b.profits; - } - - - if (!betinfo.isOpen) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "position closed")); - return result; - } - - prices_betjson(result, betinfo.bets, betinfo.leverage, betinfo.lastheight, betinfo.lastprice); // fill output json - - if (betinfo.isRekt) - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "position rekt")); - return(result); - } - - mtx.vin.push_back(CTxIn(bettxid, NVOUT_CCMARKER, CScript())); // spend cc marker - if ((inputsum = AddPricesInputs(cp, mtx, destaddr, betinfo.equity + txfee, 64)) > betinfo.equity + txfee) // TODO: why txfee from the fund? - CCchange = (inputsum - betinfo.equity); - mtx.vout.push_back(CTxOut(betinfo.equity, CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - if (CCchange >= txfee) - mtx.vout.push_back(MakeCC1vout(cp->evalcode, CCchange, pricespk)); - // TODO: what should the opret param be: - rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, prices_finalopret(false, bettxid, mypk, nextheight-1, betinfo.averageCostbasis, betinfo.lastprice, betinfo.liquidationprice, betinfo.equity, txfee, 0)); - return(prices_rawtxresult(result, rawtx, 0)); - -} - - -// pricesinfo rpc impl -UniValue PricesInfo(uint256 bettxid, int32_t refheight) -{ - UniValue result(UniValue::VOBJ); -/* CTransaction bettx; - uint256 hashBlock, batontxid, tokenid; - int64_t positionsize = 0, firstprice = 0, lastprice = 0; - int32_t firstheight = 0, endheight; - int16_t leverage = 0; - std::vector vec; - CPubKey pk, mypk, pricespk; - std::string rawtx; */ - - BetInfo betinfo; - int32_t retcode = prices_getbetinfo(bettxid, betinfo); - if (retcode < 0) { - if( retcode == -1 ) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant find bettxid or incorrect")); - } - else if (retcode == -2) { - throw std::runtime_error("tx still in mempool"); - } - else if (retcode == -3) - { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "cant decode opret")); - return(result); - } - else if (retcode == -4) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "error scanning chain")); - } - else { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", retcode)); - } - return(result); - } - - if (!betinfo.isRekt) - result.push_back(Pair("rekt", 0)); - else - { - result.push_back(Pair("rekt", (int64_t)1)); - result.push_back(Pair("rektfee", betinfo.exitfee)); - result.push_back(Pair("rektheight", betinfo.lastheight)); - } - - result.push_back(Pair("open", betinfo.isOpen ? 1 : 0 )); - - std::string expr = prices_getsourceexpression(betinfo.vecparsed); - result.push_back(Pair("expression", expr)); - result.push_back(Pair("reduced", prices_getreducedexpr(expr))); -// result.push_back(Pair("batontxid", batontxid.GetHex())); - result.push_back(Pair("costbasis", ValueFromAmount(betinfo.averageCostbasis))); -#ifdef TESTMODE - result.push_back(Pair("costbasis_test_period", 7)); -#endif - - prices_betjson(result, betinfo.bets, betinfo.leverage, betinfo.lastheight, betinfo.lastprice); - - result.push_back(Pair("LiquidationPrice", ValueFromAmount(betinfo.liquidationprice))); - - return(result); -} - -// priceslist rpc impl -UniValue PricesList(uint32_t filter, CPubKey mypk) -{ - UniValue result(UniValue::VARR); - std::vector > addressIndex, addressIndexCC; - struct CCcontract_info *cp, C; - - cp = CCinit(&C, EVAL_PRICES); - //pricespk = GetUnspendable(cp, 0); - - // filters and outputs prices bet txid - auto AddBetToList = [&](uint256 txid) - { - int64_t amount, firstprice; - int32_t height; - int16_t leverage; - uint256 hashBlock, tokenid; - CPubKey pk, pricespk; - std::vector vec; - CTransaction vintx; - - if (myGetTransaction(txid, vintx, hashBlock) != 0) - { - - // TODO: forget old tx - //CBlockIndex *bi = komodo_getblockindex(hashBlock); - //if (bi && bi->nHeight < 5342) - // return; - - bool bAppend = false; - if (vintx.vout.size() > 0 && prices_betopretdecode(vintx.vout.back().scriptPubKey, pk, height, amount, leverage, firstprice, vec, tokenid) == 'B' && - (mypk == CPubKey() || mypk == pk)) // if only mypubkey to list - { - if (filter == 0) - bAppend = true; - else { - int32_t vini; - int32_t height; - uint256 finaltxid; - - int32_t spent = CCgetspenttxid(finaltxid, vini, height, txid, NVOUT_CCMARKER); - if (filter == 1 && spent < 0 || // open positions - filter == 2 && spent == 0) // closed positions - bAppend = true; - } - if (bAppend) - result.push_back(txid.GetHex()); - } - std::cerr << "PricesList() " << " bettxid=" << txid.GetHex() << " mypk=" << HexStr(mypk) << " opretpk=" << HexStr(pk) << " filter=" << filter << " bAppend=" << bAppend << std::endl; - } - }; - - - SetCCtxids(addressIndex, cp->normaladdr, false); // old normal marker - for (std::vector >::const_iterator it = addressIndex.begin(); it != addressIndex.end(); it++) - { - if( it->first.index == NVOUT_NORMALMARKER ) - AddBetToList(it->first.txhash); - } - - /* for future when switch to cc marker only - SetCCtxids(addressIndexCC, cp->unspendableCCaddr, true); // cc marker - for (std::vector >::const_iterator it = addressIndexCC.begin(); it != addressIndexCC.end(); it++) - { - priceslist(it, 1); - } - */ - return(result); -} - - -static bool prices_addbookentry(uint256 txid, std::vector &book) -{ - BetInfo betinfo; - if (prices_getbetinfo(txid, betinfo) == 0) { - book.push_back(betinfo); - return true; - } - return false; -} - - -static bool prices_ispositionup(const std::vector &vecparsed, int16_t leverage) { - if (vecparsed.size() > 1 && vecparsed.size() <= 3) { - uint16_t opcode = vecparsed[0]; - - int32_t value = (opcode & (KOMODO_MAXPRICES - 1)); // filter index or weight = opcode & (2048-1) - - if ((opcode & KOMODO_PRICEMASK) == 0) { - char name[65]; - if (komodo_pricename(name, value)) { - std::string upperquote, bottomquote; - prices_splitpair(std::string(name), upperquote, bottomquote); - - uint16_t opcode1 = vecparsed[1]; - bool isInverted = ((opcode1 & KOMODO_PRICEMASK) == PRICES_INV); - - //std::cerr << "prices_ispositionup upperquote=" << upperquote << " bottomquote=" << bottomquote << " opcode1=" << opcode1 << " (opcode1 & KOMODO_PRICEMASK)=" << (opcode1 & KOMODO_PRICEMASK) << std::endl; - - if (upperquote == "BTC" || bottomquote == "BTC") { // it is relatively btc - if (upperquote == "BTC" && (leverage > 0 && !isInverted || leverage < 0 && isInverted) || - bottomquote == "BTC" && (leverage < 0 && !isInverted || leverage > 0 && isInverted)) { - std::cerr << "prices_ispositionup returns true for BTC for expr=" << prices_getsourceexpression(vecparsed) << " lev=" << leverage << std::endl; - return true; - } - else { - std::cerr << "prices_ispositionup returns false for BTC for expr=" << prices_getsourceexpression(vecparsed) << " lev=" << leverage << std::endl; - return false; - } - } - - if (upperquote == "USD" || bottomquote == "USD") { // it is relatively usd - if (upperquote == "USD" && (leverage > 0 && !isInverted || leverage < 0 && isInverted) || - bottomquote == "USD" && (leverage < 0 && !isInverted || leverage > 0 && isInverted)) { - std::cerr << "prices_ispositionup returns true for USD for expr=" << prices_getsourceexpression(vecparsed) << " lev=" << leverage << std::endl; - return true; - } - else { - std::cerr << "prices_ispositionup returns false for USD for expr=" << prices_getsourceexpression(vecparsed) << " lev=" << leverage << std::endl; - return false; - } - } - } - } - } - std::cerr << "prices_ispositionup returns false for expr=" << prices_getsourceexpression(vecparsed) << " lev=" << leverage << std::endl; - return false; -} - -static bool prices_isopposite(BetInfo p1, BetInfo p2) { - if (p1.vecparsed.size() <= 3 && p2.vecparsed.size() <= 3) { // simple synthetic exp - - uint16_t opcode1 = p1.vecparsed[0]; - uint16_t opcode2 = p2.vecparsed[0]; - - int32_t value1 = (opcode1 & (KOMODO_MAXPRICES - 1)); // index or weight - int32_t value2 = (opcode2 & (KOMODO_MAXPRICES - 1)); // index or weight - - if ( (opcode1 & KOMODO_PRICEMASK) == 0 && (opcode2 & KOMODO_PRICEMASK) == 0 ) { - char name1[65]; - char name2[65]; - if (komodo_pricename(name1, value1) && komodo_pricename(name2, value2)) { - - uint16_t opcode1 = p1.vecparsed[1]; - uint16_t opcode2 = p2.vecparsed[1]; - - std::string upperquote1, bottomquote1, upperquote2, bottomquote2; - prices_splitpair(std::string(name1), upperquote1, bottomquote1); - prices_splitpair(std::string(name2), upperquote2, bottomquote2); - - bool isInverted1 = ((opcode1 & KOMODO_PRICEMASK) != PRICES_INV); - bool isInverted2 = ((opcode2 & KOMODO_PRICEMASK) != PRICES_INV); - - if (/*upperquote1 == bottomquote2 && bottomquote1 == upperquote2 && (p1.leverage > 0 == p2.leverage > 0 || (opcode1 & KOMODO_PRICEMASK) == PRICES_INV == (opcode2 & KOMODO_PRICEMASK) == PRICES_INV) ||*/ - upperquote1 == upperquote2 && bottomquote1 == bottomquote2 && ((p1.leverage > 0) != (p2.leverage > 0) || isInverted1 != isInverted2) ) - return true; - } - } - } - return false; -} - - - -static std::string findMatchedBook(const std::vector &vecparsed, const std::map > & bookmatched) { - - if (vecparsed.size() > 1 && vecparsed.size() <= 3) { - uint16_t opcode = vecparsed[0]; - - int32_t value = (opcode & (KOMODO_MAXPRICES - 1)); // filter index or weight = opcode & (2048-1) - - if ((opcode & KOMODO_PRICEMASK) == 0) { - char name[65]; - if (komodo_pricename(name, value)) { - auto it = bookmatched.find(std::string(name)); - if (it != bookmatched.end()) - return it->first; - } - } - } - return std::string(""); -} - - -void prices_getorderbook(std::map > & bookmatched, std::map &matchedTotals, TotalFund &fundTotals) -{ - std::vector book; - std::vector > addressIndex; - struct CCcontract_info *cp, C; - - cp = CCinit(&C, EVAL_PRICES); - - // add all bets: - SetCCtxids(addressIndex, cp->normaladdr, false); // old normal marker - for (std::vector >::const_iterator it = addressIndex.begin(); it != addressIndex.end(); it++) - { - if (it->first.index == NVOUT_NORMALMARKER) - prices_addbookentry(it->first.txhash, book); - } - - - // calc total fund amount - fundTotals.totalFund = 0; - fundTotals.totalRekt = 0; - fundTotals.totalEquity = 0; - fundTotals.totalActiveBets = 0; - - std::vector > addressCCunspents; - SetCCunspents(addressCCunspents, cp->unspendableCCaddr, true); // cc marker - for (std::vector >::const_iterator it = addressCCunspents.begin(); it != addressCCunspents.end(); it++) - { - //std::cerr << "totalfund calc txid=" << it->first.txhash.GetHex() << " nvout=" << it->first.index << " satoshis=" << it->second.satoshis << std::endl; - fundTotals.totalFund += it->second.satoshis; - } - - // extract out opposite bets: - while (book.size() > 0) { - - int64_t totalPos = 0; - for (auto bet : book[0].bets) totalPos += bet.positionsize; - - if (book[0].isOpen) { - - fundTotals.totalActiveBets += totalPos; - fundTotals.totalEquity += book[0].equity; - - if (book[0].vecparsed.size() <= 3) { // only short expr check for match: "BTC_USD,1" or "BTC_USD,!,1" - char name[65]; - komodo_pricename(name, (book[0].vecparsed[0] & (KOMODO_MAXPRICES - 1))); - std::string sname = name; - bookmatched[sname].push_back(book[0]); - - for (int j = 1; j < book.size(); j++) { - if (book[0].isOpen && book[j].isOpen) { - if (prices_isopposite(book[0], book[j])) { - - bookmatched[sname].push_back(book[j]); - book.erase(book.begin() + j); - } - } - } - } - else { - // store as is - std::string sname = prices_getsourceexpression(book[0].vecparsed); - bookmatched[sname].push_back(book[0]); - } - } - else { - if( book[0].isRekt ) - fundTotals.totalRekt += (totalPos - book[0].exitfee); - else - fundTotals.totalCashout += (totalPos - book[0].exitfee); - - //TODO: store rekt - } - book.erase(book.begin()); - } - - // calculate cancelling amount - for (auto &m : bookmatched) { // note: use reference &m otherwise isUp will be changed only in a copy - int64_t totalLeveragedPositionUp = 0; - int64_t totalLeveragedPositionDown = 0; - - for (int i = 0; i < m.second.size(); i++) { - int64_t totalPos = 0; - for (auto bet : m.second[i].bets) totalPos += bet.positionsize; - m.second[i].isUp = prices_ispositionup(m.second[i].vecparsed, m.second[i].leverage); - if (m.second[i].isUp) - totalLeveragedPositionUp += totalPos * abs(m.second[i].leverage); - else - totalLeveragedPositionDown += totalPos * abs(m.second[i].leverage); - //std::cerr << "PricesGetOrderbook 0 m.second[i].isUp=" << m.second[i].isUp << " i=" << i << std::endl; - - } - matchedTotals[m.first].diffLeveragedPosition = totalLeveragedPositionUp - totalLeveragedPositionDown; - } -} - -static bool prices_isacceptableamount(const std::vector &vecparsed, int64_t amount, int16_t leverage) { - - std::map > matchedBook; - std::map matchedTotals; - TotalFund fundTotals; - - prices_getorderbook(matchedBook, matchedTotals, fundTotals); - std::string pricename = findMatchedBook(vecparsed, matchedBook); - if (!pricename.empty()) { - std::cerr << "prices_isacceptableamount() found matched book=" << pricename << " diffLeveragedPosition=" << matchedTotals[pricename].diffLeveragedPosition << " expr=" << prices_getsourceexpression(vecparsed) << std::endl; - // could fit into leveraged amount - if (prices_ispositionup(vecparsed, leverage) && amount*abs(leverage) + matchedTotals[pricename].diffLeveragedPosition <= 0) { - std::cerr << "prices_isacceptableamount() could fit into opposite negative lev amount" << std::endl; - return true; - } - if (!prices_ispositionup(vecparsed, leverage) && -amount*abs(leverage) + matchedTotals[pricename].diffLeveragedPosition >= 0) { - std::cerr << "prices_isacceptableamount() could fit into opposite positive lev amount" << std::endl; - return true; - } - } - - std::cerr << "prices_isacceptableamount() amount=" << amount << " leverage=" << leverage << " fundTotals.totalFund=" << fundTotals.totalFund << " fundTotals.totalEquity=" << fundTotals.totalEquity << std::endl; - // if not fit to matched = allow to bet for leveraged amount no more than 10% from free fund - if (amount * leverage < (fundTotals.totalFund - fundTotals.totalEquity) * PRICES_MINAVAILFUNDFRACTION) - return true; - - return false; -} - - -// walk through uxtos on the global address -// calculate the balance: -// + rekt positions -// = opposite positions -// - unbalanced positions -UniValue PricesGetOrderbook() -{ - UniValue result(UniValue::VOBJ); - std::map > matchedBook; - std::map matchedTotals; - TotalFund fundTotals; - - prices_getorderbook(matchedBook, matchedTotals, fundTotals); - - /*UniValue resbook (UniValue::VARR); - for (int i = 0; i < book.size(); i++) { - UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("expression", prices_getsourceexpression(book[i].vecparsed))); - entry.push_back(Pair("costbasis", book[i].averageCostbasis)); - entry.push_back(Pair("leverage", book[i].leverage)); - entry.push_back(Pair("equity", book[i].equity)); - resbook.push_back(entry); - } - result.push_back(Pair("unmatched", resbook)); */ - - // copy to rpc UniResult - for (auto &m : matchedBook) { - UniValue resheader(UniValue::VOBJ); - UniValue resbook(UniValue::VARR); - for (int i = 0; i < m.second.size(); i++) { - UniValue entry(UniValue::VOBJ); - - int64_t totalPos = 0; - for (auto bet : m.second[i].bets) totalPos += bet.positionsize; - entry.push_back(Pair("isOpen", (m.second[i].isOpen ? 1 : 0 ))); - entry.push_back(Pair("expression", prices_getsourceexpression(m.second[i].vecparsed))); - entry.push_back(Pair("positionsize", totalPos)); - entry.push_back(Pair("leverage", m.second[i].leverage)); - entry.push_back(Pair("costbasis", m.second[i].averageCostbasis)); - entry.push_back(Pair("lastprice", m.second[i].lastprice)); - entry.push_back(Pair("equity", m.second[i].equity)); - entry.push_back(Pair("isUpPosition", (m.second[i].isUp ? 1 : 0))); - resbook.push_back(entry); - } - resheader.push_back(Pair("positions", resbook)); - resheader.push_back(Pair("DiffLeveragedPosition", matchedTotals[m.first].diffLeveragedPosition)); - result.push_back(Pair(m.first, resheader)); - } - - //int64_t totalLiabilities = 0; - /* empty - for (int i = 0; i < book.size(); i++) { - if (book[i].isOpen) { - int64_t t = 0; - for (auto b : book[i].bets) t += b.positionsize; - std::cerr << "book[i].txid=" << book[i].txid.GetHex() << " exp=" << prices_getsourceexpression(book[i].vecparsed) << " totalpos=" << t << " equity=" << book[i].equity << std::endl; - totalLiabilities += book[i].equity; - } - } */ - - result.push_back(Pair("TotalFund", ValueFromAmount(fundTotals.totalFund))); - result.push_back(Pair("TotalEquity", ValueFromAmount(fundTotals.totalEquity))); - result.push_back(Pair("TotalRekt", ValueFromAmount(fundTotals.totalRekt))); - result.push_back(Pair("TotalBets", ValueFromAmount(fundTotals.totalActiveBets))); - result.push_back(Pair("TotalCashoutBets", ValueFromAmount(fundTotals.totalCashout))); - -// result.push_back(Pair("TotalLiabilities", ValueFromAmount(totalLiabilities))); - return result; -} diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index c2e85c7f..5466805c 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -14,6 +14,8 @@ ******************************************************************************/ #include "CCrewards.h" +#include "komodo_bitcoind.h" +#include /* The rewards CC contract is initially for OOT, which needs this functionality. However, many of the attributes can be parameterized to allow different rewards programs to run. Multiple rewards plans could even run on the same blockchain, though the user would need to choose which one to lock funds into. @@ -68,11 +70,11 @@ /// the following are compatible with windows /// mpz_set_lli sets a long long singed int to a big num mpz_t for very large integer math -extern void mpz_set_lli( mpz_t rop, long long op ); +void mpz_set_lli( mpz_t rop, long long op ); // mpz_get_si2 gets a mpz_t and returns a signed long long int -extern int64_t mpz_get_si2( mpz_t op ); +int64_t mpz_get_si2( mpz_t op ); // mpz_get_ui2 gets a mpz_t and returns a unsigned long long int -extern uint64_t mpz_get_ui2( mpz_t op ); +uint64_t mpz_get_ui2( mpz_t op ); uint64_t RewardsCalc(int64_t amount, uint256 txid, int64_t APR, int64_t minseconds, int64_t maxseconds, uint32_t timestamp) { diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index 6774eb32..82edce7e 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -547,44 +547,7 @@ uint16_t _komodo_userpass(char *username, char *password, FILE *fp) return(port); } -/*void komodo_statefname(char *fname,char *symbol,char *str) -{ - int32_t n,len; - sprintf(fname,"%s",getDataDir()); - if ( (n= (int32_t)strlen(ASSETCHAINS_SYMBOL)) != 0 ) - { - len = (int32_t)strlen(fname); - if ( strcmp(ASSETCHAINS_SYMBOL,&fname[len - n]) == 0 ) - fname[len - n] = 0; - else - { - printf("unexpected fname.(%s) vs %s [%s] n.%d len.%d (%s)\n",fname,symbol,ASSETCHAINS_SYMBOL,n,len,&fname[len - n]); - return; - } - } - else - { -#ifdef _WIN32 - strcat(fname,"\\"); -#else - strcat(fname,"/"); -#endif - } - if ( symbol != 0 && symbol[0] != 0 && strcmp("KMD",symbol) != 0 ) - { - strcat(fname,symbol); - //printf("statefname.(%s) -> (%s)\n",symbol,fname); -#ifdef _WIN32 - strcat(fname,"\\"); -#else - strcat(fname,"/"); -#endif - } - strcat(fname,str); - //printf("test.(%s) -> [%s] statename.(%s) %s\n",test,ASSETCHAINS_SYMBOL,symbol,fname); -}*/ - -uint16_t komodo_userpass(char *userpass,char *symbol) +uint16_t komodo_userpass(char *userpass,const char *symbol) { FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[KOMODO_ASSETCHAIN_MAXLEN]; userpass[0] = 0; @@ -597,7 +560,6 @@ uint16_t komodo_userpass(char *userpass,char *symbol) #endif } else sprintf(confname,"%s.conf",symbol); - //komodo_statefname(fname,symbol,confname); if ( (fp= fopen(confname,"rb")) != 0 ) { port = _komodo_userpass(username,password,fp); @@ -621,9 +583,7 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) { sprintf(url,(char *)"http://%s:%u",IPADDRESS,port); sprintf(postdata,"{\"method\":\"%s\",\"params\":%s}",method,params); - //printf("[%s] (%s) postdata.(%s) params.(%s) USERPASS.(%s)\n",ASSETCHAINS_SYMBOL,url,postdata,params,USERPASS); retstr2 = bitcoind_RPC(&retstr,(char *)"debug",url,userpass,method,params); - //retstr = curl_post(&cHandle,url,USERPASS,postdata,0,0,0,0); } return(retstr2); } diff --git a/src/cc/rogue_rpc.cpp b/src/cc/rogue_rpc.cpp index 8b75e229..296af930 100644 --- a/src/cc/rogue_rpc.cpp +++ b/src/cc/rogue_rpc.cpp @@ -16,6 +16,7 @@ #include "cJSON.h" #include "CCinclude.h" +#include "komodo_bitcoind.h" #define ROGUE_REGISTRATION 5 #define ROGUE_REGISTRATIONSIZE (100 * 10000) @@ -162,8 +163,8 @@ CScript rogue_keystrokesopret(uint256 gametxid,uint256 batontxid,CPubKey pk,std: CScript rogue_highlanderopret(uint8_t funcid,uint256 gametxid,int32_t regslot,CPubKey pk,std::vectorplayerdata,std::string pname) { - CScript opret; uint8_t evalcode = EVAL_ROGUE; std::string symbol(ASSETCHAINS_SYMBOL); - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << gametxid << symbol << pname << regslot << pk << playerdata ); + CScript opret; uint8_t evalcode = EVAL_ROGUE; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << gametxid << chainName.symbol() << pname << regslot << pk << playerdata ); return(opret); } @@ -701,7 +702,7 @@ uint64_t rogue_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 obj.push_back(Pair("seed",(int64_t)seed)); if ( rogue_iamregistered(maxplayers,gametxid,tx,myrogueaddr) > 0 ) sprintf(cmd,"cc/rogue/rogue %llu %s",(long long)seed,gametxid.ToString().c_str()); - else sprintf(cmd,"./komodo-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",ASSETCHAINS_SYMBOL,EVAL_ROGUE,gametxid.ToString().c_str()); + else sprintf(cmd,"./komodo-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",chainName.symbol().c_str(),EVAL_ROGUE,gametxid.ToString().c_str()); obj.push_back(Pair("run",cmd)); } } @@ -1513,7 +1514,7 @@ UniValue rogue_setname(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) { CScript scriptPubKey; std::vector vopret; uint8_t *script,e,f,funcid,tokentx=0; int32_t i,maxplayers,enabled = 0,decoded=0,regslot,ind,err,dispflag,gameheight,score,numvouts; CTransaction vintx,gametx; CPubKey pk; uint256 hashBlock,gametxid,txid,tokenid,batontxid,playertxid,ptxid; int64_t buyin,cashout; std::vector playerdata,keystrokes; std::string symbol,pname; - if ( strcmp(ASSETCHAINS_SYMBOL,"ROGUE") == 0 ) + if ( chainName.isSymbol("ROGUE") ) { if (height < 21274 ) return(true); diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 42fa422f..503dca73 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -201,6 +201,8 @@ /* */ /************************************************************************************/ +#include "komodo_bitcoind.h" + #include #include #include @@ -2968,7 +2970,7 @@ bool sudoku_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const strcpy(laststr,str); LogPrintf("%s\n",str); } - if ( strcmp(ASSETCHAINS_SYMBOL,"SUDOKU") != 0 || height > 2000 ) + if ( !chainName.isSymbol("SUDOKU") || height > 2000 ) return eval->Invalid("mismatched sudoku value vs score"); else return(true); } else return(true); @@ -3000,14 +3002,14 @@ bool sudoku_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const { if ( dispflag != 0 ) LogPrintf("ht.%d errflag.%d %s\n",height,errflag,unsolved); - if ( (height != 1220 && height != 1383) || strcmp(ASSETCHAINS_SYMBOL,"SUDOKU") != 0 ) + if ( (height != 1220 && height != 1383) || !chainName.isSymbol("SUDOKU") ) return eval->Invalid("invalid timestamp vs unsolved"); } if ( dupree_solver(0,&score,unsolved) != 1 ) { if ( dispflag != 0 ) LogPrintf("non-unique sudoku at ht.%d\n",height); - if ( strcmp(ASSETCHAINS_SYMBOL,"SUDOKU") != 0 ) + if ( !chainName.isSymbol("SUDOKU") ) return eval->Invalid("invalid sudoku with multiple solutions"); } if ( dispflag != 0 ) @@ -3034,7 +3036,7 @@ bool sudoku_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const return(true); } else return eval->Invalid("invalid solution opret"); } - else if ( strcmp(ASSETCHAINS_SYMBOL,"SUDOKU") == 0 && height == 236 ) + else if ( chainName.isSymbol("SUDOKU") && height == 236 ) return(true); else return eval->Invalid("invalid solution vin"); } diff --git a/src/chain.cpp b/src/chain.cpp index c93dd30e..5e87d88a 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -19,6 +19,10 @@ ******************************************************************************/ #include "chain.h" +#include "komodo_defs.h" +#include "komodo_globals.h" +#include "notaries_staked.h" +#include "komodo_hardfork.h" using namespace std; @@ -26,7 +30,7 @@ using namespace std; * CChain implementation */ void CChain::SetTip(CBlockIndex *pindex) { - lastTip = pindex; + AssertLockHeld(cs_main); if (pindex == NULL) { vChain.clear(); return; @@ -39,6 +43,7 @@ void CChain::SetTip(CBlockIndex *pindex) { } CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { + AssertLockHeld(cs_main); int nStep = 1; std::vector vHave; vHave.reserve(32); @@ -67,6 +72,7 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { } const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { + AssertLockHeld(cs_main); if ( pindex == 0 ) return(0); if (pindex->nHeight > Height()) @@ -127,3 +133,13 @@ void CBlockIndex::BuildSkip() if (pprev) pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); } + +bool CDiskBlockIndex::isStakedAndNotaryPay() const +{ + return is_STAKED(chainName.symbol()) != 0 && ASSETCHAINS_NOTARY_PAY[0] != 0; +} + +bool CDiskBlockIndex::isStakedAndAfterDec2019(unsigned int nTime) const +{ + return ASSETCHAINS_STAKED != 0 && (nTime > nStakedDecemberHardforkTimestamp || is_STAKED(chainName.symbol()) != 0); +} diff --git a/src/chain.h b/src/chain.h index 46080f0e..ff0136b3 100644 --- a/src/chain.h +++ b/src/chain.h @@ -26,19 +26,26 @@ #include "pow.h" #include "tinyformat.h" #include "uint256.h" +#include "sync.h" +#include "assetchain.h" #include #include +extern CCriticalSection cs_main; + static const int SPROUT_VALUE_VERSION = 1001400; static const int SAPLING_VALUE_VERSION = 1010100; -extern char ASSETCHAINS_SYMBOL[65]; -extern uint64_t ASSETCHAINS_NOTARY_PAY[]; + +// These 5 are declared here to avoid circular dependencies +// code used this moved into .cpp +/*extern assetchain chainName; +extern uint64_t ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS+1]; extern int32_t ASSETCHAINS_STAKED; extern const uint32_t nStakedDecemberHardforkTimestamp; //December 2019 hardfork extern const int32_t nDecemberHardforkHeight; //December 2019 hardfork -extern int8_t is_STAKED(const char *chain_name); +uint8_t is_STAKED(const std::string& symbol);*/ struct CDiskBlockPos { @@ -311,12 +318,19 @@ class CBlockIndex enum { nMedianTimeSpan=11 }; + /*** + * @note times are stored as a 4 byte int. Although this returns int64_t, it will be at + * 32 bit resolution. + * @note storing this as 32 bits can cause a "Year 2038" problem. + * @returns the median time (uinx epoch) of the last nMedianTimeSpan (currently 11) blocks + */ int64_t GetMedianTimePast() const { int64_t pmedian[nMedianTimeSpan]; int64_t* pbegin = &pmedian[nMedianTimeSpan]; int64_t* pend = &pmedian[nMedianTimeSpan]; + // grab the times of the last 11 blocks const CBlockIndex* pindex = this; for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) *(--pbegin) = pindex->GetBlockTime(); @@ -432,22 +446,20 @@ class CDiskBlockIndex : public CBlockIndex } // leave the existing LABS exemption here for segid and notary pay, but also add a timestamp activated segid for non LABS PoS64 chains. - if ( (s.GetType() & SER_DISK) && is_STAKED(ASSETCHAINS_SYMBOL) != 0 && ASSETCHAINS_NOTARY_PAY[0] != 0 ) + if ( (s.GetType() & SER_DISK) && isStakedAndNotaryPay() /*is_STAKED(chainName.symbol()) != 0 && ASSETCHAINS_NOTARY_PAY[0] != 0*/ ) { READWRITE(nNotaryPay); } - if ( (s.GetType() & SER_DISK) && ASSETCHAINS_STAKED != 0 && (nTime > nStakedDecemberHardforkTimestamp || is_STAKED(ASSETCHAINS_SYMBOL) != 0) ) //December 2019 hardfork + if ( (s.GetType() & SER_DISK) && isStakedAndAfterDec2019(nTime) /*ASSETCHAINS_STAKED != 0 && (nTime > nStakedDecemberHardforkTimestamp || is_STAKED(chainName.symbol()) != 0)*/ ) //December 2019 hardfork { READWRITE(segid); } - - /*if ( (s.GetType() & SER_DISK) && (is_STAKED(ASSETCHAINS_SYMBOL) != 0) && ASSETCHAINS_NOTARY_PAY[0] != 0 ) - { - READWRITE(nNotaryPay); - READWRITE(segid); - }*/ } +private: + bool isStakedAndNotaryPay() const; + bool isStakedAndAfterDec2019(unsigned int nTime) const; +public: uint256 GetBlockHash() const { CBlockHeader block; @@ -476,41 +488,49 @@ class CDiskBlockIndex : public CBlockIndex /** An in-memory indexed chain of blocks. */ class CChain { -private: +protected: std::vector vChain; - CBlockIndex *lastTip; - + CBlockIndex *at(int nHeight) const REQUIRES(cs_main) + { + if (nHeight < 0 || nHeight >= (int)vChain.size()) + return NULL; + return vChain[nHeight]; + } public: /** Returns the index entry for the genesis block of this chain, or NULL if none. */ - CBlockIndex *Genesis() const { + CBlockIndex *Genesis() const REQUIRES(cs_main) { + AssertLockHeld(cs_main); return vChain.size() > 0 ? vChain[0] : NULL; } - /** Returns the index entry for the tip of this chain, or nullptr if none. */ - CBlockIndex *Tip() const { + /** Returns the index entry for the tip of this chain, or NULL if none. */ + CBlockIndex *Tip() const REQUIRES(cs_main) { + AssertLockHeld(cs_main); return vChain.size() > 0 ? vChain[vChain.size() - 1] : nullptr; } - + /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */ - CBlockIndex *operator[](int nHeight) const { - if (nHeight < 0 || nHeight >= (int)vChain.size()) - return NULL; - return vChain[nHeight]; + CBlockIndex *operator[](int nHeight) const REQUIRES(cs_main) { + AssertLockHeld(cs_main); + return at(nHeight); } /** Compare two chains efficiently. */ - friend bool operator==(const CChain &a, const CChain &b) { - return a.vChain.size() == b.vChain.size() && - a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1]; + friend bool operator==(const CChain &a, const CChain &b) REQUIRES(cs_main) { + AssertLockHeld(cs_main); + return a.Height() == b.Height() && + a.Tip() == b.Tip(); } /** Efficiently check whether a block is present in this chain. */ - bool Contains(const CBlockIndex *pindex) const { + bool Contains(const CBlockIndex *pindex) const REQUIRES(cs_main) { + AssertLockHeld(cs_main); return (*this)[pindex->nHeight] == pindex; } /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */ - CBlockIndex *Next(const CBlockIndex *pindex) const { + CBlockIndex *Next(const CBlockIndex *pindex) const REQUIRES(cs_main) { + AssertLockHeld(cs_main); if (Contains(pindex)) return (*this)[pindex->nHeight + 1]; else @@ -518,18 +538,19 @@ class CChain { } /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */ - int Height() const { + int Height() const REQUIRES(cs_main) { + AssertLockHeld(cs_main); return vChain.size() - 1; } /** Set/initialize a chain with a given tip. */ - void SetTip(CBlockIndex *pindex); + void SetTip(CBlockIndex *pindex) REQUIRES(cs_main); /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */ - CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const; + CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const REQUIRES(cs_main); /** Find the last common block between this chain and a block index entry. */ - const CBlockIndex *FindFork(const CBlockIndex *pindex) const; + const CBlockIndex *FindFork(const CBlockIndex *pindex) const REQUIRES(cs_main); }; #endif // BITCOIN_CHAIN_H diff --git a/src/chainparams.cpp b/src/chainparams.cpp index ab9164fb..2cb74024 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -21,12 +21,11 @@ #include "key_io.h" #include "main.h" #include "crypto/equihash.h" - +#include "komodo_globals.h" #include "util.h" #include "utilstrencodings.h" #include - #include #include "chainparamsseeds.h" @@ -135,9 +134,6 @@ class CMainParams : public CChainParams { consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170007; consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; - // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000281b32ff3198a1"); - /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce @@ -196,12 +192,12 @@ class CMainParams : public CChainParams { vSeeds.push_back(CDNSSeedData("komodoseeds.com", "dynamic.komodoseeds.com")); */ - // TODO: set up bootstrapping for mainnet - base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,60); - base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,85); - base58Prefixes[SECRET_KEY] = std::vector(1,188); - base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container >(); - base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container >(); + // TODO: we need more seed crawlers from other community members + base58Prefixes[PUBKEY_ADDRESS] = {60}; + base58Prefixes[SCRIPT_ADDRESS] = {85}; + base58Prefixes[SECRET_KEY] = {188}; + base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xb2, 0x1e}; + base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xad, 0xe4}; // guarantees the first two characters, when base58 encoded, are "zc" base58Prefixes[ZCPAYMENT_ADDRRESS] = {22,154}; // guarantees the first 4 characters, when base58 encoded, are "ZiVK" @@ -221,7 +217,107 @@ class CMainParams : public CChainParams { fRequireStandard = true; fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = false; - } + + checkpointData = { + boost::assign::map_list_of + + (0, consensus.hashGenesisBlock) + ( 50000, uint256S("0x00076e16d3fa5194da559c17cf9cf285e21d1f13154ae4f7c7b87919549345aa")) + ( 100000, uint256S("0x0f02eb1f3a4b89df9909fec81a4bd7d023e32e24e1f5262d9fc2cc36a715be6f")) + ( 150000, uint256S("0x0a817f15b9da636f453a7a01835cfc534ed1a55ce7f08c566471d167678bedce")) + ( 200000, uint256S("0x000001763a9337328651ca57ac487cc0507087be5838fb74ca4165ff19f0e84f")) + ( 250000, uint256S("0x0dd54ef5f816c7fde9d2b1c8c1a26412b3c761cc5dd3901fa5c4cd1900892fba")) + ( 300000, uint256S("0x000000fa5efd1998959926047727519ed7de06dcf9f2cd92a4f71e907e1312dc")) + ( 350000, uint256S("0x0000000228ef321323f81dae00c98d7960fc7486fb2d881007fee60d1e34653f")) + ( 400000, uint256S("0x036d294c5be96f4c0efb28e652eb3968231e87204a823991a85c5fdab3c43ae6")) + ( 450000, uint256S("0x0906ef1e8dc194f1f03bd4ce1ac8c6992fd721ef2c5ccbf4871ec8cdbb456c18")) + ( 500000, uint256S("0x0bebdb417f7a51fe0c36fcf94e2ed29895a9a862eaa61601272866a7ecd6391b")) + ( 550000, uint256S("0x06df52fc5f9ba03ccc3a7673b01ab47990bd5c4947f6e1bc0ba14d21cd5bcccd")) + ( 600000, uint256S("0x00000005080d5689c3b4466e551cd1986e5d2024a62a79b1335afe12c42779e4")) + ( 650000, uint256S("0x039a3cb760cc6e564974caf69e8ae621c14567f3a36e4991f77fd869294b1d52")) + ( 700000, uint256S("0x00002285be912b2b887a5bb42d2f1aa011428c565b0ffc908129c47b5ce87585")) + ( 750000, uint256S("0x04cff4c26d185d591bed3613ce15e1d15d9c91dd8b98a6729f89c58ce4bd1fd6")) + ( 800000, uint256S("0x0000000617574d402fca8e6570f0845bd5fe449398b318b4e1f65bc69cdd6606")) + ( 850000, uint256S("0x044199301f37194f20ba7b498fc72ed742f6c0ba6e476f28d6c81d225e58d5ce")) + ( 900000, uint256S("0x08bdbe4de2a65ac89fd2913192d05362c900e3af476a0c99d9f311875067451e")) + ( 950000, uint256S("0x0000000aa9a44b593e6138f247bfae75bd43b9396ef9ff0a6a3ebd852f131806")) + ( 1000000, uint256S("0x0cb1d2457eaa58af5028e86e27ac54578fa09558206e7b868ebd35e7005ed8bb")) + ( 1050000, uint256S("0x044d49bbc3bd9d32b6288b768d4f7e0afe3cbeda606f3ac3579a076e4bddf6ae")) + ( 1100000, uint256S("0x000000050cad04887e170059dd2556d85bbd20390b04afb9b07fb62cafd647b4")) + ( 1150000, uint256S("0x0c85501c759d957dd1ccc5f7fdfcc415c89c7f2a26471fffc75b75f79e63c16a")) + ( 1200000, uint256S("0x0763cbf43ed7227988081c29d9e9fc7ab2450216e6d0354cc4596c86689702d4")) + ( 1250000, uint256S("0x0489640207f8c343a56a10e45d987516059ea82a3c6859a771b3a9cf94f5c3bb")) + ( 1300000, uint256S("0x000000012a01709b254b4f75e2b9ed772d8fe558655c8c859892ca8c9d625e87")) + ( 1350000, uint256S("0x075a1a5c66a68b47d9848ca6986687ed2665b1852457051bf142208e62f98a60")) + ( 1400000, uint256S("0x055f73dd9b20650c3d6e6dbb606af8d9479e4c81d89430867abff5329f167bb2")) + ( 1450000, uint256S("0x014c2926e07e9712211c5e82f05df1b802c59cc8bc24e3cc9b09942017080f2d")) + ( 1500000, uint256S("0x0791f892210ce3c513ab607d689cd1e8907a27f3dfeb58dec21ae299b7981cb7")) + ( 1550000, uint256S("0x08fcbaffb7164b161a25efc6dd5c70b679498ee637d663fe201a55c7decc37a3")) + ( 1600000, uint256S("0x0e577dcd49319a67fe2acbb39ae6d46afccd3009d3ba9d1bcf6c624708e12bac")) + ( 1650000, uint256S("0x091ac57a0f786a9526b2224a10b62f1f464b9ffc0afc2240d86264439e6ad3d0")) + ( 1700000, uint256S("0x0d0be6ab4a5083ce9d2a7ea2549b03cfc9770427b7d51c0bf0c603399a60d037")) + ( 1750000, uint256S("0x0a019d830157db596eeb678787279908093fd273a4e022b5e052f3a9f95714ca")) + ( 1800000, uint256S("0x0390779f6c615620391f9dd7df7f3f4947523bd6350b26625c0315571c616076")) + ( 1850000, uint256S("0x000000007ca2de1bd9cb7b52fe0accca4874143822521d955e58c73e304279e0")) + ( 1900000, uint256S("0x04c6589d5703f8237bf215c4e3e881c1c77063ef079cea5dc132a0e7f7a0cbd9")) + ( 1950000, uint256S("0x00000000386795b9fa21f14782ee1b9176763d6a544d7e0511d1860c62d540aa")) + ( 2000000, uint256S("0x0b0403fbe3c5742bbd0e3fc643049534e50c4a49bbc4a3b284fc0ecedf15c044")) + ( 2050000, uint256S("0x0c7923957469864d49a0be56b5ffbee7f21c1b6d00acc7374f60f1c1c7b87e14")) + ( 2100000, uint256S("0x05725ed166ae796529096ac2a42e85a3bdd0d69dbb2f69e620c08219fda1130a")) + ( 2150000, uint256S("0x0edb94f5a5501fc8dd72a455cdaccf0af0215b914dd3d8d4ae5d644e27ef562c")) + ( 2200000, uint256S("0x08b92203aa4a3b09001a75e8eebe8e64434259ae7ed7a31384203924d1ab03b8")) + ( 2250000, uint256S("0x0127d1ed5cd6f261631423275b6b17728c392583177e1151a6e638a4b0dea985")) + ( 2300000, uint256S("0x07df8af646bc30c71d068b146d9ea2c8b25b27a180e9537d5aef859efcfc41f7")) + ( 2350000, uint256S("0x0b8028dbfcd92fe34496953872cba2d256923e3e52b4abbdcbe9911071e929e5")) + ( 2400000, uint256S("0x0000000030f4e55dab91dc3528257fdddbbaec7e7e6f877d357654f07704d773")) + ( 2450000, uint256S("0x00000000b1cb8e9046e561486a5dbdb7fa06ac35c96f290653d1f0f4578d55c0")) + ( 2453333, uint256S("0x0183557e5d92b5337e005499f5e0f58c8c6a02756b55ad56f2be4792d38351bd")), + 1624689070, // * UNIX timestamp of last checkpoint block + 14279227, // * total number of transactions between genesis and last checkpoint + // (the tx=... number in the SetBestChain debug.log lines) + 2777 // * estimated number of transactions per day after checkpoint + // total number of tx / (checkpoint block height / (24 * 24)) + }; + + genesisNotaries = { + { "jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, + { "jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, + { "pondsea_SH", "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" }, + { "crackers_EU", "0340c66cf2c41c41efb420af57867baa765e8468c12aa996bfd816e1e07e410728" }, + { "pondsea_EU", "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" }, + { "locomb_EU", "025c6d26649b9d397e63323d96db42a9d3caad82e1d6076970efe5056c00c0779b" }, + { "fullmoon_AE", "0204a908350b8142698fdb6fabefc97fe0e04f537adc7522ba7a1e8f3bec003d4a" }, + { "movecrypto_EU", "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" }, + { "badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, + { "crackers_NA", "029e1c01131974f4cd3f564cc0c00eb87a0f9721043fbc1ca60f9bd0a1f73f64a1" }, + { "proto_EU", "03681ffdf17c8f4f0008cefb7fa0779c5e888339cdf932f0974483787a4d6747c1" }, // 10 + { "jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, + { "farl4web_EU", "035caa40684ace968677dca3f09098aa02b70e533da32390a7654c626e0cf908e1" }, + { "nxtswe_EU", "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" }, + { "traderbill_EU", "03196e8de3e2e5d872f31d79d6a859c8704a2198baf0af9c7b21e29656a7eb455f" }, + { "vanbreuk_EU", "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" }, // 15 + { "titomane_EU", "03517fcac101fed480ae4f2caf775560065957930d8c1facc83e30077e45bdd199" }, + { "supernet_AE", "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" }, + { "supernet_EU", "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" }, + { "supernet_NA", "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" }, + { "yassin_EU", "033fb7231bb66484081952890d9a03f91164fb27d392d9152ec41336b71b15fbd0" }, // 20 + { "durerus_EU", "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" }, + { "badass_SH", "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" }, + { "badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, + { "pondsea_NA", "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" }, + { "rnr_EU", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" }, + { "crackers_SH", "02313d72f9a16055737e14cfc528dcd5d0ef094cfce23d0348fe974b6b1a32e5f0" }, + { "grewal_SH", "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" }, + { "polycryptoblock_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, + { "titomane_NA", "0387046d9745414fb58a0fa3599078af5073e10347e4657ef7259a99cb4f10ad47" }, + { "titomane_AE", "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" }, + { "kolo_EU", "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" }, + { "artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, + { "eclips_EU", "0339369c1f5a2028d44be7be6f8ec3b907fdec814f87d2dead97cab4edb71a42e9" }, + { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, + }; + + } // ctor }; static CMainParams mainParams; @@ -256,7 +352,7 @@ class CTestNetParams : public CChainParams { public: CTestNetParams() { strNetworkID = "test"; - strCurrencyUnits = "TAZ"; + strCurrencyUnits = "TKMD"; bip44CoinType = 1; consensus.fCoinbaseMustBeProtected = true; consensus.nSubsidySlowStartInterval = 20000; @@ -264,8 +360,8 @@ class CTestNetParams : public CChainParams { consensus.nMajorityEnforceBlockUpgrade = 51; consensus.nMajorityRejectBlockOutdated = 75; consensus.nMajorityWindow = 400; - consensus.powLimit = uint256S("07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - consensus.powAlternate = uint256S("07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.powLimit = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); + consensus.powAlternate = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); consensus.nPowAveragingWindow = 17; assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); consensus.nMaxFutureBlockTime = 7 * 60; @@ -291,9 +387,6 @@ class CTestNetParams : public CChainParams { consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170007; consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = 280000; - // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000000001d0c4d9cd"); - pchMessageStart[0] = 0x5A; pchMessageStart[1] = 0x1F; pchMessageStart[2] = 0x7E; @@ -308,22 +401,20 @@ class CTestNetParams : public CChainParams { nEquihashK = K; //! Modify the testnet genesis block so the timestamp is valid for a later start. - genesis.nTime = 1296688602; - genesis.nBits = KOMODO_MINDIFF_NBITS; - genesis.nNonce = uint256S("0x0000000000000000000000000000000000000000000000000000000000000009"); - genesis.nSolution = ParseHex("003423da3e41f916bf3ff0ee770eb844a240361abe08a8c9d46bd30226e2ad411a4047b6ddc230d173c60537e470e24f764120f5a2778b2a1285b0727bf79a0b085ad67e6266fb38fd72ef17f827315c42f921720248c983d4100e6ebd1c4b5e8762a973bac3bec7f7153b93752ebbb465f0fc9520bcfc30f9abfe303627338fed6ede9cf1b9173a736cf270cf4d9c6999ff4c3a301a78fd50dab6ccca67a0c5c2e41f216a1f3efd049a74bbe6252f9773bc309d3f9e554d996913ce8e1cec672a1fa4ea59726b61ea9e75d5ce9aa5dbfa96179a293810e02787f26de324fe7c88376ff57e29574a55faff7c2946f3e40e451861c32bf67da7377de3136858a18f34fab1bc8da37726ca2c25fc7b312a5427554ec944da81c7e27255d6c94ade9987ff7daedc2d1cc63d7d4cf93e691d13326fb1c7ee72ccdc0b134eb665fc6a9821e6fef6a6d45e4aac6dca6b505a0100ad56ea4f6fa4cdc2f0d1b65f730104a515172e34163bdb422f99d083e6eb860cf6b3f66642c4dbaf0d0fa1dca1b6166f1d1ffaa55a9d6d6df628afbdd14f1622c1c8303259299521a253bc28fcc93676723158067270fc710a09155a1e50c533e9b79ed5edba4ab70a08a9a2fc0eef0ddae050d75776a9804f8d6ad7e30ccb66c6a98d86710ca7a4dfb4feb159484796b9a015c5764aa3509051c87f729b9877ea41f8b470898c01388ed9098b1e006d3c30fc6e7c781072fa3f75d918505ee8ca75840fc62f67c57060666aa42578a2dd022eda62e3f1e447d7364074d34fd60ad9b138f60422afa6cfcb913fd6c213b496144dbfda7bfc7c24540cfe40ad0c0fd5a8c0902127f53d3178ba1b2a87bf1224d53d3a15e49ccdf121ae872a011c996d1b9793153cdcd4c0a7e99f8a35669788551cca2b62769eda24b6b55e2f4e0ac0d30aa50ecf33c6cdb24adfc922006a7bf434ced800fefe814c94c6fc8caa37b372d5088bb31d2f6b11a7a67ad3f70abbac0d5c256b637828de6cc525978cf151a2e50798e0c591787639a030291272c9ced3ab7d682e03f8c7db51f60163baa85315789666ea8c5cd6f789a7f4a5de4f8a9dfefce20f353cec606492fde8eab3e3b487b3a3a57434f8cf252a4b643fc125c8a5948b06744f5dc306aa587bdc85364c7488235c6edddd78763675e50a9637181519be06dd30c4ba0d845f9ba320d01706fd6dd64d1aa3cd4211a4a7d1d3f2c1ef2766d27d5d2cdf8e7f5e3ea309d4f149bb737305df1373a7f5313abe5986f4aa620bec4b0065d48aafac3631de3771f5c4d2f6eec67b09d9c70a3c1969fecdb014cb3c69832b63cc9d6efa378bff0ef95ffacdeb1675bb326e698f022c1a3a2e1c2b0f05e1492a6d2b7552388eca7ee8a2467ef5d4207f65d4e2ae7e33f13eb473954f249d7c20158ae703e1accddd4ea899f026618695ed2949715678a32a153df32c08922fafad68b1895e3b10e143e712940104b3b352369f4fe79bd1f1dbe03ea9909dbcf5862d1f15b3d1557a6191f54c891513cdb3c729bb9ab08c0d4c35a3ed67d517ffe1e2b7a798521aed15ff9822169c0ec860d7b897340bc2ef4c37f7eb73bd7dafef12c4fd4e6f5dd3690305257ae14ed03df5e3327b68467775a90993e613173fa6650ffa2a26e84b3ce79606bf234eda9f4053307f344099e3b10308d3785b8726fd02d8e94c2759bebd05748c3fe7d5fe087dc63608fb77f29708ab167a13f32da251e249a544124ed50c270cfc6986d9d1814273d2f0510d0d2ea335817207db6a4a23ae9b079967b63b25cb3ceea7001b65b879263f5009ac84ab89738a5b8b71fd032beb9f297326f1f5afa630a5198d684514e242f315a4d95fa6802e82799a525bb653b80b4518ec610a5996403b1391"); + genesis = CreateGenesisBlock(1296688602, + uint256S("0x000000000000000000000000000000000000000000000000000000000000000a"), + ParseHex("008b6bd48ca3ef23bfa3d34885483158e089ad887539fd33950f2d78d5720e39769165aa7b2c679b65060e209249f54e3279e8bf31ec13781184b109aaee6e3db57260b466ce8182122b564ce43ca77b011ea1fa038f0139e98e923b0eb1929a80b622cdb72cd5505f275b7cf0e89892ff37f53b010f5ba1fb78bedead4a0c4d39f8319605d358e36a0a0e5e5cdb25a2ffff9320f57569f7270857e2d87287fa71c24d36611b2ac502ffffdbbe425ca71b09b1f0255a66f26356fae7f210227d79e3ea9fe99f7d5e5b05febdf3a54dfec02507bdb85ff409773ce56441191734059a11d9d4c481554fbe6c93b1a93be2cfc707d146e4c28966de5ced066fc85f548fd146c9cd086fafdbf982c3c099394e0a25a5e4670dea2673e84886f5fa765a8a5f1ff3a307680a20e520b1f3d21714eb3efca769f182106a6d193aae881461a64b55d98668eb7f7b92c3527eb75b044d01ffff427d9157c301e5b69fa09776009f53c30551484020fabbb3d664c106d72844b540c133bc67048ad4ca0082ad42848e146dac76b55e3ba51937c412c817034e1e67fb3d909347d42d198599f28df8ee0fa9bd9c180beb0fad03f265a8bbbfb6ce1bff1d8223c9ea28748983393fbf1b8364e449d331b8ffb8363dfab5728c5f34b1e4cd03e3a758c3e5280994a44a47fed5f84b13bc67df9074dac4b7288d927e1b8ef50a7afc01ea4b798d6025415f26d15dc506c96896b530af775fb3648ddf983f59bb10536e1e74a6bee4640ed3275bbdceb79520ec81618ac7087e06baba12432671e185b6e1706523edd26d07435bf5289c5f703f0b6703fbfc56e46b421ca9ca325e281387353daa33274925b44ea4a7c939ef13ec6f38941ed13c7a9ae5253dba2119a0b8b1401f73d503e2c7252dd9507d305cf9dcb5f3db29214bb6c7be8b5654421baefbdc7701408f5ab4d652879d54e4e4ad6dc3c1b49835ae7e2ca806e302d33657ada2c8b86b716a239d409fafdb05a547952f6aafd5d9dd60f76070b0ee12605815ad36fca1c3bc231b15428ce6412fd37d2f27255eb19b060aadf47e0c1b67b0911459505bc9fdfd1875fdac31362dd434ab4e297b9478b74f5efdaac35e7b3deb07b2125aaf07483dd104d6e43161506a0e1b14fd7a13b729f771ca5e2a5e53c2d6eb96f66a66a4581c87018fa98856630ab1dead01afbe62c280c697d96e6d056afb94a4cca2e6d63bc866f5dceb9a5d2a38b3bb11e109de75d17e6116aad2514b5ababe09f99ddf2c130cdd7866129fa103cdb2ec9d2a44853c8bf9c31201ec1b89cca7f31542da558f57645c4e897e9e9d1038be3a796eaf1cafa8f6d69897426c5e7b8f3933c004eb3113898ac5295fb31245494b63fdf5227ece5714a13469fd86ec944b8b9924cc67ab86561f73fdb3060c8acf9a255ca96834038ef1383f69733876bc7f2524ebe92eb01049bc6863835220a555e496bb17e7067d3427f209fb00a46e48082a549af2fdd23cc7cc0b96923fd695642389a1db1a457ac5874f7c5c62e407ba7a7248f04807c516c0ba5c08194d3f1b1fa78f0841f062529d5d9354091d8fb9fecb777df7bd3508174f66a13f1d7d272cd4145762b25841ae9c3e9351209ac43d2dcb542d4ccd64b19367b56d7772fed9b00630fe9567036fd4bb1d67d2665c12c2547fd4a112128512ea4bf1d9d1f68d421c3bde90d8c22cde1aa40a257a8a0089b9b4e8aff50fb2d41cf152be7ecc892ffaa22d162a50e1f24be74207756c46370531cf9f07094d789c8758f9260214cbe6463376cc6f5fb26211740a59a68a97d27bb7e152f91d0ff8f431d3569e08420d79e957df36d4e2c601406046df386abf944f19730acd2b4bbd715cd321c7f54c8e61bf2cf73019"), + KOMODO_MINDIFF_NBITS, 1, COIN); consensus.hashGenesisBlock = genesis.GetHash(); - //assert(consensus.hashGenesisBlock == uint256S("0x05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38")); vFixedSeeds.clear(); vSeeds.clear(); - //vSeeds.push_back(CDNSSeedData("z.cash", "dns.testnet.z.cash")); // Komodo - base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,0); - base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,5); - base58Prefixes[SECRET_KEY] = std::vector(1,128); - base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container >(); - base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container >(); + base58Prefixes[PUBKEY_ADDRESS] = {0}; + base58Prefixes[SCRIPT_ADDRESS] = {5}; + base58Prefixes[SECRET_KEY] = {128}; + base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; + base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; base58Prefixes[ZCPAYMENT_ADDRRESS] = {20,81}; // guarantees the first 4 characters, when base58 encoded, are "ZiVt" base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAC,0x0C}; @@ -343,16 +434,8 @@ class CTestNetParams : public CChainParams { fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = true; - - checkpointData = //(CCheckpointData) - { - boost::assign::map_list_of - (0, consensus.hashGenesisBlock) - (38000, uint256S("0x001e9a2d2e2892b88e9998cf7b079b41d59dd085423a921fe8386cecc42287b8")), - 1486897419, // * UNIX timestamp of last checkpoint block - 47163, // * total number of transactions between genesis and last checkpoint - // (the tx=... number in the SetBestChain debug.log lines) - 715 // total number of tx / (checkpoint block height / (24 * 24)) + genesisNotaries = { + { "jmj_testA", "037c032430fd231b5797cb4a637dae3eadf87b10274fd84be31670bd2a02c4fbc5" } }; } }; @@ -397,9 +480,7 @@ class CRegTestParams : public CChainParams { consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170006; consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; - - // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x00"); + coinbaseMaturity = 1; pchMessageStart[0] = 0xaa; pchMessageStart[1] = 0x8e; @@ -417,8 +498,6 @@ class CRegTestParams : public CChainParams { 1296688602, uint256S("0x0000000000000000000000000000000000000000000000000000000000000009"), ParseHex("01936b7db1eb4ac39f151b8704642d0a8bda13ec547d54cd5e43ba142fc6d8877cab07b3"), - - KOMODO_MINDIFF_NBITS, 4, 0); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0x029f11d80ef9765602235e1bc9727e3eb6ba20839319f761fee920d63401e327")); @@ -436,10 +515,10 @@ class CRegTestParams : public CChainParams { fMineBlocksOnDemand = true; fTestnetToBeDeprecatedFieldRPC = false; - checkpointData = //(CCheckpointData) - { - boost::assign::map_list_of - ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")), + checkpointData = (CCheckpointData){ + MapCheckpoints { + {0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")} + }, 0, 0, 0 @@ -574,10 +653,8 @@ void komodo_setactivation(int32_t height) void *chainparams_commandline() { - LogPrintf("chainparams_commandline called\n"); CChainParams::CCheckpointData checkpointData; - //LogPrintf(">>>>>>>> port.%u\n",ASSETCHAINS_P2PPORT); - if ( ASSETCHAINS_SYMBOL[0] != 0 ) + if ( !chainName.isKMD() ) { if ( ASSETCHAINS_BLOCKTIME != 60 ) { @@ -587,7 +664,6 @@ void *chainparams_commandline() pCurrentParams->SetDefaultPort(ASSETCHAINS_P2PPORT); if ( ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0 ) { - //BOOST_STATIC_ASSERT(equihash_parameters_acceptable(ASSETCHAINS_NK[0], ASSETCHAINS_NK[1])); pCurrentParams->SetNValue(ASSETCHAINS_NK[0]); pCurrentParams->SetKValue(ASSETCHAINS_NK[1]); } @@ -599,85 +675,25 @@ void *chainparams_commandline() pCurrentParams->pchMessageStart[1] = (ASSETCHAINS_MAGIC >> 8) & 0xff; pCurrentParams->pchMessageStart[2] = (ASSETCHAINS_MAGIC >> 16) & 0xff; pCurrentParams->pchMessageStart[3] = (ASSETCHAINS_MAGIC >> 24) & 0xff; - LogPrintf(">>>>>>>>>> %s: p2p.%u rpc.%u magic.%08x %u %u coins\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_MAGIC,ASSETCHAINS_MAGIC,(uint32_t)ASSETCHAINS_SUPPLY); + LogPrintf(">>>>>>>>>> %s: p2p.%u rpc.%u magic.%08x %u %u coins\n",chainName.symbol().c_str(),ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_MAGIC,ASSETCHAINS_MAGIC,(uint32_t)ASSETCHAINS_SUPPLY); pCurrentParams->consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = ASSETCHAINS_SAPLING; pCurrentParams->consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = ASSETCHAINS_OVERWINTER; - checkpointData = //(Checkpoints::CCheckpointData) + checkpointData = { - boost::assign::map_list_of - (0, pCurrentParams->consensus.hashGenesisBlock), + MapCheckpoints { + {0, pCurrentParams->consensus.hashGenesisBlock}, + }, (int64_t)1231006505, (int64_t)1, - (double)2777 // * estimated number of transactions per day after checkpoint + (double)2777 // * estimated number of transactions per day after checkpoint // total number of tx / (checkpoint block height / (24 * 24)) }; } else { - checkpointData = // (Checkpoints::CCheckpointData) - { - boost::assign::map_list_of - - (0, pCurrentParams->consensus.hashGenesisBlock) - ( 50000, uint256S("0x00076e16d3fa5194da559c17cf9cf285e21d1f13154ae4f7c7b87919549345aa")) - ( 100000, uint256S("0x0f02eb1f3a4b89df9909fec81a4bd7d023e32e24e1f5262d9fc2cc36a715be6f")) - ( 150000, uint256S("0x0a817f15b9da636f453a7a01835cfc534ed1a55ce7f08c566471d167678bedce")) - ( 200000, uint256S("0x000001763a9337328651ca57ac487cc0507087be5838fb74ca4165ff19f0e84f")) - ( 250000, uint256S("0x0dd54ef5f816c7fde9d2b1c8c1a26412b3c761cc5dd3901fa5c4cd1900892fba")) - ( 300000, uint256S("0x000000fa5efd1998959926047727519ed7de06dcf9f2cd92a4f71e907e1312dc")) - ( 350000, uint256S("0x0000000228ef321323f81dae00c98d7960fc7486fb2d881007fee60d1e34653f")) - ( 400000, uint256S("0x036d294c5be96f4c0efb28e652eb3968231e87204a823991a85c5fdab3c43ae6")) - ( 450000, uint256S("0x0906ef1e8dc194f1f03bd4ce1ac8c6992fd721ef2c5ccbf4871ec8cdbb456c18")) - ( 500000, uint256S("0x0bebdb417f7a51fe0c36fcf94e2ed29895a9a862eaa61601272866a7ecd6391b")) - ( 550000, uint256S("0x06df52fc5f9ba03ccc3a7673b01ab47990bd5c4947f6e1bc0ba14d21cd5bcccd")) - ( 600000, uint256S("0x00000005080d5689c3b4466e551cd1986e5d2024a62a79b1335afe12c42779e4")) - ( 650000, uint256S("0x039a3cb760cc6e564974caf69e8ae621c14567f3a36e4991f77fd869294b1d52")) - ( 700000, uint256S("0x00002285be912b2b887a5bb42d2f1aa011428c565b0ffc908129c47b5ce87585")) - ( 750000, uint256S("0x04cff4c26d185d591bed3613ce15e1d15d9c91dd8b98a6729f89c58ce4bd1fd6")) - ( 800000, uint256S("0x0000000617574d402fca8e6570f0845bd5fe449398b318b4e1f65bc69cdd6606")) - ( 850000, uint256S("0x044199301f37194f20ba7b498fc72ed742f6c0ba6e476f28d6c81d225e58d5ce")) - ( 900000, uint256S("0x08bdbe4de2a65ac89fd2913192d05362c900e3af476a0c99d9f311875067451e")) - ( 950000, uint256S("0x0000000aa9a44b593e6138f247bfae75bd43b9396ef9ff0a6a3ebd852f131806")) - ( 1000000, uint256S("0x0cb1d2457eaa58af5028e86e27ac54578fa09558206e7b868ebd35e7005ed8bb")) - ( 1050000, uint256S("0x044d49bbc3bd9d32b6288b768d4f7e0afe3cbeda606f3ac3579a076e4bddf6ae")) - ( 1100000, uint256S("0x000000050cad04887e170059dd2556d85bbd20390b04afb9b07fb62cafd647b4")) - ( 1150000, uint256S("0x0c85501c759d957dd1ccc5f7fdfcc415c89c7f2a26471fffc75b75f79e63c16a")) - ( 1200000, uint256S("0x0763cbf43ed7227988081c29d9e9fc7ab2450216e6d0354cc4596c86689702d4")) - ( 1250000, uint256S("0x0489640207f8c343a56a10e45d987516059ea82a3c6859a771b3a9cf94f5c3bb")) - ( 1300000, uint256S("0x000000012a01709b254b4f75e2b9ed772d8fe558655c8c859892ca8c9d625e87")) - ( 1350000, uint256S("0x075a1a5c66a68b47d9848ca6986687ed2665b1852457051bf142208e62f98a60")) - ( 1400000, uint256S("0x055f73dd9b20650c3d6e6dbb606af8d9479e4c81d89430867abff5329f167bb2")) - ( 1450000, uint256S("0x014c2926e07e9712211c5e82f05df1b802c59cc8bc24e3cc9b09942017080f2d")) - ( 1500000, uint256S("0x0791f892210ce3c513ab607d689cd1e8907a27f3dfeb58dec21ae299b7981cb7")) - ( 1550000, uint256S("0x08fcbaffb7164b161a25efc6dd5c70b679498ee637d663fe201a55c7decc37a3")) - ( 1600000, uint256S("0x0e577dcd49319a67fe2acbb39ae6d46afccd3009d3ba9d1bcf6c624708e12bac")) - ( 1650000, uint256S("0x091ac57a0f786a9526b2224a10b62f1f464b9ffc0afc2240d86264439e6ad3d0")) - ( 1700000, uint256S("0x0d0be6ab4a5083ce9d2a7ea2549b03cfc9770427b7d51c0bf0c603399a60d037")) - ( 1750000, uint256S("0x0a019d830157db596eeb678787279908093fd273a4e022b5e052f3a9f95714ca")) - ( 1800000, uint256S("0x0390779f6c615620391f9dd7df7f3f4947523bd6350b26625c0315571c616076")) - ( 1850000, uint256S("0x000000007ca2de1bd9cb7b52fe0accca4874143822521d955e58c73e304279e0")) - ( 1900000, uint256S("0x04c6589d5703f8237bf215c4e3e881c1c77063ef079cea5dc132a0e7f7a0cbd9")) - ( 1950000, uint256S("0x00000000386795b9fa21f14782ee1b9176763d6a544d7e0511d1860c62d540aa")) - ( 2000000, uint256S("0x0b0403fbe3c5742bbd0e3fc643049534e50c4a49bbc4a3b284fc0ecedf15c044")) - ( 2050000, uint256S("0x0c7923957469864d49a0be56b5ffbee7f21c1b6d00acc7374f60f1c1c7b87e14")) - ( 2100000, uint256S("0x05725ed166ae796529096ac2a42e85a3bdd0d69dbb2f69e620c08219fda1130a")) - ( 2150000, uint256S("0x0edb94f5a5501fc8dd72a455cdaccf0af0215b914dd3d8d4ae5d644e27ef562c")) - ( 2200000, uint256S("0x08b92203aa4a3b09001a75e8eebe8e64434259ae7ed7a31384203924d1ab03b8")) - ( 2250000, uint256S("0x0127d1ed5cd6f261631423275b6b17728c392583177e1151a6e638a4b0dea985")) - ( 2300000, uint256S("0x07df8af646bc30c71d068b146d9ea2c8b25b27a180e9537d5aef859efcfc41f7")) - ( 2350000, uint256S("0x0b8028dbfcd92fe34496953872cba2d256923e3e52b4abbdcbe9911071e929e5")) - ( 2400000, uint256S("0x0000000030f4e55dab91dc3528257fdddbbaec7e7e6f877d357654f07704d773")) - ( 2450000, uint256S("0x00000000b1cb8e9046e561486a5dbdb7fa06ac35c96f290653d1f0f4578d55c0")) - ( 2453333, uint256S("0x0183557e5d92b5337e005499f5e0f58c8c6a02756b55ad56f2be4792d38351bd")), - - 1624689070, // * UNIX timestamp of last checkpoint block - 14279227, // * total number of transactions between genesis and last checkpoint - // (the tx=... number in the SetBestChain debug.log lines) - 2777 // * estimated number of transactions per day after checkpoint - // total number of tx / (checkpoint block height / (24 * 24)) - }; + checkpointData = pCurrentParams->Checkpoints(); } pCurrentParams->SetCheckpointData(checkpointData); diff --git a/src/chainparams.h b/src/chainparams.h index daa16af8..30eb9f56 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -30,11 +30,17 @@ #include +/**** + * DNS seed info + */ struct CDNSSeedData { std::string name, host; CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {} }; +/**** + * IPv6 seed info + */ struct SeedSpec6 { uint8_t addr[16]; uint16_t port; @@ -82,62 +88,151 @@ class CChainParams MAX_BECH32_TYPES }; + /**** + * @returns parameters that influence chain consensus + */ const Consensus::Params& GetConsensus() const { return consensus; } + /*** + * Message header start bytes + * @returns 4 bytes + */ const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } + /**** + * @returns bytes of public key that signs broadcast alert messages + */ const std::vector& AlertKey() const { return vAlertPubKey; } + /*** + * @returns default TCP port for P2P connections + */ int GetDefaultPort() const { return nDefaultPort; } + /*** + * @returns the first block of the chain + */ const CBlock& GenesisBlock() const { return genesis; } - /** Make miner wait to have peers to avoid wasting work */ + /** + * Make miner wait to have peers to avoid wasting work + * @returns true if peers are required before mining begins + */ bool MiningRequiresPeers() const { return fMiningRequiresPeers; } - /** Default value for -checkmempool and -checkblockindex argument */ + /** + * Default value for -checkmempool and -checkblockindex argument + * @returns true if mempool and indexes should be checked by default + */ bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; } - /** Policy: Filter transactions that do not match well-defined patterns */ + /** + * Policy: Filter transactions that do not match well-defined patterns + * @returns true to filter, false to be permissive + */ bool RequireStandard() const { return fRequireStandard; } + /**** + * @returns height where pruning should happen + */ int64_t PruneAfterHeight() const { return nPruneAfterHeight; } + /**** + * @returns N value for equihash algo + */ unsigned int EquihashN() const { return nEquihashN; } + /*** + * @returns K value for equihash algo + */ unsigned int EquihashK() const { return nEquihashK; } + /**** + * @returns currency units (i.e. "KMD", "REG", "TAZ" + */ std::string CurrencyUnits() const { return strCurrencyUnits; } + /**** + * @ref https://github.com/satoshilabs/slips/blob/master/slip-0044.md + * @returns coin identifier for this chain + */ uint32_t BIP44CoinType() const { return bip44CoinType; } - /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ + /** + * Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated + * @returns true if on-demand block mining is allowed (true for RegTest, should probably be false for all others) + */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } - /** In the future use NetworkIDString() for RPC fields */ + /** + * Deprecated. Use NetworkIDString() to identify the network + * @returns true if testnet + */ bool TestnetToBeDeprecatedFieldRPC() const { return fTestnetToBeDeprecatedFieldRPC; } - /** Return the BIP70 network string (main, test or regtest) */ + /** + * Return the BIP70 network string ("main", "test" or "regtest") + * @returns the network ID + */ std::string NetworkIDString() const { return strNetworkID; } + /**** + * @returns a vector of DNS entries to get seed data + */ const std::vector& DNSSeeds() const { return vSeeds; } + /*** + * @param the type (i.e. PUBKEY_ADDRESS, SCRIPT_ADDRESS) + * @returns prefix bytes to common encoded strings + */ const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } + /**** + * @returns the Human Readable Part of a particular type of Bech32 data + */ const std::string& Bech32HRP(Bech32Type type) const { return bech32HRPs[type]; } + /**** + * Use in case of problems with DNS + * @returns hard-coded IPv6 addresses of seed nodes + */ const std::vector& FixedSeeds() const { return vFixedSeeds; } + const std::vector > GenesisNotaries() const { return genesisNotaries; } const CCheckpointData& Checkpoints() const { return checkpointData; } - /** Return the founder's reward address and script for a given block height */ + /** + * @returns the founder's reward address for a given block height + */ std::string GetFoundersRewardAddressAtHeight(int height) const; + /*** + * @returns the founder's reward script for a given block height + */ CScript GetFoundersRewardScriptAtHeight(int height) const; + /*** + * @param i the index + * @returns the founder's reward address + */ std::string GetFoundersRewardAddressAtIndex(int i) const; - /** Enforce coinbase consensus rule in regtest mode */ + /** + * Enforce coinbase consensus rule in regtest mode + */ void SetRegTestCoinbaseMustBeProtected() { consensus.fCoinbaseMustBeProtected = true; } + /*** + * Set the default P2P IP port + * @param port the new port + */ void SetDefaultPort(uint16_t port) { nDefaultPort = port; } + /*** + * @param checkpointData the new data + */ void SetCheckpointData(CCheckpointData checkpointData); + /*** + * @param n the new N value for equihash + */ void SetNValue(uint64_t n) { nEquihashN = n; } + /**** + * @param k the new K value for equihash + */ void SetKValue(uint64_t k) { nEquihashK = k; } + /**** + * @param flag true to require connected peers before mining can begin + */ void SetMiningRequiresPeers(bool flag) { fMiningRequiresPeers = flag; } + uint32_t CoinbaseMaturity() const { return coinbaseMaturity; } + void SetCoinbaseMaturity(uint32_t in) const { coinbaseMaturity = in; } - //void setnonce(uint32_t nonce) { memcpy(&genesis.nNonce,&nonce,sizeof(nonce)); } - //void settimestamp(uint32_t timestamp) { genesis.nTime = timestamp; } - //void setgenesis(CBlock &block) { genesis = block; } - //void recalc_genesis(uint32_t nonce) { genesis = CreateGenesisBlock(ASSETCHAINS_TIMESTAMP, nonce, GENESIS_NBITS, 1, COIN); }; - CMessageHeader::MessageStartChars pchMessageStart; // jl777 moved - Consensus::Params consensus; + CMessageHeader::MessageStartChars pchMessageStart; // message header start bytes + Consensus::Params consensus; // parameters that influence consensus protected: CChainParams() {} - //! Raw pub key bytes for the broadcast alert signing key. - std::vector vAlertPubKey; - int nMinerThreads = 0; + std::vector vAlertPubKey; // Raw pub key bytes for the broadcast alert signing key + int nMinerThreads = 0; // number of mining threads long nMaxTipAge = 0; - int nDefaultPort = 0; + int nDefaultPort = 0; // p2p uint64_t nPruneAfterHeight = 0; unsigned int nEquihashN = 0; unsigned int nEquihashK = 0; @@ -156,29 +251,42 @@ class CChainParams bool fTestnetToBeDeprecatedFieldRPC = false; CCheckpointData checkpointData; std::vector vFoundersRewardAddress; + mutable uint32_t coinbaseMaturity = 100; // allow to modify by -ac_cbmaturity + std::vector< std::pair > genesisNotaries; }; /** - * Return the currently selected parameters. This won't change after app - * startup, except for unit tests. + * NOTE: This won't change after app startup (except for unit tests) + * @returns the currently selected parameters for this chain */ const CChainParams &Params(); -/** Return parameters for the given network. */ +/** + * @param network the network + * @returns parameters for the given network. + */ CChainParams &Params(CBaseChainParams::Network network); -/** Sets the params returned by Params() to those for the given network. */ +/** + * Sets the params returned by Params() to those for the given network. + * @param network the network to use + */ void SelectParams(CBaseChainParams::Network network); /** * Looks for -regtest or -testnet and then calls SelectParams as appropriate. - * Returns false if an invalid combination is given. + * @returns false if an invalid combination is given. */ bool SelectParamsFromCommandLine(); /** * Allows modifying the network upgrade regtest parameters. + * @param idx the index of the new parameters + * @param nActivationHeight when to activate */ void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight); +void komodo_setactivation(int32_t height); +int32_t MAX_BLOCK_SIZE(int32_t height); + #endif // BITCOIN_CHAINPARAMS_H diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index 94e3a423..0d6df592 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -38,7 +38,14 @@ class CBaseChainParams MAX_NETWORK_TYPES }; + /*** + * @brief returns the subdirectory for the network + * @return the data subdirectory ( nothing, or "testnet3" or "regtest" ) + */ const std::string& DataDir() const { return strDataDir; } + /**** + * @returns the port used for RPC calls + */ int RPCPort() const { return nRPCPort; } protected: @@ -49,29 +56,31 @@ class CBaseChainParams }; /** - * Return the currently selected parameters. This won't change after app - * startup, except for unit tests. + * NOTE: These params should not change after startup (except for unit tests) + * @returns the currently selected parameters */ const CBaseChainParams& BaseParams(); -/** Sets the params returned by Params() to those for the given network. */ +/** + * Sets the params returned by Params() to those for the given network. + * @param network the network you wish to use + */ void SelectBaseParams(CBaseChainParams::Network network); /** * Looks for -regtest or -testnet and returns the appropriate Network ID. - * Returns MAX_NETWORK_TYPES if an invalid combination is given. + * @returns Network ID or MAX_NETWORK_TYPES if an invalid combination is given */ CBaseChainParams::Network NetworkIdFromCommandLine(); /** * Calls NetworkIdFromCommandLine() and then calls SelectParams as appropriate. - * Returns false if an invalid combination is given. + * @returns false if an invalid combination is given. */ bool SelectBaseParamsFromCommandLine(); /** - * Return true if SelectBaseParamsFromCommandLine() has been called to select - * a network. + * @returns true if SelectBaseParamsFromCommandLine() has been called */ bool AreBaseParamsConfigured(); diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 026475f8..9ec509a2 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -18,13 +18,9 @@ ******************************************************************************/ #include "checkpoints.h" - -#include "chainparams.h" #include "main.h" -#include "uint256.h" #include - #include namespace Checkpoints { @@ -38,17 +34,33 @@ namespace Checkpoints { * fast multicore CPU, it won't be much higher than 1. */ static const double SIGCHECK_VERIFICATION_FACTOR = 5.0; + + /****** + * @param data the collection of checkpoints + * @param nHeight the height + * @param hash the expected hash at nHight + * @returns true if the checkpoint at nHeight is not found or hash matches the found checkpoint + */ bool CheckBlock(const CChainParams::CCheckpointData& data, int nHeight, const uint256& hash) { const MapCheckpoints& checkpoints = data.mapCheckpoints; MapCheckpoints::const_iterator i = checkpoints.find(nHeight); - if (i == checkpoints.end()) return true; + if (i == checkpoints.end()) + return true; return hash == i->second; } - //! Guess how far we are in the verification process at the given block index - double GuessVerificationProgress(const CChainParams::CCheckpointData& data, CBlockIndex *pindex, bool fSigchecks) { + /****** + * @brief Guess how far we are in the verification process at the given block index + * @param data the checkpoint collection + * @param pindex the block index + * @param fsigchecks true to include signature checks in the calculation + * @returns + */ + double GuessVerificationProgress(const CChainParams::CCheckpointData& data, + CBlockIndex *pindex, bool fSigchecks) + { if (pindex==NULL) return 0.0; @@ -77,6 +89,11 @@ namespace Checkpoints { return std::min(fWorkBefore / (fWorkBefore + fWorkAfter), 1.0); } + /***** + * @brief Return conservative estimate of total number of blocks, 0 if unknown + * @param data the collection of checkpoints + * @returns the number of blocks + */ int GetTotalBlocksEstimate(const CChainParams::CCheckpointData& data) { const MapCheckpoints& checkpoints = data.mapCheckpoints; @@ -87,6 +104,10 @@ namespace Checkpoints { return checkpoints.rbegin()->first; } + /****** + * @param data the collection of checkpoints + * @returns last CBlockIndex* in mapBlockIndex that is a checkpoint (can be nullptr) + */ CBlockIndex* GetLastCheckpoint(const CChainParams::CCheckpointData& data) { const MapCheckpoints& checkpoints = data.mapCheckpoints; @@ -98,7 +119,7 @@ namespace Checkpoints { if (t != mapBlockIndex.end()) return t->second; } - return NULL; + return nullptr; } } // namespace Checkpoints diff --git a/src/checkpoints.h b/src/checkpoints.h index 1b21755f..92ed7020 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -34,26 +34,36 @@ struct CCheckpointData; */ namespace Checkpoints { - - typedef std::map MapCheckpoints; - -struct CCheckpointData { - MapCheckpoints mapCheckpoints; - int64_t nTimeLastCheckpoint; - int64_t nTransactionsLastCheckpoint; - double fTransactionsPerDay; -}; + /****** + * @param data the collection of checkpoints + * @param nHeight the height + * @param hash the expected hash at nHight + * @returns true if the checkpoint at nHeight is not found or hash matches the found checkpoint + */ bool CheckBlock(const CChainParams::CCheckpointData& data, int nHeight, const uint256& hash); - -//! Return conservative estimate of total number of blocks, 0 if unknown + /***** + * @brief Return conservative estimate of total number of blocks, 0 if unknown + * @param data the collection of checkpoints + * @returns the total number of blocks + */ int GetTotalBlocksEstimate(const CChainParams::CCheckpointData& data); -//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint + /****** + * @param data the collection of checkpoints + * @returns last CBlockIndex* in mapBlockIndex that is a checkpoint (can be nullptr) + */ CBlockIndex* GetLastCheckpoint(const CChainParams::CCheckpointData& data); -double GuessVerificationProgress(const CChainParams::CCheckpointData& data, CBlockIndex* pindex, bool fSigchecks = true); + /****** + * @brief Guess how far we are in the verification process at the given block index + * @param data the checkpoint collection + * @param pindex the block index + * @param fsigchecks true to include signature checks in the calculation + * @returns + */ + double GuessVerificationProgress(const CChainParams::CCheckpointData& data, CBlockIndex* pindex, bool fSigchecks = true); -} //namespace Checkpoints +} // namespace Checkpoints #endif // BITCOIN_CHECKPOINTS_H diff --git a/src/coins.cpp b/src/coins.cpp index 346200a2..ee052218 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -25,6 +25,9 @@ #include "policy/fees.h" #include "komodo_defs.h" #include "importcoin.h" +#include "komodo_utils.h" +#include "komodo_bitcoind.h" +#include "komodo_interest.h" #include @@ -565,10 +568,6 @@ const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input) const return coins->vout[input.prevout.n]; } -//uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; - const CScript &CCoinsViewCache::GetSpendFor(const CCoins *coins, const CTxIn& input) { assert(coins); @@ -581,11 +580,19 @@ const CScript &CCoinsViewCache::GetSpendFor(const CTxIn& input) const return GetSpendFor(coins, input); } -CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTransaction& tx,uint32_t tiptime) const +/** + * @brief get amount of bitcoins coming in to a transaction + * @note lightweight clients may not know anything besides the hash of previous transactions, + * so may not be able to calculate this. + * @param[in] nHeight the chain height + * @param[out] interestp the interest found + * @param[in] tx transaction for which we are checking input total + * @returns Sum of value of all inputs (scriptSigs), (positive valueBalance or zero) and JoinSplit vpub_new + */ +CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t &interestp,const CTransaction& tx) const { CAmount value,nResult = 0; - if ( interestp != 0 ) - *interestp = 0; + interestp = 0; if ( tx.IsCoinImport() ) return GetCoinImportValue(tx); if ( tx.IsCoinBase() != 0 ) @@ -600,16 +607,17 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTr value = GetOutputFor(tx.vin[i]).nValue; nResult += value; #ifdef KOMODO_ENABLE_INTEREST - if ( ASSETCHAINS_SYMBOL[0] == 0 && nHeight >= 60000 ) + if ( chainName.isKMD() && nHeight >= 60000 ) { if ( value >= 10*COIN ) { - int64_t interest; int32_t txheight; uint32_t locktime; - interest = komodo_accrued_interest(&txheight,&locktime,tx.vin[i].prevout.hash,tx.vin[i].prevout.n,0,value,(int32_t)nHeight); - //printf("nResult %.8f += val %.8f interest %.8f ht.%d lock.%u tip.%u\n",(double)nResult/COIN,(double)value/COIN,(double)interest/COIN,txheight,locktime,tiptime); - //LogPrintf("nResult %.8f += val %.8f interest %.8f ht.%d lock.%u tip.%u\n",(double)nResult/COIN,(double)value/COIN,(double)interest/COIN,txheight,locktime,tiptime); + int64_t interest; + int32_t txheight; + uint32_t locktime; + interest = komodo_accrued_interest(&txheight,&locktime,tx.vin[i].prevout.hash, + tx.vin[i].prevout.n,0,value,nHeight); nResult += interest; - (*interestp) += interest; + interestp += interest; } } #endif diff --git a/src/coins.h b/src/coins.h index 0aace435..d26dd792 100644 --- a/src/coins.h +++ b/src/coins.h @@ -470,7 +470,9 @@ class CTransactionExceptionData CTransactionExceptionData() : scriptPubKey(), voutMask() {} }; -/** CCoinsView that adds a memory cache for transactions to another CCoinsView */ +/** + * CCoinsView that adds a memory cache in front of another CCoinsView + */ class CCoinsViewCache : public CCoinsViewBacked { protected: @@ -555,14 +557,15 @@ class CCoinsViewCache : public CCoinsViewBacked size_t DynamicMemoryUsage() const; /** - * Amount of bitcoins coming in to a transaction - * Note that lightweight clients may not know anything besides the hash of previous transactions, + * @brief get amount of bitcoins coming in to a transaction + * @note lightweight clients may not know anything besides the hash of previous transactions, * so may not be able to calculate this. - * - * @param[in] tx transaction for which we are checking input total - * @return Sum of value of all inputs (scriptSigs), (positive valueBalance or zero) and JoinSplit vpub_new + * @param[in] nHeight the chain height + * @param[out] interestp the interest found + * @param[in] tx transaction for which we are checking input total + * @returns Sum of value of all inputs (scriptSigs), (positive valueBalance or zero) and JoinSplit vpub_new */ - CAmount GetValueIn(int32_t nHeight,int64_t *interestp,const CTransaction& tx,uint32_t prevblocktime) const; + CAmount GetValueIn(int32_t nHeight,int64_t &interestp,const CTransaction& tx) const; //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view bool HaveInputs(const CTransaction& tx) const; diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 97556e68..d6a7add4 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -41,8 +41,6 @@ extern unsigned int MAX_BLOCK_SIGOPS; /** The maximum size of a transaction (network rule) */ static const unsigned int MAX_TX_SIZE_BEFORE_SAPLING = 100000; static const unsigned int MAX_TX_SIZE_AFTER_SAPLING = (2 * MAX_TX_SIZE_BEFORE_SAPLING); //MAX_BLOCK_SIZE; -/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ -extern int COINBASE_MATURITY; /** The minimum value which is invalid for expiry height, used by CTransaction and CMutableTransaction */ static constexpr uint32_t TX_EXPIRY_HEIGHT_THRESHOLD = 500000000; diff --git a/src/consensus/params.h b/src/consensus/params.h index 5f36d05f..1cd6a91f 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -119,28 +119,35 @@ struct Params { BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS]; /** Proof of work parameters */ - uint256 powLimit; - uint256 powAlternate; + uint256 powLimit; // minimum dificulty limit if EQUIHASH used + uint256 powAlternate; // minimum dificulty limit if EQUIHASH not used boost::optional nPowAllowMinDifficultyBlocksAfterHeight; boost::optional nHF22Height; uint32_t nHF22NotariesPriorityRotateDelta; - int64_t nPowAveragingWindow; - int64_t nPowMaxAdjustDown; - int64_t nPowMaxAdjustUp; - int64_t nPowTargetSpacing; - int64_t nLwmaAjustedWeight; + int64_t nPowAveragingWindow; // lookback window to determine block production speed averages + int64_t nPowMaxAdjustDown; // max percentage difficulty level should be lowered + int64_t nPowMaxAdjustUp; // max percentage difficulty level should be raised + int64_t nPowTargetSpacing; // the target block production speed (in seconds) /* Proof of stake parameters */ uint256 posLimit; int64_t nPOSAveragingWindow; // can be completely different than POW and initially trying a relatively large number, like 100 int64_t nPOSTargetSpacing; // spacing is 1000 units per block to get better resolution, (100 % = 1000, 50% = 2000, 10% = 10000) - int64_t nLwmaPOSAjustedWeight; /* applied to all block times */ int64_t nMaxFutureBlockTime; + /***** + * @returns How long the entire lookback window should take given target values + */ int64_t AveragingWindowTimespan() const { return nPowAveragingWindow * nPowTargetSpacing; } + /**** + * @returns the minimum time the lookback window should take before difficulty should be raised + */ int64_t MinActualTimespan() const { return (AveragingWindowTimespan() * (100 - nPowMaxAdjustUp )) / 100; } + /***** + * @returns the maximum time the lookback window should take before the difficulty should be lowered + */ int64_t MaxActualTimespan() const { return (AveragingWindowTimespan() * (100 + nPowMaxAdjustDown)) / 100; } void SetSaplingHeight(int32_t height) { vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = height; } void SetOverwinterHeight(int32_t height) { vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = height; } diff --git a/src/consensus/upgrades.cpp b/src/consensus/upgrades.cpp index 70e52ead..813bbefe 100644 --- a/src/consensus/upgrades.cpp +++ b/src/consensus/upgrades.cpp @@ -22,10 +22,6 @@ extern int32_t KOMODO_NSPV; #define NSPV_BRANCHID 0x76b809bb -#ifndef KOMODO_NSPV_FULLNODE -#define KOMODO_NSPV_FULLNODE (KOMODO_NSPV <= 0) -#endif // !KOMODO_NSPV_FULLNODE - #ifndef KOMODO_NSPV_SUPERLITE #define KOMODO_NSPV_SUPERLITE (KOMODO_NSPV > 0) #endif // !KOMODO_NSPV_SUPERLITE diff --git a/src/crosschain.cpp b/src/crosschain.cpp index 83fd977c..d6f05c21 100644 --- a/src/crosschain.cpp +++ b/src/crosschain.cpp @@ -17,11 +17,13 @@ #include "crosschain.h" #include "importcoin.h" #include "main.h" -#include "notarisationdb.h" #include "merkleblock.h" #include "hex.h" - +#include "komodo_bitcoind.h" #include "cc/CCinclude.h" +#include "komodo_notary.h" +#include "notarisationdb.h" +#include "cc/import.h" /* * The crosschain workflow. @@ -44,11 +46,80 @@ int NOTARISATION_SCAN_LIMIT_BLOCKS = 1440; -CBlockIndex *komodo_getblockindex(uint256 hash); +/**** + * Determine the type of crosschain + * @param symbol the asset chain to check + * @returns the type of chain + */ +CrosschainType CrossChain::GetSymbolAuthority(const std::string& symbol) +{ + if (symbol.find("TXSCL") == 0) + return CROSSCHAIN_TXSCL; + + if (is_STAKED(symbol.c_str()) != 0) + return CROSSCHAIN_STAKED; + + return CROSSCHAIN_KOMODO; +} + +/*** + * @param tx the transaction to check + * @param auth the authority object + * @returns true on success + */ +bool CrossChain::CheckTxAuthority(const CTransaction &tx, CrosschainAuthority auth) +{ + if (tx.vin.size() < auth.requiredSigs) + return false; + + uint8_t seen[64] = {0}; + for(const CTxIn &txIn : tx.vin) // check each vIn + { + // Get notary pubkey + CTransaction tx; + uint256 hashBlock; + EvalRef eval; + if (!eval->GetTxUnconfirmed(txIn.prevout.hash, tx, hashBlock)) + return false; + if (tx.vout.size() < txIn.prevout.n) + return false; + CScript spk = tx.vout[txIn.prevout.n].scriptPubKey; + if (spk.size() != 35) + return false; + const unsigned char *pk = &spk[0]; + if (pk++[0] != 33) + return false; + if (pk[33] != OP_CHECKSIG) + return false; + + // Check it's a notary + for (int i=0; i &moms, uint256 &destNotarisationTxid) { /* @@ -68,12 +139,11 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh if (kmdHeight < 0 || kmdHeight > chainActive.Height()) return uint256(); - int seenOwnNotarisations = 0, i = 0; - - int authority = GetSymbolAuthority(symbol); + int seenOwnNotarisations = 0; + CrosschainType authority = GetSymbolAuthority(symbol); std::set tmp_moms; - for (i=0; i kmdHeight) break; NotarisationsInBlock notarisations; uint256 blockHash = *chainActive[kmdHeight-i]->phashBlock; @@ -81,7 +151,7 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh continue; // See if we have an own notarisation in this block - BOOST_FOREACH(Notarisation& nota, notarisations) { + for(Notarisation& nota : notarisations) { if (strcmp(nota.second.symbol, symbol) == 0) { seenOwnNotarisations++; @@ -94,7 +164,7 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh } if (seenOwnNotarisations >= 1) { - BOOST_FOREACH(Notarisation& nota, notarisations) { + for(Notarisation& nota : notarisations) { if (GetSymbolAuthority(nota.second.symbol) == authority) if (nota.second.ccId == targetCCid) { tmp_moms.insert(nota.second.MoM); @@ -113,15 +183,17 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh // add set to vector. Set makes sure there are no dupes included. moms.clear(); std::copy(tmp_moms.begin(), tmp_moms.end(), std::back_inserter(moms)); - //LogPrintf( "SeenOwnNotarisations.%i moms.size.%li blocks scanned.%i\n",seenOwnNotarisations, moms.size(), i); return GetMerkleRoot(moms); } -/* - * Get a notarisation from a given height - * - * Will scan notarisations leveldb up to a limit +/***** + * @brief Get a notarisation from a given height + * @note Will scan notarisations leveldb up to a limit + * @param[in] nHeight the height + * @param[in] f + * @param[out] found + * @returns the height of the notarisation */ template int ScanNotarisationsFromHeight(int nHeight, const IsTarget f, Notarisation &found) @@ -135,8 +207,9 @@ int ScanNotarisationsFromHeight(int nHeight, const IsTarget f, Notarisation &fou if (!GetBlockNotarisations(*chainActive[h]->phashBlock, notarisations)) continue; - BOOST_FOREACH(found, notarisations) { - if (f(found)) { + for(auto entry : notarisations) { + if (f(entry)) { + found = entry; return h; } } @@ -144,9 +217,17 @@ int ScanNotarisationsFromHeight(int nHeight, const IsTarget f, Notarisation &fou return 0; } - -/* On KMD */ -TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_t targetCCid, +/****** + * @brief + * @note this happens on the KMD chain + * @param txid + * @param targetSymbol + * @param targetCCid + * @param assetChainProof + * @param offset + * @returns a pair of target chain notarisation txid and the merkle branch + */ +TxProof CrossChain::GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_t targetCCid, const TxProof assetChainProof, int32_t offset) { /* @@ -227,62 +308,53 @@ TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_ } -/* - * Takes an importTx that has proof leading to assetchain root - * and extends proof to cross chain root +/***** + * @brief Takes an importTx that has proof leading to assetchain root and extends proof to cross chain root + * @param importTx + * @param offset */ -void CompleteImportTransaction(CTransaction &importTx, int32_t offset) +void CrossChain::CompleteImportTransaction(CTransaction &importTx, int32_t offset) { - ImportProof proof; CTransaction burnTx; std::vector payouts; std::vector rawproof; + ImportProof proof; + CTransaction burnTx; + std::vector payouts; + if (!UnmarshalImportTx(importTx, proof, burnTx, payouts)) throw std::runtime_error("Couldn't unmarshal importTx"); std::string targetSymbol; uint32_t targetCCid; uint256 payoutsHash; + std::vector rawproof; if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCCid, payoutsHash, rawproof)) throw std::runtime_error("Couldn't unmarshal burnTx"); TxProof merkleBranch; if( !proof.IsMerkleBranch(merkleBranch) ) throw std::runtime_error("Incorrect import tx proof"); - TxProof newMerkleBranch = GetCrossChainProof(burnTx.GetHash(), targetSymbol.data(), targetCCid, merkleBranch, offset); + TxProof newMerkleBranch = GetCrossChainProof(burnTx.GetHash(), targetSymbol.data(), + targetCCid, merkleBranch, offset); ImportProof newProof(newMerkleBranch); importTx = MakeImportCoinTransaction(newProof, burnTx, payouts); } - +/***** + * @param nota the notarisation + * @returns true if the notarization belongs to this chain + */ bool IsSameAssetChain(const Notarisation ¬a) { - return strcmp(nota.second.symbol, ASSETCHAINS_SYMBOL) == 0; + return chainName.isSymbol(nota.second.symbol); }; - -/* On assetchain */ -bool GetNextBacknotarisation(uint256 kmdNotarisationTxid, Notarisation &out) -{ - /* - * Here we are given a txid, and a proof. - * We go from the KMD notarisation txid to the backnotarisation, - * then jump to the next backnotarisation, which contains the corresponding MoMoM. - */ - Notarisation bn; - if (!GetBackNotarisation(kmdNotarisationTxid, bn)) - return false; - - // Need to get block height of that backnotarisation - EvalRef eval; - CBlockIndex block; - CTransaction tx; - if (!eval->GetTxConfirmed(bn.first, tx, block)){ - LogPrintf( "Can't get height of backnotarisation, this should not happen\n"); - return false; - } - - return (bool) ScanNotarisationsFromHeight(block.nHeight+1, &IsSameAssetChain, out); -} - -bool CheckMoMoM(uint256 kmdNotarisationHash, uint256 momom) +/**** + * @brief Check MoMoM + * @note on Assetchain + * @param kmdNotarisationHash the hash + * @param momom what to check + * @returns true on success + */ +bool CrossChain::CheckMoMoM(uint256 kmdNotarisationHash, uint256 momom) { /* * Given a notarisation hash and an MoMoM. Backnotarisations may arrive out of order @@ -313,14 +385,14 @@ bool CheckMoMoM(uint256 kmdNotarisationHash, uint256 momom) } -/* -* Check notaries approvals for the txoutproofs of burn tx -* (alternate check if MoMoM check has failed) -* Params: -* burntxid - txid of burn tx on the source chain -* rawproof - array of txids of notaries' proofs +/***** +* @brief Check notaries approvals for the txoutproofs of burn tx +* @note alternate check if MoMoM check has failed +* @param burntxid - txid of burn tx on the source chain +* @param notaryTxids txids of notaries' proofs +* @returns true on success */ -bool CheckNotariesApproval(uint256 burntxid, const std::vector & notaryTxids) +bool CrossChain::CheckNotariesApproval(uint256 burntxid, const std::vector & notaryTxids) { int count = 0; @@ -419,13 +491,14 @@ bool CheckNotariesApproval(uint256 burntxid, const std::vector & notary } -/* - * On assetchain - * in: txid - * out: pair +/***** + * @brief get the proof + * @note On assetchain + * @param hash + * @param burnTx + * @returns a pair containing the notarisation tx hash and the merkle branch */ - -TxProof GetAssetchainProof(uint256 hash,CTransaction burnTx) +TxProof CrossChain::GetAssetchainProof(uint256 hash,CTransaction burnTx) { int nIndex; CBlockIndex* blockIndex; diff --git a/src/crosschain.h b/src/crosschain.h index 25763c01..934ebc72 100644 --- a/src/crosschain.h +++ b/src/crosschain.h @@ -1,3 +1,4 @@ +#pragma once /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * @@ -12,15 +13,16 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ - -#ifndef CROSSCHAIN_H -#define CROSSCHAIN_H - +/***** + * transfer or migrate assets from one chain to another + */ #include "cc/eval.h" -const int CROSSCHAIN_KOMODO = 1; -const int CROSSCHAIN_TXSCL = 2; -const int CROSSCHAIN_STAKED = 3; +enum CrosschainType { + CROSSCHAIN_KOMODO = 1, + CROSSCHAIN_TXSCL = 2, + CROSSCHAIN_STAKED = 3 +}; typedef struct CrosschainAuthority { uint8_t notaries[64][33]; @@ -28,21 +30,81 @@ typedef struct CrosschainAuthority { int8_t requiredSigs; } CrosschainAuthority; -int GetSymbolAuthority(const char* symbol); -bool CheckTxAuthority(const CTransaction &tx, CrosschainAuthority auth); +class CrossChain +{ +public: + /**** + * Determine the type of crosschain + * @param symbol the asset chain to check + * @returns the type of chain + */ + static CrosschainType GetSymbolAuthority(const std::string& symbol); + + /*** + * @param tx the transaction to check + * @param auth the authority object + * @returns true on success + */ + static bool CheckTxAuthority(const CTransaction &tx, CrosschainAuthority auth); + + /***** + * @brief get the proof + * @note On assetchain + * @param hash + * @param burnTx + * @returns a pair containing the notarisation tx hash and the merkle branch + */ + static TxProof GetAssetchainProof(uint256 hash,CTransaction burnTx); + + /***** + * @brief Calculate the proof root + * @note this happens on the KMD chain + * @param symbol the chain symbol + * @param targetCCid + * @param kmdHeight + * @param moms collection of MoMs + * @param destNotarisationTxid + * @returns the proof root, or 0 on error + */ + static uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeight, + std::vector &moms, uint256 &destNotarisationTxid); -/* On assetchain */ -TxProof GetAssetchainProof(uint256 hash,CTransaction burnTx); + /***** + * @brief Takes an importTx that has proof leading to assetchain root and extends proof to cross chain root + * @param importTx + * @param offset + */ + static void CompleteImportTransaction(CTransaction &importTx,int32_t offset); -/* On KMD */ -uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeight, - std::vector &moms, uint256 &destNotarisationTxid); -TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_t targetCCid, - const TxProof assetChainProof,int32_t offset); -void CompleteImportTransaction(CTransaction &importTx,int32_t offset); + /**** + * @brief check the MoMoM + * @note on Assetchain + * @param kmdNotarisationHash the hash + * @param momom what to check + * @returns true on success + */ + static bool CheckMoMoM(uint256 kmdNotarisationHash, uint256 momom); -/* On assetchain */ -bool CheckMoMoM(uint256 kmdNotarisationHash, uint256 momom); -bool CheckNotariesApproval(uint256 burntxid, const std::vector & notaryTxids); + /***** + * @brief Check notaries approvals for the txoutproofs of burn tx + * @note alternate check if MoMoM check has failed + * @param burntxid - txid of burn tx on the source chain + * @param notaryTxids txids of notaries' proofs + * @returns true on success + */ + static bool CheckNotariesApproval(uint256 burntxid, const std::vector & notaryTxids); -#endif /* CROSSCHAIN_H */ +private: + /****** + * @brief + * @note this happens on the KMD chain + * @param txid + * @param targetSymbol + * @param targetCCid + * @param assetChainProof + * @param offset + * @returns a pair of target chain notarisation txid and the merkle branch + */ + static TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_t targetCCid, + const TxProof assetChainProof,int32_t offset); +}; \ No newline at end of file diff --git a/src/crosschain_authority.cpp b/src/crosschain_authority.cpp deleted file mode 100644 index 06051b9e..00000000 --- a/src/crosschain_authority.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "cc/eval.h" -#include "crosschain.h" -#include "notarisationdb.h" -#include "notaries_staked.h" - -int GetSymbolAuthority(const char* symbol) -{ - if (strncmp(symbol, "TXSCL", 5) == 0) - return CROSSCHAIN_TXSCL; - if (is_STAKED(symbol) != 0) { - //LogPrintf("RETURNED CROSSCHAIN STAKED AS TRUE\n"); - return CROSSCHAIN_STAKED; - } - //LogPrintf("RETURNED CROSSCHAIN KOMODO AS TRUE\n"); - return CROSSCHAIN_KOMODO; -} - - -bool CheckTxAuthority(const CTransaction &tx, CrosschainAuthority auth) -{ - EvalRef eval; - - if (tx.vin.size() < auth.requiredSigs) return false; - - uint8_t seen[64] = {0}; - - BOOST_FOREACH(const CTxIn &txIn, tx.vin) - { - // Get notary pubkey - CTransaction tx; - uint256 hashBlock; - if (!eval->GetTxUnconfirmed(txIn.prevout.hash, tx, hashBlock)) return false; - if (tx.vout.size() < txIn.prevout.n) return false; - CScript spk = tx.vout[txIn.prevout.n].scriptPubKey; - if (spk.size() != 35) return false; - const unsigned char *pk = &spk[0]; - if (pk++[0] != 33) return false; - if (pk[33] != OP_CHECKSIG) return false; - - // Check it's a notary - for (int i=0; i bool Read(const K& key, V& value) const { @@ -213,6 +225,13 @@ class CDBWrapper return true; } + /**** + * Write a value to a key + * @param key the key + * @param value the value + * @param fSync true to use sync option instead of just write + * @returns true on success + */ template bool Write(const K& key, const V& value, bool fSync = false) { @@ -221,6 +240,11 @@ class CDBWrapper return WriteBatch(batch, fSync); } + /*** + * Check to see if a key exists + * @param key the key + * @returns true if key exists + */ template bool Exists(const K& key) const { @@ -240,6 +264,12 @@ class CDBWrapper return true; } + /*** + * Erase a key from the db + * @param key the key + * @param fSync true to use sync option instead of just write + * @returns true on success + */ template bool Erase(const K& key, bool fSync = false) { @@ -248,27 +278,45 @@ class CDBWrapper return WriteBatch(batch, fSync); } + /*** + * Write a batch of transactions to the db + * @param batch the transactions + * @param fSync true to use sync option instead of just write + * @returns true on success + */ bool WriteBatch(CDBBatch& batch, bool fSync = false); - // not available for LevelDB; provide for compatibility with BDB + /**** + * not available for LevelDB; provided for compatibility with BDB + * @returns true always + */ bool Flush() { return true; } + /**** + * Synchronize the db + * @returns true on success + */ bool Sync() { CDBBatch batch(*this); return WriteBatch(batch, true); } + /*** + * Get a new iterator + * NOTE: you are responsible for deletion of the returned iterator + * @returns an iterator + */ CDBIterator *NewIterator() { return new CDBIterator(*this, pdb->NewIterator(iteroptions)); } /** - * Return true if the database managed by this class contains no entries. + * @returns true if the database managed by this class contains no entries. */ bool IsEmpty(); }; diff --git a/src/deprecation.cpp b/src/deprecation.cpp index 6005918e..93c1d8c7 100644 --- a/src/deprecation.cpp +++ b/src/deprecation.cpp @@ -25,9 +25,9 @@ #include "ui_interface.h" #include "util.h" #include "chainparams.h" +#include "komodo_globals.h" static const std::string CLIENT_VERSION_STR = FormatVersion(CLIENT_VERSION); -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; void EnforceNodeDeprecation(int nHeight, bool forceLogging, bool fThread) { @@ -35,7 +35,8 @@ void EnforceNodeDeprecation(int nHeight, bool forceLogging, bool fThread) { std::string networkID = Params().NetworkIDString(); std::string msg; - if (networkID != "main" || ASSETCHAINS_SYMBOL[0] != 0 ) return; + if (networkID != "main" || !chainName.isKMD() ) + return; int blocksToDeprecation = DEPRECATION_HEIGHT - nHeight; if (blocksToDeprecation <= 0) { diff --git a/src/importcoin.cpp b/src/importcoin.cpp index e7b43ad6..e55551f2 100644 --- a/src/importcoin.cpp +++ b/src/importcoin.cpp @@ -23,15 +23,21 @@ #include "core_io.h" #include "script/sign.h" #include "wallet/wallet.h" - #include "cc/CCinclude.h" +#include "komodo_bitcoind.h" -int32_t komodo_nextheight(); -// makes import tx for either coins or tokens -CTransaction MakeImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector payouts, uint32_t nExpiryHeightOverride) +/****** + * @brief makes import tx for either coins or tokens + * @param proof the proof + * @param burnTx the inputs + * @param payouts the outputs + * @param nExpiryHeightOverride if an actual height (!= 0) makes a tx for validating int import tx + * @returns the generated import transaction + */ +CTransaction MakeImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, + const std::vector payouts, uint32_t nExpiryHeightOverride) { - //std::vector payload = E_MARSHAL(ss << EVAL_IMPORTCOIN); CScript scriptSig; CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); @@ -75,20 +81,36 @@ CTransaction MakeImportCoinTransaction(const ImportProof proof, const CTransacti return CTransaction(mtx); } -CTransaction MakePegsImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector payouts, uint32_t nExpiryHeightOverride) +/***** + * @brief makes import tx that includes spending markers to track account state + * @param proof + * @param burnTx + * @param payouts + * @param nExpiryHeighOverride + * @returns the transaction + */ +CTransaction MakePegsImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, + const std::vector payouts, uint32_t nExpiryHeightOverride) { - CMutableTransaction mtx; uint256 accounttxid,pegstxid,tokenid; CScript opret; CScript scriptSig; - - mtx=MakeImportCoinTransaction(proof,burnTx,payouts); + CMutableTransaction mtx=MakeImportCoinTransaction(proof,burnTx,payouts); // for spending markers in import tx - to track account state - accounttxid=burnTx.vin[0].prevout.hash; + uint256 accounttxid = burnTx.vin[0].prevout.hash; mtx.vin.push_back(CTxIn(accounttxid,0,CScript())); mtx.vin.push_back(CTxIn(accounttxid,1,CScript())); return (mtx); } - -CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string targetSymbol, const std::vector payouts, const std::vector rawproof) +/****** + * @brief make a burn output + * @param value the amount + * @param targetCCid the ccid + * @param targetSymbol + * @param payouts the outputs + * @param rawproof the proof in binary form + * @returns the txout + */ +CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string& targetSymbol, + const std::vector payouts, const std::vector rawproof) { std::vector opret; opret = E_MARSHAL(ss << (uint8_t)EVAL_IMPORTCOIN; // should mark burn opret to differentiate it from token opret @@ -99,8 +121,28 @@ CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string targ return CTxOut(value, CScript() << OP_RETURN << opret); } -CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymbol, const std::vector payouts,std::vector rawproof, - uint256 bindtxid,std::vector publishers,std::vector txids,uint256 burntxid,int32_t height,int32_t burnvout,std::string rawburntx,CPubKey destpub, int64_t amount) +/****** + * @brief make a burn output + * @param value + * @param targetCCid the target ccid + * @param targetSymbol the target symbol + * @param payouts the outputs + * @param rawproof the proof in binary form + * @param bindtxid + * @param publishers + * @param txids + * @param burntxid + * @param height + * @param burnvout + * @param rawburntx + * @param destpub + * @param amount + * @returns the txout + */ +CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string& targetSymbol, + const std::vector payouts,std::vector rawproof, uint256 bindtxid, + std::vector publishers,std::vector txids,uint256 burntxid, + int32_t height,int32_t burnvout, const std::string& rawburntx,CPubKey destpub, int64_t amount) { std::vector opret; opret = E_MARSHAL(ss << (uint8_t)EVAL_IMPORTCOIN; @@ -121,8 +163,20 @@ CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymb return CTxOut(value, CScript() << OP_RETURN << opret); } -CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymbol, const std::vector payouts,std::vector rawproof,std::string srcaddr, - std::string receipt) +/****** + * @brief make a burn output + * @param value the amount + * @param targetCCid the ccid + * @param targetSymbol + * @param payouts the outputs + * @param rawproof the proof in binary form + * @param srcaddr the source address + * @param receipt + * @returns the txout + */ +CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string& targetSymbol, + const std::vector payouts,std::vector rawproof,const std::string& srcaddr, + const std::string& receipt) { std::vector opret; opret = E_MARSHAL(ss << (uint8_t)EVAL_IMPORTCOIN; @@ -135,8 +189,23 @@ CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymb return CTxOut(value, CScript() << OP_RETURN << opret); } -CTxOut MakeBurnOutput(CAmount value,uint32_t targetCCid,std::string targetSymbol,const std::vector payouts,std::vector rawproof,uint256 pegstxid, - uint256 tokenid,CPubKey srcpub,int64_t amount,std::pair account) +/****** + * @brief make a burn output + * @param value the amount + * @param targetCCid the ccid + * @param targetSymbol + * @param payouts the outputs + * @param rawproof the proof in binary form + * @param pegstxid + * @param tokenid + * @param srcpub + * @param amount + * @param account + * @returns the txout + */ +CTxOut MakeBurnOutput(CAmount value,uint32_t targetCCid, const std::string& targetSymbol, + const std::vector payouts,std::vector rawproof,uint256 pegstxid, + uint256 tokenid,CPubKey srcpub,int64_t amount, std::pair account) { std::vector opret; opret = E_MARSHAL(ss << (uint8_t)EVAL_IMPORTCOIN; @@ -152,8 +221,16 @@ CTxOut MakeBurnOutput(CAmount value,uint32_t targetCCid,std::string targetSymbol return CTxOut(value, CScript() << OP_RETURN << opret); } - -bool UnmarshalImportTx(const CTransaction importTx, ImportProof &proof, CTransaction &burnTx, std::vector &payouts) +/**** + * @brief break a serialized import tx into its components + * @param[in] importTx the transaction + * @param[out] proof the proof + * @param[out] burnTx the burn transaction + * @param[out] payouts the collection of tx outs + * @returns true on success + */ +bool UnmarshalImportTx(const CTransaction importTx, ImportProof &proof, CTransaction &burnTx, + std::vector &payouts) { if (importTx.vout.size() < 1) return false; @@ -203,15 +280,22 @@ bool UnmarshalImportTx(const CTransaction importTx, ImportProof &proof, CTransac return retcode; } - -bool UnmarshalBurnTx(const CTransaction burnTx, std::string &targetSymbol, uint32_t *targetCCid, uint256 &payoutsHash,std::vector&rawproof) +/**** + * @brief break a serialized burn tx into its components + * @param[in] burnTx the transaction + * @param[out] targetSymbol the symbol + * @param[out] targetCCid the target ccid + * @param[out] payoutsHash the hash of the payouts + * @param[out] rawproof the bytes of the proof + * @returns true on success + */ +bool UnmarshalBurnTx(const CTransaction burnTx, std::string &targetSymbol, uint32_t *targetCCid, + uint256 &payoutsHash,std::vector&rawproof) { - std::vector vburnOpret; uint32_t ccid = 0; - uint8_t evalCode; - if (burnTx.vout.size() == 0) return false; + std::vector vburnOpret; GetOpReturnData(burnTx.vout.back().scriptPubKey, vburnOpret); if (vburnOpret.empty()) { LOGSTREAM("importcoin", CCLOG_INFO, stream << "UnmarshalBurnTx() cannot unmarshal burn tx: empty burn opret" << std::endl); @@ -245,20 +329,33 @@ bool UnmarshalBurnTx(const CTransaction burnTx, std::string &targetSymbol, uint3 ss >> rawproof; isEof = ss.eof();) || !isEof; // if isEof == false it means we have successfully read the vars upto 'rawproof' // and it might be additional data further that we do not need here so we allow !isEof } - else { - LOGSTREAM("importcoin", CCLOG_INFO, stream << "UnmarshalBurnTx() invalid eval code in opret" << std::endl); - return false; - } + + LOGSTREAM("importcoin", CCLOG_INFO, stream << "UnmarshalBurnTx() invalid eval code in opret" << std::endl); + return false; } +/**** + * @brief break a serialized burn tx into its components + * @param[in] burnTx the transaction + * @param[out] srcaddr the source address + * @param[out] receipt + * @returns true on success + */ bool UnmarshalBurnTx(const CTransaction burnTx, std::string &srcaddr, std::string &receipt) { - std::vector burnOpret,rawproof; bool isEof=true; - std::string targetSymbol; uint32_t targetCCid; uint256 payoutsHash; + if (burnTx.vout.size() == 0) + return false; + + // parts of tx that are deserialized but not returned + std::vector rawproof; + std::string targetSymbol; + uint32_t targetCCid; + uint256 payoutsHash; uint8_t evalCode; - if (burnTx.vout.size() == 0) return false; + std::vector burnOpret; GetOpReturnData(burnTx.vout.back().scriptPubKey, burnOpret); + return (E_UNMARSHAL(burnOpret, ss >> evalCode; ss >> VARINT(targetCCid); ss >> targetSymbol; @@ -268,13 +365,36 @@ bool UnmarshalBurnTx(const CTransaction burnTx, std::string &srcaddr, std::strin ss >> receipt)); } -bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &bindtxid,std::vector &publishers,std::vector &txids,uint256& burntxid,int32_t &height,int32_t &burnvout,std::string &rawburntx,CPubKey &destpub, int64_t &amount) +/**** + * @brief break a serialized burn tx into its components + * @param[in] burnTx the transaction + * @param[out] bindtxid + * @param[out] publishers + * @param[out] txids + * @param[out] burntxid + * @param[out] height + * @param[out] burnvout + * @param[out] rawburntx + * @param[out] destpub + * @param[out] amount + * @returns true on success + */ +bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &bindtxid, + std::vector &publishers,std::vector &txids, + uint256& burntxid, int32_t &height,int32_t &burnvout, + std::string &rawburntx,CPubKey &destpub, int64_t &amount) { - std::vector burnOpret,rawproof; bool isEof=true; - uint32_t targetCCid; uint256 payoutsHash; std::string targetSymbol; + if (burnTx.vout.size() == 0) + return false; + + // parts of tx that are deserialized but not returned + std::vector rawproof; + uint32_t targetCCid; + uint256 payoutsHash; + std::string targetSymbol; uint8_t evalCode; - if (burnTx.vout.size() == 0) return false; + std::vector burnOpret; GetOpReturnData(burnTx.vout.back().scriptPubKey, burnOpret); return (E_UNMARSHAL(burnOpret, ss >> evalCode; ss >> VARINT(targetCCid); @@ -292,7 +412,18 @@ bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &bindtxid,std::vector> amount)); } -bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &pegstxid,uint256 &tokenid,CPubKey &srcpub, int64_t &amount,std::pair &account) +/**** + * @brief break a serialized burn tx into its components + * @param[in] burnTx the transaction + * @param[out] pegstxid + * @param[out] tokenid + * @param[out] srcpub + * @param[out] amount + * @param[out] account + * @returns true on success + */ +bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &pegstxid,uint256 &tokenid,CPubKey &srcpub, + int64_t &amount,std::pair &account) { std::vector burnOpret,rawproof; bool isEof=true; uint32_t targetCCid; uint256 payoutsHash; std::string targetSymbol; @@ -313,15 +444,18 @@ bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &pegstxid,uint256 &tokeni ss >> account)); } -/* - * Required by main +/****** + * @brief get the value of the transaction + * @param tx the transaction + * @returns the burned value within tx */ CAmount GetCoinImportValue(const CTransaction &tx) { - ImportProof proof; CTransaction burnTx; std::vector payouts; - bool isNewImportTx = false; + ImportProof proof; + CTransaction burnTx; + std::vector payouts; - if ((isNewImportTx = UnmarshalImportTx(tx, proof, burnTx, payouts))) { + if ( UnmarshalImportTx(tx, proof, burnTx, payouts) ) { if (burnTx.vout.size() > 0) { vscript_t vburnOpret; @@ -331,7 +465,7 @@ CAmount GetCoinImportValue(const CTransaction &tx) return 0; } - if (isNewImportTx && vburnOpret.begin()[0] == EVAL_TOKENS) { //if it is tokens + if ( vburnOpret.begin()[0] == EVAL_TOKENS) { //if it is tokens uint8_t evalCodeInOpret; uint256 tokenid; @@ -364,17 +498,23 @@ CAmount GetCoinImportValue(const CTransaction &tx) } -/* - * CoinImport is different enough from normal script execution that it's not worth + +/***** + * @brief verify a coin import signature + * @note CoinImport is different enough from normal script execution that it's not worth * making all the mods neccesary in the interpreter to do the dispatch correctly. + * @param[in] scriptSig the signature + * @param[in] checker the checker to use + * @param[out] state the error state + * @returns true on success, `state` will contain the reason if false */ bool VerifyCoinImport(const CScript& scriptSig, TransactionSignatureChecker& checker, CValidationState &state) { auto pc = scriptSig.begin(); - opcodetype opcode; - std::vector evalScript; auto f = [&] () { + opcodetype opcode; + std::vector evalScript; if (!scriptSig.GetOp(pc, opcode, evalScript)) return false; if (pc != scriptSig.end()) @@ -393,29 +533,37 @@ bool VerifyCoinImport(const CScript& scriptSig, TransactionSignatureChecker& che return f() ? true : state.Invalid(false, 0, "invalid-coin-import"); } - +/**** + * @brief add an import tombstone + * @param importTx the transaction + * @param inputs the inputs to be modified + * @param nHeight the height + */ void AddImportTombstone(const CTransaction &importTx, CCoinsViewCache &inputs, int nHeight) { - uint256 burnHash = importTx.vin[0].prevout.hash; - //LogPrintf("add tombstone.(%s)\n",burnHash.GetHex().c_str()); - CCoinsModifier modifier = inputs.ModifyCoins(burnHash); + CCoinsModifier modifier = inputs.ModifyCoins(importTx.vin[0].prevout.hash); modifier->nHeight = nHeight; - modifier->nVersion = 4;//1; + modifier->nVersion = 4; modifier->vout.push_back(CTxOut(0, CScript() << OP_0)); } - +/***** + * @brief remove an import tombstone from inputs + * @param importTx the transaction + * @param inputs what to modify + */ void RemoveImportTombstone(const CTransaction &importTx, CCoinsViewCache &inputs) { - uint256 burnHash = importTx.vin[0].prevout.hash; - //LogPrintf("remove tombstone.(%s)\n",burnHash.GetHex().c_str()); - inputs.ModifyCoins(burnHash)->Clear(); + inputs.ModifyCoins(importTx.vin[0].prevout.hash)->Clear(); } - -int ExistsImportTombstone(const CTransaction &importTx, const CCoinsViewCache &inputs) +/***** + * @brief See if a tombstone exists + * @param importTx the transaction + * @param inputs + * @returns true if the transaction is a tombstone + */ +bool ExistsImportTombstone(const CTransaction &importTx, const CCoinsViewCache &inputs) { - uint256 burnHash = importTx.vin[0].prevout.hash; - //LogPrintf("check tombstone.(%s) in %s\n",burnHash.GetHex().c_str(),importTx.GetHash().GetHex().c_str()); - return inputs.HaveCoins(burnHash); + return inputs.HaveCoins(importTx.vin[0].prevout.hash); } diff --git a/src/importcoin.h b/src/importcoin.h index acb81652..14c7f412 100644 --- a/src/importcoin.h +++ b/src/importcoin.h @@ -1,3 +1,4 @@ +#pragma once /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * @@ -12,10 +13,6 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ - -#ifndef IMPORTCOIN_H -#define IMPORTCOIN_H - #include "cc/eval.h" #include "coins.h" #include "primitives/transaction.h" @@ -29,6 +26,12 @@ enum ProofKind : uint8_t { PROOF_MERKLEBLOCK = 0x13 }; +/***** + * Holds the proof. This can be one of 3 types: + * - Merkle branch + * - Notary TXIDs + * - Merkle block + */ class ImportProof { private: @@ -38,13 +41,28 @@ class ImportProof { std::vector proofBlock; public: + /**** + * @brief Default ctor + */ ImportProof() { proofKind = PROOF_NONE; } + /**** + * @brief Merkle branch proof ctor + * @param _proofBranch the Merkle branch + */ ImportProof(const TxProof &_proofBranch) { proofKind = PROOF_MERKLEBRANCH; proofBranch = _proofBranch; } + /**** + * @brief Notary TXID proof ctor + * @param _notaryTxids the collection of txids + */ ImportProof(const std::vector &_notaryTxids) { proofKind = PROOF_NOTARYTXIDS; notaryTxids = _notaryTxids; } + /***** + * @brief Merkle block proof ctor + * @param _proofBlock the Merkle block + */ ImportProof(const std::vector &_proofBlock) { proofKind = PROOF_MERKLEBLOCK; proofBlock = _proofBlock; } @@ -64,6 +82,10 @@ class ImportProof { proofKind = PROOF_NONE; // if we have read some trash } + /***** + * @param _proofBranch the merkle branch to store + * @returns true if this object is a Merkle branch ImportProof + */ bool IsMerkleBranch(TxProof &_proofBranch) const { if (proofKind == PROOF_MERKLEBRANCH) { _proofBranch = proofBranch; @@ -72,6 +94,11 @@ class ImportProof { else return false; } + + /***** + * @param _notaryTxids the txids to store + * @returns true if this object is a Notary TXID ImportProof + */ bool IsNotaryTxids(std::vector &_notaryTxids) const { if (proofKind == PROOF_NOTARYTXIDS) { _notaryTxids = notaryTxids; @@ -80,6 +107,11 @@ class ImportProof { else return false; } + + /***** + * @param _proofBlock the block to store + * @returns true if this object is a Merkle Block ImportProof + */ bool IsMerkleBlock(std::vector &_proofBlock) const { if (proofKind == PROOF_MERKLEBLOCK) { _proofBlock = proofBlock; @@ -90,35 +122,194 @@ class ImportProof { } }; - +/****** + * @brief get the value of the transaction + * @param tx the transaction + * @returns the burned value within tx + */ CAmount GetCoinImportValue(const CTransaction &tx); +/****** + * @brief makes import tx for either coins or tokens + * @param proof the proof + * @param burnTx the inputs + * @param payouts the outputs + * @param nExpiryHeightOverride if an actual height (!= 0) makes a tx for validating int import tx + * @returns the generated import transaction + */ CTransaction MakeImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector payouts, uint32_t nExpiryHeightOverride = 0); + +/***** + * @brief makes import tx for pegs cc + * @param proof the proof + * @param burnTx the inputs + * @param payouts the outputs + * @param nExpiryHeighOverride if an actual height (!= 0) makes a tx for validating int import tx + * @returns the transaction including spending markers for pegs CC + */ CTransaction MakePegsImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector payouts, uint32_t nExpiryHeightOverride = 0); -CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string targetSymbol, const std::vector payouts, const std::vector rawproof); -CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymbol, const std::vector payouts,std::vector rawproof, - uint256 bindtxid,std::vector publishers,std::vectortxids,uint256 burntxid,int32_t height,int32_t burnvout,std::string rawburntx,CPubKey destpub, int64_t amount); -CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymbol, const std::vector payouts,std::vector rawproof,std::string srcaddr, - std::string receipt); -CTxOut MakeBurnOutput(CAmount value,uint32_t targetCCid,std::string targetSymbol,const std::vector payouts,std::vector rawproof,uint256 pegstxid, - uint256 tokenid,CPubKey srcpub,int64_t amount,std::pair account); +/****** + * @brief make a burn output + * @param value the amount + * @param targetCCid the ccid + * @param targetSymbol + * @param payouts the outputs + * @param rawproof + * @returns the txout + */ +CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string& targetSymbol, + const std::vector payouts, const std::vector rawproof); + +/****** + * @brief make a burn output + * @param value + * @param targetCCid the target ccid + * @param targetSymbol the target symbol + * @param payouts the outputs + * @param rawproof the proof in binary form + * @param bindtxid + * @param publishers + * @param txids + * @param burntxid + * @param height + * @param burnvout + * @param rawburntx + * @param destpub + * @param amount + * @returns the txout + */ +CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string& targetSymbol, + const std::vector payouts,std::vector rawproof, uint256 bindtxid, + std::vector publishers,std::vectortxids,uint256 burntxid,int32_t height, + int32_t burnvout,const std::string& rawburntx,CPubKey destpub, int64_t amount); + +/****** + * @brief make a burn output + * @param value the amount + * @param targetCCid the ccid + * @param targetSymbol + * @param payouts the outputs + * @param rawproof the proof in binary form + * @param srcaddr the source address + * @param receipt + * @returns the txout + */ +CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string& targetSymbol, + const std::vector payouts,std::vector rawproof, const std::string& srcaddr, + const std::string& receipt); -bool UnmarshalBurnTx(const CTransaction burnTx, std::string &targetSymbol, uint32_t *targetCCid, uint256 &payoutsHash,std::vector &rawproof); +/****** + * @brief make a burn output + * @param value the amount + * @param targetCCid the ccid + * @param targetSymbol + * @param payouts the outputs + * @param rawproof the proof in binary form + * @param pegstxid + * @param tokenid + * @param srcpub + * @param amount + * @param account + * @returns the txout + */ +CTxOut MakeBurnOutput(CAmount value,uint32_t targetCCid,const std::string& targetSymbol, + const std::vector payouts,std::vector rawproof,uint256 pegstxid, + uint256 tokenid,CPubKey srcpub,int64_t amount,std::pair account); + +/**** + * @brief break a serialized burn tx into its components + * @param[in] burnTx the transaction + * @param[out] targetSymbol the symbol + * @param[out] targetCCid the target ccid + * @param[out] payoutsHash the hash of the payouts + * @param[out] rawproof the bytes of the proof + * @returns true on success + */ +bool UnmarshalBurnTx(const CTransaction burnTx, std::string &targetSymbol, uint32_t *targetCCid, + uint256 &payoutsHash,std::vector &rawproof); + +/**** + * @brief break a serialized burn tx into its components + * @param[in] burnTx the transaction + * @param[out] srcaddr the source address + * @param[out] receipt + * @returns true on success + */ bool UnmarshalBurnTx(const CTransaction burnTx, std::string &srcaddr, std::string &receipt); -bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &bindtxid,std::vector &publishers,std::vector &txids,uint256& burntxid,int32_t &height,int32_t &burnvout,std::string &rawburntx,CPubKey &destpub, int64_t &amount); -bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &pegstxid,uint256 &tokenid,CPubKey &srcpub,int64_t &amount,std::pair &account); -bool UnmarshalImportTx(const CTransaction importTx, ImportProof &proof, CTransaction &burnTx,std::vector &payouts); +/**** + * @brief break a serialized burn tx into its components + * @param[in] burnTx the transaction + * @param[out] bindtxid + * @param[out] publishers + * @param[out] txids + * @param[out] burntxid + * @param[out] height + * @param[out] burnvout + * @param[out] rawburntx + * @param[out] destpub + * @param[out] amount + * @returns true on success + */ +bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &bindtxid,std::vector &publishers, + std::vector &txids,uint256& burntxid,int32_t &height,int32_t &burnvout, + std::string &rawburntx,CPubKey &destpub, int64_t &amount); + +/**** + * @brief break a serialized burn tx into its components + * @param[in] burnTx the transaction + * @param[out] pegstxid + * @param[out] tokenid + * @param[out] srcpub + * @param[out] amount + * @param[out] account + * @returns true on success + */ +bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &pegstxid,uint256 &tokenid,CPubKey &srcpub, + int64_t &amount,std::pair &account); + +/**** + * @brief break a serialized import tx into its components + * @param[in] importTx the transaction + * @param[out] proof the proof + * @param[out] burnTx the burn transaction + * @param[out] payouts the collection of tx outs + * @returns true on success + */ +bool UnmarshalImportTx(const CTransaction importTx, ImportProof &proof, + CTransaction &burnTx,std::vector &payouts); + +/***** + * @brief verify a coin import signature + * @note CoinImport is different enough from normal script execution that it's not worth + * making all the mods neccesary in the interpreter to do the dispatch correctly. + * @param[in] scriptSig the signature + * @param[in] checker the checker to use + * @param[out] state the error state + * @returns true on success, `state` will contain the reason if false + */ bool VerifyCoinImport(const CScript& scriptSig, TransactionSignatureChecker& checker, CValidationState &state); +/**** + * @brief add an import tombstone + * @param importTx the transaction + * @param inputs the inputs to be modified + * @param nHeight the height + */ void AddImportTombstone(const CTransaction &importTx, CCoinsViewCache &inputs, int nHeight); -void RemoveImportTombstone(const CTransaction &importTx, CCoinsViewCache &inputs); -int ExistsImportTombstone(const CTransaction &importTx, const CCoinsViewCache &inputs); -bool CheckVinPubKey(const CTransaction &sourcetx, int32_t i, uint8_t pubkey33[33]); - -CMutableTransaction MakeSelfImportSourceTx(CTxDestination &dest, int64_t amount); -int32_t GetSelfimportProof(const CMutableTransaction sourceMtx, CMutableTransaction &templateMtx, ImportProof &proofNull); +/***** + * @brief remove an import tombstone from inputs + * @param importTx the transaction + * @param inputs what to modify + */ +void RemoveImportTombstone(const CTransaction &importTx, CCoinsViewCache &inputs); -#endif /* IMPORTCOIN_H */ +/***** + * @brief See if a tombstone exists + * @param importTx the transaction + * @param inputs + * @returns true if the transaction is a tombstone + */ +bool ExistsImportTombstone(const CTransaction &importTx, const CCoinsViewCache &inputs); diff --git a/src/init.cpp b/src/init.cpp index 8aac8458..605e2bee 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -35,7 +35,11 @@ #include "httprpc.h" #include "key.h" #include "notarisationdb.h" -//#include "komodo_notary.h" +#include "komodo_globals.h" +#include "komodo_notary.h" +#include "komodo_gateway.h" +#include "main.h" + #ifdef ENABLE_MINING #include "key_io.h" #endif @@ -56,6 +60,7 @@ #ifdef ENABLE_WALLET #include "wallet/wallet.h" #include "wallet/walletdb.h" + #endif #include #include @@ -94,15 +99,19 @@ using namespace std; #include "komodo_defs.h" +#include "komodo_extern_globals.h" +#include "assetchain.h" + +#include "komodo_gateway.h" +#include "rpc/net.h" extern void ThreadSendAlert(); -extern bool komodo_dailysnapshot(int32_t height); -extern int32_t KOMODO_LOADINGBLOCKS; -extern char ASSETCHAINS_SYMBOL[]; -extern int32_t KOMODO_SNAPSHOT_INTERVAL; -extern void komodo_init(int32_t height); +//extern bool komodo_dailysnapshot(int32_t height); //todo remove +//extern int32_t KOMODO_SNAPSHOT_INTERVAL; ZCJoinSplit* pzcashParams = NULL; +assetchain chainName; + #ifdef ENABLE_WALLET CWallet* pwalletMain = NULL; #endif @@ -271,7 +280,7 @@ void Shutdown() delete pcoinsdbview; pcoinsdbview = NULL; delete pblocktree; - pblocktree = NULL; + pblocktree = nullptr; delete pnotarisations; pnotarisations = nullptr; } @@ -707,7 +716,7 @@ void ThreadImport(std::vector vImportFiles) LogPrintf("Reindexing finished\n"); // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked): InitBlockIndex(); - KOMODO_LOADINGBLOCKS = 0; + KOMODO_LOADINGBLOCKS = false; } // hardcoded $DATADIR/bootstrap.dat @@ -861,11 +870,15 @@ bool AppInitServers(boost::thread_group& threadGroup) return true; } -/** Initialize bitcoin. - * @pre Parameters should be parsed and config file should be read. - */ -extern int32_t KOMODO_REWIND; +//extern int32_t KOMODO_REWIND; +/*** + * Initialize everything and fire up the services + * @pre Parameters should be parsed and config file should be read + * @param threadGroup + * @param scheduler + * @returns true on success + */ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) { // ********************************************************* Step 1: setup @@ -1374,7 +1387,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) return InitError(_("Unable to start HTTP server. See debug log for details.")); } - int64_t nStart; + int64_t nStart = GetTimeMillis(); // ********************************************************* Step 5: verify wallet database integrity #ifdef ENABLE_WALLET @@ -1551,7 +1564,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) SetRPCWarmupFinished(); uiInterface.InitMessage(_("Done loading")); pwalletMain = new CWallet("tmptmp.wallet"); - return !fRequestShutdown; + return !ShutdownRequested(); } // ********************************************************* Step 7: load block chain @@ -1668,7 +1681,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) strLoadError = _("Error initializing block database"); break; } - KOMODO_LOADINGBLOCKS = 0; + KOMODO_LOADINGBLOCKS = false; // Check for changed -txindex state if (fTxIndex != GetBoolArg("-txindex", true)) { strLoadError = _("You need to rebuild the database using -reindex to change -txindex"); @@ -1739,7 +1752,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } } - KOMODO_LOADINGBLOCKS = 0; + KOMODO_LOADINGBLOCKS = false; // As LoadBlockIndex can take several minutes, it's possible the user // requested to kill the GUI during the last operation. If so, exit. @@ -1851,7 +1864,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) RegisterValidationInterface(pwalletMain); + // TODO: lock into ZEC (ZCash) CBlockIndex *pindexRescan = chainActive.Tip(); + if (clearWitnessCaches || GetBoolArg("-rescan", false)) { pwalletMain->ClearNoteWitnessCache(); @@ -1984,10 +1999,22 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) vImportFiles.push_back(strFile); } threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); - if (chainActive.Tip() == NULL) { - LogPrintf("Waiting for genesis block to be imported...\n"); - while (!fRequestShutdown && chainActive.Tip() == NULL) - MilliSleep(10); + { + CBlockIndex *tip = nullptr; + { + LOCK(cs_main); + tip = chainActive.Tip(); + } + if (tip == nullptr) { + LogPrintf("Waiting for genesis block to be imported...\n"); + while (!ShutdownRequested() && tip == nullptr) + { + MilliSleep(10); + LOCK(cs_main); + tip = chainActive.Tip(); + } + if (ShutdownRequested()) return false; + } } // ********************************************************* Step 11: start node @@ -1999,8 +2026,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) return InitError(strErrors.str()); //// debug print - LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size()); - LogPrintf("nBestHeight = %d\n", chainActive.Height()); + { + LOCK(cs_main); + LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size()); + LogPrintf("nBestHeight = %d\n", chainActive.Height()); + } + #ifdef ENABLE_WALLET RescanWallets(); @@ -2046,5 +2077,5 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // SENDALERT threadGroup.create_thread(boost::bind(ThreadSendAlert)); - return !fRequestShutdown; + return !ShutdownRequested(); } diff --git a/src/init.h b/src/init.h index a51bba7e..b98ea8b5 100644 --- a/src/init.h +++ b/src/init.h @@ -41,6 +41,13 @@ bool ShutdownRequested(); /** Interrupt threads */ void Interrupt(boost::thread_group& threadGroup); void Shutdown(); +/*** + * Initialize everything and fire up the services + * @pre Parameters should be parsed and config file should be read + * @param threadGroup + * @param scheduler + * @returns true on success + */ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler); /** The help message mode determines what help message to show */ diff --git a/src/komodo-tx.cpp b/src/komodo-tx.cpp index f2d0d1ac..03d00877 100644 --- a/src/komodo-tx.cpp +++ b/src/komodo-tx.cpp @@ -57,6 +57,7 @@ uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 static bool fCreateBlank; static std::map registers; static const int CONTINUE_EXECUTION=-1; +assetchain chainName; // // This function returns either one of EXIT_ codes when it's expected to stop the process or diff --git a/src/komodo.cpp b/src/komodo.cpp index 5886c14e..47199b99 100644 --- a/src/komodo.cpp +++ b/src/komodo.cpp @@ -13,9 +13,19 @@ * * ******************************************************************************/ #include "komodo.h" +#include "komodo_globals.h" #include "komodo_extern_globals.h" +#include "komodo_utils.h" #include "komodo_notary.h" +#include "komodo_bitcoind.h" #include "mem_read.h" +#include "notaries_staked.h" + +static FILE *fp; // for stateupdate +//int32_t KOMODO_EXTERNAL_NOTARIES = 0; //todo remove +#include "komodo_gateway.h" +#include "komodo_events.h" +#include "komodo_ccdata.h" void komodo_currentheight_set(int32_t height) { @@ -24,7 +34,7 @@ void komodo_currentheight_set(int32_t height) sp->CURRENT_HEIGHT = height; } -extern struct NSPV_inforesp NSPV_inforesult; +extern NSPV_inforesp NSPV_inforesult; int32_t komodo_currentheight() { @@ -47,17 +57,17 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char if ( (func= fgetc(fp)) != EOF ) { bool matched = false; - if ( ASSETCHAINS_SYMBOL[0] == 0 && strcmp(symbol,"KMD") == 0 ) + if ( chainName.isKMD() && strcmp(symbol,"KMD") == 0 ) matched = true; else - matched = (strcmp(symbol,ASSETCHAINS_SYMBOL) == 0); + matched = chainName.isSymbol(symbol); int32_t ht; if ( fread(&ht,1,sizeof(ht),fp) != sizeof(ht) ) throw komodo::parse_error("Unable to read height from file"); if ( func == 'P' ) { - std::shared_ptr pk = std::make_shared(fp, ht); + komodo::event_pubkeys pk(fp, ht); if ( (KOMODO_EXTERNAL_NOTARIES && matched ) || (strcmp(symbol,"KMD") == 0 && !KOMODO_EXTERNAL_NOTARIES) ) { komodo_eventadd_pubkeys(sp, symbol, ht, pk); @@ -65,23 +75,23 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char } else if ( func == 'N' || func == 'M' ) { - std::shared_ptr evt = std::make_shared(fp, ht, dest, func == 'M'); + komodo::event_notarized evt(fp, ht, dest, func == 'M'); komodo_eventadd_notarized(sp, symbol, ht, evt); } else if ( func == 'U' ) // deprecated { - std::shared_ptr evt = std::make_shared(fp, ht); + komodo::event_u evt(fp, ht); } else if ( func == 'K' || func == 'T') { - std::shared_ptr evt = std::make_shared(fp, ht, func == 'T'); + komodo::event_kmdheight evt(fp, ht, func == 'T'); komodo_eventadd_kmdheight(sp, symbol, ht, evt); } else if ( func == 'R' ) { - std::shared_ptr evt = std::make_shared(fp, ht); + komodo::event_opreturn evt(fp, ht); // check for oversized opret - if ( evt->opret.size() < 16384*4 ) + if ( evt.opret.size() < 16384*4 ) komodo_eventadd_opreturn(sp, symbol, ht, evt); } else if ( func == 'D' ) @@ -90,14 +100,23 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char } else if ( func == 'V' ) { - std::shared_ptr evt = std::make_shared(fp, ht); + komodo::event_pricefeed evt(fp, ht); komodo_eventadd_pricefeed(sp, symbol, ht, evt); } + else if ( func == 'B' ) { + // can be written but not processed on read + } + else { + throw komodo::parse_error("Unable to parse state file: unknown event"); + } } // retrieved the func } catch(const komodo::parse_error& pe) { LogPrintf("Error occurred in parsestatefile: %s\n", pe.what()); + LogPrintf("komodostate file is invalid. Komodod will be stopped. Please remove komodostate and komodostate.ind files and start the daemon"); + std::cerr << std::endl << " Error in komodostate file: unknown event " << (char)func << ", exiting. Please remove komodostate and komodostate.ind files and start the daemon" << std::endl << std::endl; + StartShutdown(); func = -1; } return func; @@ -115,17 +134,17 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long func = filedata[fpos++]; bool matched = false; - if ( ASSETCHAINS_SYMBOL[0] == 0 && strcmp(symbol,"KMD") == 0 ) + if ( chainName.isKMD() && strcmp(symbol,"KMD") == 0 ) matched = true; else - matched = (strcmp(symbol,ASSETCHAINS_SYMBOL) == 0); + matched = chainName.isSymbol(symbol); int32_t ht; if ( mem_read(ht, filedata, fpos, datalen) != sizeof(ht) ) throw komodo::parse_error("Unable to parse height from file data"); if ( func == 'P' ) { - std::shared_ptr pk = std::make_shared(filedata, fpos, datalen, ht); + komodo::event_pubkeys pk(filedata, fpos, datalen, ht); if ( (KOMODO_EXTERNAL_NOTARIES && matched ) || (strcmp(symbol,"KMD") == 0 && !KOMODO_EXTERNAL_NOTARIES) ) { komodo_eventadd_pubkeys(sp, symbol, ht, pk); @@ -133,101 +152,95 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long } else if ( func == 'N' || func == 'M' ) { - std::shared_ptr ntz = - std::make_shared(filedata, fpos, datalen, ht, dest, func == 'M'); + komodo::event_notarized ntz(filedata, fpos, datalen, ht, dest, func == 'M'); komodo_eventadd_notarized(sp, symbol, ht, ntz); } else if ( func == 'U' ) // deprecated { - std::shared_ptr u = - std::make_shared(filedata, fpos, datalen, ht); + komodo::event_u u(filedata, fpos, datalen, ht); } else if ( func == 'K' || func == 'T' ) { - std::shared_ptr kmd_ht = - std::make_shared(filedata, fpos, datalen, ht, func == 'T'); + komodo::event_kmdheight kmd_ht(filedata, fpos, datalen, ht, func == 'T'); komodo_eventadd_kmdheight(sp, symbol, ht, kmd_ht); } else if ( func == 'R' ) { - std::shared_ptr opret = - std::make_shared(filedata, fpos, datalen, ht); + komodo::event_opreturn opret(filedata, fpos, datalen, ht); komodo_eventadd_opreturn(sp, symbol, ht, opret); } else if ( func == 'D' ) { - LogPrintf("unexpected function D[%d]\n",ht); + printf("unexpected function D[%d]\n",ht); } else if ( func == 'V' ) { - std::shared_ptr pf = - std::make_shared(filedata, fpos, datalen, ht); + komodo::event_pricefeed pf(filedata, fpos, datalen, ht); komodo_eventadd_pricefeed(sp, symbol, ht, pf); } + else if ( func == 'B' ) { + // can be written but not processed on read + } + else { + throw komodo::parse_error("Unable to parse file data: unknown event"); + } *fposp = fpos; } } catch( const komodo::parse_error& pe) { LogPrintf("Unable to parse state file data. Error: %s\n", pe.what()); + LogPrintf("komodostate file is invalid. Komodod will be stopped. Please remove komodostate and komodostate.ind files and start the daemon"); + std::cerr << std::endl << " Error in komodostate file: unknown event " << (char)func << ", exiting. Please remove komodostate and komodostate.ind files and start the daemon" << std::endl << std::endl; + StartShutdown(); func = -1; } return func; } -/*** - * @brief persist event to file stream - * @param evt the event - * @param fp the file - * @returns the number of bytes written - */ -size_t write_event(std::shared_ptr evt, FILE *fp) -{ - std::stringstream ss; - ss << evt; - std::string buf = ss.str(); - return fwrite(buf.c_str(), buf.size(), 1, fp); -} - 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 notaryid,uint256 txhash,uint32_t *pvals, uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue, uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth) { - static FILE *fp; static int32_t errs,didinit; static uint256 zero; struct komodo_state *sp; - char fname[512],symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; - int32_t retval,ht,func; + char fname[MAX_STATEFNAME+1],symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; + int32_t ht,func; uint8_t num,pubkeys[64][33]; if ( didinit == 0 ) { - portable_mutex_init(&KOMODO_KV_mutex); portable_mutex_init(&KOMODO_CC_mutex); didinit = 1; } if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) { KOMODO_INITDONE = (uint32_t)time(NULL); - LogPrintf("[%s] no komodo_stateptr\n",ASSETCHAINS_SYMBOL); + LogPrintf("[%s] no komodo_stateptr\n",chainName.symbol().c_str()); return; } if ( fp == 0 ) { - komodo_statefname(fname,ASSETCHAINS_SYMBOL,(char *)"komodostate"); - if ( (fp= fopen(fname,"rb+")) != 0 ) + komodo_statefname(fname,chainName.symbol().c_str(),(char *)"komodostate"); + if ( (fp= fopen(fname,"rb+")) != nullptr ) { - if ( (retval= komodo_faststateinit(sp,fname,symbol,dest)) > 0 ) + if ( komodo_faststateinit(sp, fname, symbol, dest) ) fseek(fp,0,SEEK_END); else { - LogPrintf("komodo_faststateinit retval.%d\n",retval); - while ( komodo_parsestatefile(sp,fp,symbol,dest) >= 0 ) + // unable to use faststateinit, so try again only slower + LogPrintf("komodo_faststateinit retval.-1\n"); + while (!ShutdownRequested() && komodo_parsestatefile(sp,fp,symbol,dest) >= 0) ; } - } else fp = fopen(fname,"wb+"); + } + else + fp = fopen(fname,"wb+"); // the state file probably did not exist, create it. + + if (ShutdownRequested()) { fclose(fp); return; } + KOMODO_INITDONE = (uint32_t)time(NULL); } if ( height <= 0 ) @@ -238,40 +251,41 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar { if ( KMDheight != 0 ) { - std::shared_ptr kmd_ht = std::make_shared(height); - kmd_ht->kheight = KMDheight; - kmd_ht->timestamp = KMDtimestamp; + komodo::event_kmdheight kmd_ht(height); + kmd_ht.kheight = KMDheight; + kmd_ht.timestamp = KMDtimestamp; write_event(kmd_ht, fp); komodo_eventadd_kmdheight(sp,symbol,height,kmd_ht); } else if ( opretbuf != 0 && opretlen > 0 ) { - std::shared_ptr evt = std::make_shared(height); - evt->txid = txhash; - evt->vout = vout; - evt->value = opretvalue; + komodo::event_opreturn evt(height); + evt.txid = txhash; + evt.vout = vout; + evt.value = opretvalue; for(uint16_t i = 0; i < opretlen; ++i) - evt->opret.push_back(opretbuf[i]); + evt.opret.push_back(opretbuf[i]); write_event(evt, fp); komodo_eventadd_opreturn(sp,symbol,height,evt); } else if ( notarypubs != 0 && numnotaries > 0 ) { - std::shared_ptr pk = std::make_shared(height); - pk->num = numnotaries; - memcpy(pk->pubkeys, notarypubs, 33 * 64); + komodo::event_pubkeys pk(height); + pk.num = numnotaries; + memcpy(pk.pubkeys, notarypubs, 33 * 64); write_event(pk, fp); komodo_eventadd_pubkeys(sp,symbol,height,pk); } + /* TODO: why is this removed in jmj_event_fix3? else if ( voutmask != 0 && numvouts > 0 ) { - std::shared_ptr evt = std::make_shared(height); - evt->n = numvouts; - evt->nid = notaryid; - memcpy(evt->mask, &voutmask, sizeof(voutmask)); - memcpy(evt->hash, &txhash, sizeof(txhash)); + komodo::event_u evt(height); + evt.n = numvouts; + evt.nid = notaryid; + memcpy(evt.mask, &voutmask, sizeof(voutmask)); + memcpy(evt.hash, &txhash, sizeof(txhash)); write_event(evt, fp); - } + } */ else if ( pvals != 0 && numpvals > 0 ) { int32_t i,nonz = 0; @@ -280,10 +294,10 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar nonz++; if ( nonz >= 32 ) { - std::shared_ptr evt = std::make_shared(height); - evt->num = numpvals; - for( uint8_t i = 0; i < evt->num; ++i) - evt->prices[i] = pvals[i]; + komodo::event_pricefeed evt(height); + evt.num = numpvals; + for( uint8_t i = 0; i < evt.num; ++i) + evt.prices[i] = pvals[i]; write_event(evt, fp); komodo_eventadd_pricefeed(sp,symbol,height,evt); } @@ -292,12 +306,12 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar { if ( sp != nullptr ) { - std::shared_ptr evt = std::make_shared(height, dest); - evt->blockhash = sp->LastNotarizedHash(); - evt->desttxid = sp->LastNotarizedDestTxId(); - evt->notarizedheight = sp->LastNotarizedHeight(); - evt->MoM = sp->LastNotarizedMoM(); - evt->MoMdepth = sp->LastNotarizedMoMDepth(); + komodo::event_notarized evt(height, dest); + evt.blockhash = sp->LastNotarizedHash(); + evt.desttxid = sp->LastNotarizedDestTxId(); + evt.notarizedheight = sp->LastNotarizedHeight(); + evt.MoM = sp->LastNotarizedMoM(); + evt.MoMdepth = sp->LastNotarizedMoMDepth(); write_event(evt, fp); komodo_eventadd_notarized(sp,symbol,height,evt); } @@ -322,8 +336,9 @@ int32_t komodo_validate_chain(uint256 srchash,int32_t notarized_height) { if ( last_rewind != 0 ) { - LogPrintf("%s FORK detected. notarized.%d %s not in this chain! last notarization %d -> rewindtarget.%d\n", - ASSETCHAINS_SYMBOL,notarized_height,srchash.ToString().c_str(),sp->LastNotarizedHeight(),rewindtarget); + LogPrintf(%s FORK detected. notarized.%d %s not in this chain! last notarization %d -> rewindtarget.%d\n", + chainName.symbol().c_str(),notarized_height,srchash.ToString().c_str(), + sp->LastNotarizedHeight(),rewindtarget); } last_rewind = rewindtarget; } @@ -344,16 +359,15 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar { if ( i == 0 && j == 0 && memcmp(NOTARY_PUBKEY33,scriptbuf+1,33) == 0 && IS_KOMODO_NOTARY ) { - LogPrintf("%s KOMODO_LASTMINED.%d -> %d\n",ASSETCHAINS_SYMBOL,KOMODO_LASTMINED,height); + LogPrintf(%s KOMODO_LASTMINED.%d -> %d\n",chainName.symbol().c_str(),KOMODO_LASTMINED,height); prevKOMODO_LASTMINED = KOMODO_LASTMINED; KOMODO_LASTMINED = height; } decode_hex(crypto777,33,CRYPTO777_PUBSECPSTR); /*for (k=0; k<33; k++) - LogPrintf("%02x",crypto777[k]); + LogPrintf(%02x",crypto777[k]); LogPrintf(" crypto777 "); for (k=0; k>16) & 0xffff) != (ccdata.CCid & 0xffff) ) - // LogPrintf("%s CCid mismatch %u != %u\n",ASSETCHAINS_SYMBOL,((MoMdepth>>16) & 0xffff),(ccdata.CCid & 0xffff)); ccdata.len = sizeof(ccdata.CCid); - if ( ASSETCHAINS_SYMBOL[0] != 0 ) + if ( !chainName.isKMD() ) { // MoMoM, depth, numpairs, (notarization ht, MoMoM offset) - if ( len+48-opoffset <= opretlen && strcmp(ccdata.symbol,ASSETCHAINS_SYMBOL) == 0 ) + if ( len+48-opoffset <= opretlen && chainName.isSymbol(ccdata.symbol) ) { len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.kmdstarti); len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.kmdendi); @@ -491,7 +498,7 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar else { if ( matched != 0 ) - LogPrintf("[%s] matched.%d VALID (%s) MoM.%s [%d] CCid.%u\n",ASSETCHAINS_SYMBOL,matched,ccdata.symbol,MoM.ToString().c_str(),MoMdepth&0xffff,(MoMdepth>>16)&0xffff); + LogPrintf("[%s] matched.%d VALID (%s) MoM.%s [%d] CCid.%u\n",chainName.symbol().c_str(),matched,ccdata.symbol,MoM.ToString().c_str(),MoMdepth&0xffff,(MoMdepth>>16)&0xffff); } if ( MoMoMdata.pairs != 0 ) free(MoMoMdata.pairs); @@ -509,19 +516,19 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar sp->SetLastNotarizedMoM(MoM); sp->SetLastNotarizedMoMDepth(MoMdepth); } - komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->LastNotarizedMoM(),sp->LastNotarizedMoMDepth()); + komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,sp->LastNotarizedMoM(),sp->LastNotarizedMoMDepth()); LogPrintf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n", - ASSETCHAINS_SYMBOL,height,sp->LastNotarizedHeight(), - ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(), - ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len, - sp->LastNotarizedMoM().ToString().c_str(),sp->LastNotarizedMoMDepth()); + chainName.symbol().c_str(),height,sp->LastNotarizedHeight(), + chainName.ToString().c_str(),srchash.ToString().c_str(), + chainName.isKMD()?"BTC":"KMD",desttxid.ToString().c_str(), + opretlen,len,sp->LastNotarizedMoM().ToString().c_str(),sp->LastNotarizedMoMDepth()); - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) { if ( signedfp == 0 ) { - char fname[512]; - komodo_statefname(fname,ASSETCHAINS_SYMBOL,(char *)"signedmasks"); + char fname[MAX_STATEFNAME+1]; + komodo_statefname(fname,chainName.symbol().c_str(),(char *)"signedmasks"); if ( (signedfp= fopen(fname,"rb+")) == 0 ) signedfp = fopen(fname,"wb"); else fseek(signedfp,0,SEEK_END); @@ -537,26 +544,23 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar //for (i=0; i 600000 && matched != 0 ) LogPrintf("%s validated.%d notarized.%d %llx reject ht.%d NOTARIZED.%d prev.%d %s.%s DESTTXID.%s len.%d opretlen.%d\n", - ccdata.symbol,validated,notarized,(long long)signedmask,height,*notarizedheightp,sp->LastNotarizedHeight(), - ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),desttxid.ToString().c_str(),len,opretlen); + ccdata.symbol,validated,notarized,(long long)signedmask,height, + *notarizedheightp, sp->LastNotarizedHeight(),chainName.ToString().c_str(), + srchash.ToString().c_str(), desttxid.ToString().c_str(),len,opretlen); } else if ( matched != 0 && i == 0 && j == 1 && opretlen == 149 ) { - if ( notaryid >= 0 && notaryid < 64 ) - komodo_paxpricefeed(height,&scriptbuf[len],opretlen); + // old pax pricefeed. Ignore. } else if ( matched != 0 ) { - //int32_t k; for (k=0; k= 32*2+4 && strcmp(ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 ) + if ( opretlen >= 32*2+4 && strcmp(chainName.ToString().c_str(),(char *)&scriptbuf[len+32*2+4]) == 0 ) { for (k=0; k<32; k++) if ( scriptbuf[len+k] != 0 ) @@ -564,17 +568,42 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar if ( k == 32 ) { *isratificationp = 1; - LogPrintf("ISRATIFICATION (%s)\n",(char *)&scriptbuf[len+32*2+4]); + LogPrintf(ISRATIFICATION (%s)\n",(char *)&scriptbuf[len+32*2+4]); } } if ( *isratificationp == 0 && (signedmask != 0 || (scriptbuf[len] != 'X' && scriptbuf[len] != 'A')) ) // && scriptbuf[len] != 'I') - komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,0,value,&scriptbuf[len],opretlen,j,zero,0); + komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,value,&scriptbuf[len],opretlen,j,zero,0); } } return(notaryid); } +// Special tx have vout[0] -> CRYPTO777 +// with more than KOMODO_MINRATIFY pay2pubkey outputs -> ratify +// 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 +// OP_RETURN: 'D' -> deposit, 'W' -> withdraw + +int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid,int32_t n) +{ + int32_t i,m; uint8_t *ptr; + LOCK(cs_main); + CTransaction tx; + uint256 hashBlock; + if ( GetTransaction(txid,tx,hashBlock,false) == 0 ) + return(-1); + else if ( n < tx.vout.size() ) + { + ptr = (uint8_t *)&tx.vout[n].scriptPubKey[0]; + m = tx.vout[n].scriptPubKey.size(); + for (i=0; inHeight); // Wallet Filter. Disabled here. Cant be activated by notaries or pools with some changes. - if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 || STAKED_NOTARY_ID > -1 ) + if ( is_STAKED(chainName.symbol()) != 0 || STAKED_NOTARY_ID > -1 ) { staked_era = STAKED_era(pindex->GetBlockTime()); if ( !fJustCheck && staked_era != lastStakedEra ) @@ -636,14 +672,14 @@ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) { if ( pindex->nHeight != hwmheight ) { - LogPrintf("%s hwmheight.%d vs pindex->nHeight.%d t.%u reorg.%d\n",ASSETCHAINS_SYMBOL,hwmheight,pindex->nHeight,(uint32_t)pindex->nTime,hwmheight-pindex->nHeight); + LogPrintf("%s hwmheight.%d vs pindex->nHeight.%d t.%u reorg.%d\n",chainName.symbol().c_str(),hwmheight,pindex->nHeight,(uint32_t)pindex->nTime,hwmheight-pindex->nHeight); komodo_purge_ccdata((int32_t)pindex->nHeight); hwmheight = pindex->nHeight; } if (!fJustCheck) { komodo_event_rewind(sp,symbol,pindex->nHeight); - komodo_stateupdate(pindex->nHeight,0,0,0,zero,0,0,0,0,-pindex->nHeight,pindex->nTime,0,0,0,0,zero,0); + komodo_stateupdate(pindex->nHeight,0,0,0,zero,0,0,-pindex->nHeight,pindex->nTime,0,0,0,0,zero,0); } } komodo_currentheight_set(chainActive.Tip()->nHeight); @@ -654,7 +690,7 @@ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) txn_count = block.vtx.size(); for (i=0; i= KOMODO_MINRATIFY) || - (numvalid >= KOMODO_MINRATIFY && ASSETCHAINS_SYMBOL[0] != 0) || - numvalid > (numnotaries/5) ) + if ( ((height < 90000 || (signedmask & 1) != 0) && numvalid >= KOMODO_MINRATIFY) + || (numvalid >= KOMODO_MINRATIFY && !chainName.isKMD()) + || numvalid > (numnotaries/5) ) { - if ( !fJustCheck && ASSETCHAINS_SYMBOL[0] != 0) + if ( !fJustCheck && !chainName.isKMD() ) { static FILE *signedfp; if ( signedfp == 0 ) { - char fname[512]; - komodo_statefname(fname,ASSETCHAINS_SYMBOL,(char *)"signedmasks"); + char fname[MAX_STATEFNAME+1]; + komodo_statefname(fname,chainName.symbol().c_str(),(char *)"signedmasks"); if ( (signedfp= fopen(fname,"rb+")) == 0 ) signedfp = fopen(fname,"wb"); else fseek(signedfp,0,SEEK_END); @@ -707,7 +743,7 @@ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) fflush(signedfp); } transaction = i; - LogPrintf("[%s] ht.%d txi.%d signedmask.%llx numvins.%d numvalid.%d numvouts.%d <<<<<<<<<<< notarized\n",ASSETCHAINS_SYMBOL,height,i,(long long)signedmask,numvins,numvalid,numvouts); + LogPrintf("[%s] ht.%d txi.%d signedmask.%llx numvins.%d numvouts.%d <<<<<<<<<<< notarized\n",chainName.symbol().c_str(),height,i,(long long)signedmask,numvins,numvouts); } notarized = 1; } @@ -734,19 +770,17 @@ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) if ( 0 && i > 0 ) { for (k=0; k 2 ) { @@ -767,27 +801,25 @@ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) } } } - if ( ASSETCHAINS_SYMBOL[0] != 0 || height < 100000 ) + if ( !chainName.isKMD() || height < 100000 ) { if ( ((signedmask & 1) != 0 && numvalid >= KOMODO_MINRATIFY) || bitweight(signedmask) > (numnotaries/3) ) { memset(&txhash,0,sizeof(txhash)); - komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0,0,zero,0); + komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,zero,0); LogPrintf("RATIFIED! >>>>>>>>>> new notaries.%d newheight.%d from height.%d\n",numvalid,(((height+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,height); } else LogPrintf("signedmask.%llx numvalid.%d wt.%d numnotaries.%d\n",(long long)signedmask,numvalid,bitweight(signedmask),numnotaries); } } } } - if ( !fJustCheck && IS_KOMODO_NOTARY && ASSETCHAINS_SYMBOL[0] == 0 ) - LogPrintf("%s ht.%d\n",ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL,height); + if ( !fJustCheck && IS_KOMODO_NOTARY && chainName.isKMD() ) + LogPrintf("%s ht.%d\n",chainName.ToString().c_str(),height); if ( !fJustCheck && pindex->nHeight == hwmheight ) - komodo_stateupdate(height,0,0,0,zero,0,0,0,0,height,(uint32_t)pindex->nTime,0,0,0,0,zero,0); + komodo_stateupdate(height,0,0,0,zero,0,0,height,(uint32_t)pindex->nTime,0,0,0,0,zero,0); } else { LogPrintf("komodo_connectblock: unexpected null pindex\n"); return(0); } - //KOMODO_INITDONE = (uint32_t)time(NULL); - //LogPrintf("%s end connect.%d\n",ASSETCHAINS_SYMBOL,pindex->nHeight); if (fJustCheck) { if ( notarisations.size() == 0 ) @@ -805,3 +837,12 @@ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) } else return(0); } + +void komodo_statefile_uninit() +{ + if (fp != nullptr) + { + fclose(fp); + fp = nullptr; + } +} diff --git a/src/komodo.h b/src/komodo.h index e250bf12..c412b22f 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -13,78 +13,41 @@ * * ******************************************************************************/ #pragma once -#include -#include -#include -#include - #include "uint256.h" +#include "chain.h" +#include "komodo_structs.h" +#include "komodo_utils.h" +#include "komodo_curve25519.h" -// #ifdef _WIN32 -// #define printf(...) -// #endif +//#include "komodo_cJSON.h" +//#include "komodo_bitcoind.h" +//#include "komodo_interest.h" // Todo: // verify: reorgs -#define KOMODO_ASSETCHAINS_WAITNOTARIZE -#define KOMODO_PAXMAX (10000 * COIN) -#include "uthash.h" -#include "utlist.h" -#include "chain.h" - -int32_t gettxout_scriptPubKey(uint8_t *scriptPubkey,int32_t maxsize,uint256 txid,int32_t n); -void komodo_event_rewind(struct komodo_state *sp,char *symbol,int32_t height); -int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block); -bool check_pprevnotarizedht(); - -#include "komodo_structs.h" -#include "komodo_utils.h" -#include "komodo_curve25519.h" - -#include "komodo_cJSON.h" -#include "komodo_bitcoind.h" -#include "komodo_interest.h" -#include "komodo_pax.h" -#include "komodo_notary.h" +//#include "komodo_kv.h" +//#include "komodo_gateway.h" +//#include "komodo_events.h" +//#include "komodo_ccdata.h" +#include int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char *dest); -#include "komodo_kv.h" -#include "komodo_jumblr.h" -#include "komodo_gateway.h" -#include "komodo_events.h" -#include "komodo_ccdata.h" void komodo_currentheight_set(int32_t height); int32_t komodo_currentheight(); -int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char *dest); - int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long *fposp,long datalen,char *symbol,char *dest); -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 KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); +void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid, + uint256 txhash,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp, + uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryid, uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i, int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp, uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp); -int32_t komodo_validate_chain(uint256 srchash,int32_t notarized_height); - -// Special tx have vout[0] -> CRYPTO777 -// with more than KOMODO_MINRATIFY pay2pubkey outputs -> ratify -// 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 -// OP_RETURN: 'D' -> deposit, 'W' -> withdraw - -int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid,int32_t n); - -int32_t komodo_notarycmp(uint8_t *scriptPubKey,int32_t scriptlen,uint8_t pubkeys[64][33],int32_t numnotaries,uint8_t rmd160[20]); - -// int32_t (!!!) -/* - read blackjok3rtt comments in main.cpp -*/ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block); diff --git a/src/komodo_bitcoind.cpp b/src/komodo_bitcoind.cpp index 03fe945d..bb43e79b 100644 --- a/src/komodo_bitcoind.cpp +++ b/src/komodo_bitcoind.cpp @@ -13,9 +13,14 @@ * * ******************************************************************************/ #include "komodo_bitcoind.h" -#include "komodo_extern_globals.h" +#include "komodo_globals.h" +#include "komodo.h" // komodo_voutupdate() #include "komodo_utils.h" // OS_milliseconds -#include "komodo_notary.h" // komodo_chosennotary() +#include "komodo_notary.h" +#include "komodo.h" +#include "rpc/net.h" +#include "init.h" + /************************************************************************ * @@ -35,7 +40,8 @@ void init_string(struct return_string *s) s->ptr[0] = '\0'; } -int tx_height( const uint256 &hash ){ +int tx_height( const uint256 &hash ) +{ int nHeight = 0; CTransaction tx; uint256 hashBlock; @@ -353,11 +359,8 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) { sprintf(url,(char *)"http://127.0.0.1:%u",port); sprintf(postdata,"{\"method\":\"%s\",\"params\":%s}",method,params); - //LogPrintf("[%s] (%s) postdata.(%s) params.(%s) USERPASS.(%s)\n",ASSETCHAINS_SYMBOL,url,postdata,params,KMDUSERPASS); retstr2 = bitcoind_RPC(&retstr,(char *)"debug",url,userpass,method,params); - //retstr = curl_post(&cHandle,url,USERPASS,postdata,0,0,0,0); } - //fprintf(stderr, "RPC RESP: %s\n", retstr2); return(retstr2); } @@ -445,7 +448,7 @@ int32_t komodo_verifynotarizedscript(int32_t height,uint8_t *script,int32_t len, LogPrintf(" notarized, "); for (i=0; i<32; i++) LogPrintf("%02x",((uint8_t *)&hash)[i]); - LogPrintf(" opreturn from [%s] ht.%d MISMATCHED\n",ASSETCHAINS_SYMBOL,height); + LogPrintf(" opreturn from [%s] ht.%d MISMATCHED\n",chainName.symbol().c_str(),height); return(-1); } @@ -465,21 +468,14 @@ int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t { char params[256],*jsonstr,*hexstr; uint8_t *script,_script[8192]; int32_t n,len,retval = -1; cJSON *json,*txjson,*vouts,*vout,*skey; script = _script; - /*params[0] = '['; - params[1] = '"'; - for (i=0; i<32; i++) - sprintf(¶ms[i*2 + 2],"%02x",((uint8_t *)&NOTARIZED_DESTTXID)[31-i]); - strcat(params,"\", 1]");*/ sprintf(params,"[\"%s\", 1]",NOTARIZED_DESTTXID.ToString().c_str()); - if ( strcmp(symbol,ASSETCHAINS_SYMBOL[0]==0?(char *)"KMD":ASSETCHAINS_SYMBOL) != 0 ) + if ( strcmp(symbol, chainName.ToString().c_str()) != 0 ) return(0); - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) - LogPrintf("[%s] src.%s dest.%s params.[%s] ht.%d notarized.%d\n",ASSETCHAINS_SYMBOL,symbol,dest,params,height,NOTARIZED_HEIGHT); if ( strcmp(dest,"KMD") == 0 ) { if ( KMDUSERPASS[0] != 0 ) { - if ( ASSETCHAINS_SYMBOL[0] != 0 ) + if ( !chainName.isKMD() ) { jsonstr = komodo_issuemethod(KMDUSERPASS,(char *)"getrawtransaction",params,KMD_PORT); //LogPrintf("userpass.(%s) got (%s)\n",KMDUSERPASS,jsonstr); @@ -498,18 +494,16 @@ int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t } else { - LogPrintf("[%s] verifynotarization error unexpected dest.(%s)\n",ASSETCHAINS_SYMBOL,dest); + LogPrintf("[%s] verifynotarization error unexpected dest.(%s)\n",chainName.symbol().c_str(),dest); return(-1); } if ( jsonstr != 0 ) { if ( (json= cJSON_Parse(jsonstr)) != 0 ) { - if ( (txjson= jobj(json,(char *)"result")) != 0 && (vouts= jarray(&n,txjson,(char *)"vout")) != 0 ) + if ( (txjson= jobj(json,(char *)"result")) != 0 && (vouts= jarray(&n,txjson,(char *)"vout")) != nullptr ) { vout = jitem(vouts,n-1); - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) - LogPrintf("vout.(%s)\n",jprint(vout,0)); if ( (skey= jobj(vout,(char *)"scriptPubKey")) != 0 ) { if ( (hexstr= jstr(skey,(char *)"hex")) != 0 ) @@ -668,7 +662,8 @@ bool komodo_checkopret(CBlock *pblock, CScript &merkleroot) bool komodo_hardfork_active(uint32_t time) { - return ( (ASSETCHAINS_SYMBOL[0] == 0 && chainActive.Height() > nDecemberHardforkHeight) || (ASSETCHAINS_SYMBOL[0] != 0 && time > nStakedDecemberHardforkTimestamp) ); //December 2019 hardfork + return ( (chainName.isKMD() && chainActive.Height() > nDecemberHardforkHeight) + || ( !chainName.isKMD() && time > nStakedDecemberHardforkTimestamp) ); //December 2019 hardfork } uint256 komodo_calcmerkleroot(CBlock *pblock, uint256 prevBlockHash, int32_t nHeight, bool fNew, CScript scriptPubKey) @@ -730,18 +725,6 @@ int32_t komodo_isPoS(CBlock *pblock, int32_t height,CTxDestination *addressout) return(0); } -void komodo_disconnect(CBlockIndex *pindex,CBlock& block) -{ - char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; - //LogPrintf("disconnect ht.%d\n",pindex->nHeight); - komodo_init(pindex->nHeight); - if ( (sp= komodo_stateptr(symbol,dest)) != 0 ) - { - //sp->rewinding = pindex->nHeight; - //LogPrintf("-%d ",pindex->nHeight); - } else LogPrintf("komodo_disconnect: ht.%d cant get komodo_state.(%s)\n",pindex->nHeight,ASSETCHAINS_SYMBOL); -} - int32_t komodo_is_notarytx(const CTransaction& tx) { uint8_t *ptr; static uint8_t crypto777[33]; @@ -801,10 +784,10 @@ int32_t komodo_block2height(CBlock *block) return(height); } -int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block) +bool komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block) { int32_t n; - if ( KOMODO_LOADINGBLOCKS == 0 ) + if ( !KOMODO_LOADINGBLOCKS ) memset(pubkey33,0xff,33); else memset(pubkey33,0,33); if ( block->vtx[0].vout.size() > 0 ) @@ -823,7 +806,7 @@ int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block) } else memset(pubkey33,0,33); } - return(0); + return false; } int32_t komodo_blockload(CBlock& block,CBlockIndex *pindex) @@ -845,28 +828,31 @@ int32_t komodo_blockload(CBlock& block,CBlockIndex *pindex) uint32_t komodo_chainactive_timestamp() { - if ( chainActive.Tip() != 0 ) - return((uint32_t)chainActive.Tip()->GetBlockTime()); - else return(0); + AssertLockHeld(cs_main); + CBlockIndex *index = chainActive.Tip(); + if ( index != nullptr ) + return((uint32_t)index->GetBlockTime()); + return 0; } CBlockIndex *komodo_chainactive(int32_t height) { - if ( chainActive.Tip() != 0 ) + AssertLockHeld(cs_main); + CBlockIndex *index = chainActive.Tip(); + if ( index != nullptr ) { - if ( height <= chainActive.Tip()->nHeight ) + if ( height <= index->nHeight ) return(chainActive[height]); } - return(0); + return 0; } uint32_t komodo_heightstamp(int32_t height) { CBlockIndex *ptr; - if ( height > 0 && (ptr= komodo_chainactive(height)) != 0 ) + if ( height > 0 && (ptr= komodo_chainactive(height)) != nullptr ) return(ptr->nTime); - //else LogPrintf("komodo_heightstamp null ptr for block.%d\n",height); - return(0); + return 0; } void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) @@ -1077,7 +1063,8 @@ bool komodo_checkpoint(int32_t *notarized_heightp, int32_t nHeight, uint256 hash else if ( nHeight == notarized_height && memcmp(&hash,¬arized_hash,sizeof(hash)) != 0 ) { // the height matches, but the hash they passed us does not match the notarized_hash we found - LogPrintf("[%s] nHeight.%d == NOTARIZED_HEIGHT.%d, diff hash\n",ASSETCHAINS_SYMBOL,nHeight,notarized_height); + LogPrintf("[%s] nHeight.%d == NOTARIZED_HEIGHT.%d, diff hash\n", + chainName.symbol().c_str(),nHeight,notarized_height); return false; } } @@ -1085,90 +1072,64 @@ bool komodo_checkpoint(int32_t *notarized_heightp, int32_t nHeight, uint256 hash return true; } -uint32_t komodo_interest_args(uint32_t *txheighttimep,int32_t *txheightp,uint32_t *tiptimep,uint64_t *valuep,uint256 hash,int32_t n) -{ - LOCK(cs_main); - CTransaction tx; uint256 hashBlock; CBlockIndex *pindex,*tipindex; - *txheighttimep = *txheightp = *tiptimep = 0; - *valuep = 0; - if ( !GetTransaction(hash,tx,hashBlock,true) ) - return(0); - uint32_t locktime = 0; - if ( n < tx.vout.size() ) - { - if ( (pindex= komodo_getblockindex(hashBlock)) != 0 ) - { - *valuep = tx.vout[n].nValue; - *txheightp = pindex->nHeight; - *txheighttimep = pindex->nTime; - if ( *tiptimep == 0 && (tipindex= chainActive.Tip()) != 0 ) - *tiptimep = (uint32_t)tipindex->nTime; - locktime = tx.nLockTime; - //LogPrintf("tx locktime.%u %.8f height.%d | tiptime.%u\n",locktime,(double)*valuep/COIN,*txheightp,*tiptimep); - } - } - return(locktime); -} - -uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); // komodo_interest.h - -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight) -{ - uint64_t value; uint32_t tiptime=0,txheighttimep; CBlockIndex *pindex; - if ( (pindex= chainActive[tipheight]) != 0 ) - tiptime = (uint32_t)pindex->nTime; - else LogPrintf("cant find height[%d]\n",tipheight); - if ( (*locktimep= komodo_interest_args(&txheighttimep,txheightp,&tiptime,&value,hash,n)) != 0 ) - { - if ( (checkvalue == 0 || value == checkvalue) && (checkheight == 0 || *txheightp == checkheight) ) - return(komodo_interest(*txheightp,value,*locktimep,tiptime)); - //LogPrintf("nValue %llu lock.%u:%u nTime.%u -> %llu\n",(long long)coins.vout[n].nValue,coins.nLockTime,timestamp,pindex->nTime,(long long)interest); - else LogPrintf("komodo_accrued_interest value mismatch %llu vs %llu or height mismatch %d vs %d\n",(long long)value,(long long)checkvalue,*txheightp,checkheight); - } - return(0); -} - int32_t komodo_nextheight() { + //AssertLockHeld(cs_main); + LOCK(cs_main); // assume usually called without lock CBlockIndex *pindex; int32_t ht; if ( (pindex= chainActive.Tip()) != 0 && (ht= pindex->nHeight) > 0 ) return(ht+1); else return(komodo_longestchain() + 1); } +/** + * @brief get the KMD chain height + * + * @param kmdheightp the chain height of KMD + * @return 1 if this chain's height >= komodo_longestchain(), otherwise 0 + */ int32_t komodo_isrealtime(int32_t *kmdheightp) { - struct komodo_state *sp; CBlockIndex *pindex; - if ( (sp= komodo_stateptrget((char *)"KMD")) != 0 ) - *kmdheightp = sp->CURRENT_HEIGHT; - else *kmdheightp = 0; - if ( (pindex= chainActive.Tip()) != 0 && pindex->nHeight >= (int32_t)komodo_longestchain() ) - return(1); - else return(0); -} + AssertLockHeld(cs_main); -int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t cmptime,int32_t dispflag) + komodo_state *sp = komodo_stateptrget( (char*)"KMD"); + if ( sp != nullptr ) + *kmdheightp = sp->CURRENT_HEIGHT; + else + *kmdheightp = 0; + CBlockIndex *pindex = chainActive.Tip(); + if ( pindex != nullptr && pindex->nHeight >= (int32_t)komodo_longestchain() ) + return 1; + return 0; +} + +/******* + * @brief validate interest in processing a transaction + * @param tx the transaction + * @param txheight the desired chain height to evaluate + * @param cmptime the block time (often the median block time of a chunk of recent blocks) + * @returns true if tx seems okay, false if tx has been in mempool too long (currently an hour + some) + */ +bool komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t cmptime) { - dispflag = 1; - if ( KOMODO_REWIND == 0 && ASSETCHAINS_SYMBOL[0] == 0 && (int64_t)tx.nLockTime >= LOCKTIME_THRESHOLD ) //1473793441 ) + if ( KOMODO_REWIND == 0 && chainName.isKMD() && (int64_t)tx.nLockTime >= LOCKTIME_THRESHOLD ) //1473793441 ) { - if ( txheight > 246748 ) + if ( txheight > 246748 ) // a long time ago { - if ( txheight < 247205 ) - cmptime -= 16000; + if ( txheight < 247205 ) // a long time ago + cmptime -= 16000; // subtract about 4 1/2 hours if ( (int64_t)tx.nLockTime < cmptime-KOMODO_MAXMEMPOOLTIME ) - { - if ( tx.nLockTime != 1477258935 && dispflag != 0 ) + { + // transaction has been in mempool for more than an hour + if ( tx.nLockTime != 1477258935 ) { - LogPrintf("komodo_validate_interest.%d reject.%d [%d] locktime %u cmp2.%u\n",dispflag,txheight,(int32_t)(tx.nLockTime - (cmptime-KOMODO_MAXMEMPOOLTIME)),(uint32_t)tx.nLockTime,cmptime); + LogPrintf("komodo_validate_interest.%d reject.%d [%d] locktime %u cmp2.%u\n",1,txheight,(int32_t)(tx.nLockTime - (cmptime-KOMODO_MAXMEMPOOLTIME)),(uint32_t)tx.nLockTime,cmptime); } - return(-1); + return false; } - if ( 0 && dispflag != 0 ) - LogPrintf("validateinterest.%d accept.%d [%d] locktime %u cmp2.%u\n",dispflag,(int32_t)txheight,(int32_t)(tx.nLockTime - (cmptime-KOMODO_MAXMEMPOOLTIME)),(int32_t)tx.nLockTime,cmptime); } } - return(0); + return true; } /* @@ -1186,11 +1147,11 @@ uint64_t komodo_commission(const CBlock *pblock,int32_t height) { static bool didinit = false,ishush3 = false; // LABS fungible chains, cannot have any block reward! - if ( is_STAKED(ASSETCHAINS_SYMBOL) == 2 ) + if ( is_STAKED(chainName.symbol()) == 2 ) return(0); if (!didinit) { - ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; + ishush3 = chainName.SymbolStartsWith("HUSH3"); didinit = true; } @@ -1350,32 +1311,6 @@ uint32_t komodo_stakehash(uint256 *hashp,char *address,uint8_t *hashbuf,uint256 return(addrhash.uints[0]); } -arith_uint256 komodo_adaptivepow_target(int32_t height,arith_uint256 bnTarget,uint32_t nTime) -{ - arith_uint256 origtarget,easy; int32_t diff,tipdiff; int64_t mult; bool fNegative,fOverflow; CBlockIndex *tipindex; - if ( height > 10 && (tipindex= komodo_chainactive(height - 1)) != 0 ) // disable offchain diffchange - { - diff = (nTime - tipindex->GetMedianTimePast()); - tipdiff = (nTime - tipindex->nTime); - if ( tipdiff > 13*ASSETCHAINS_BLOCKTIME ) - diff = tipdiff; - if ( diff >= 13 * ASSETCHAINS_BLOCKTIME && (height < 30 || tipdiff > 2*ASSETCHAINS_BLOCKTIME) ) - { - mult = diff - 12 * ASSETCHAINS_BLOCKTIME; - mult = (mult / ASSETCHAINS_BLOCKTIME) * ASSETCHAINS_BLOCKTIME + ASSETCHAINS_BLOCKTIME / 2; - origtarget = bnTarget; - bnTarget = bnTarget * arith_uint256(mult * mult); - easy.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow); - if ( bnTarget < origtarget || bnTarget > easy ) // deal with overflow - { - bnTarget = easy; - LogPrintf("tipdiff.%d diff.%d height.%d miner overflowed mult.%lld, set to mindiff\n",tipdiff,diff,height,(long long)mult); - } else LogPrintf("tipdiff.%d diff.%d height.%d miner elapsed %d, adjust by factor of %lld\n",tipdiff,diff,height,diff,(long long)mult); - } //else fprintf(stderr,"height.%d tipdiff.%d diff %d, vs %d\n",height,tipdiff,diff,13*ASSETCHAINS_BLOCKTIME); - } else LogPrintf("adaptive cant find height.%d\n",height); - return(bnTarget); -} - arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc,int32_t newStakerActive) { int32_t oldflag = 0,dispflag = 0; @@ -1627,7 +1562,7 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_ */ if ( ASSETCHAINS_STAKED < 100 && bhash < POWTarget ) { - LogPrintf("[%s:%i] isPoS but meets PoW diff nBits.%u < target.%u\n", ASSETCHAINS_SYMBOL, height, bhash.GetCompact(), POWTarget.GetCompact()); + LogPrintf("[%s:%i] isPoS but meets PoW diff nBits.%u < target.%u\n", chainName.symbol().c_str(), height, bhash.GetCompact(), POWTarget.GetCompact()); isPoS = 0; } } @@ -1867,18 +1802,13 @@ bool komodo_appendACscriptpub() void GetKomodoEarlytxidScriptPub() { + AssertLockHeld(cs_main); if ( KOMODO_EARLYTXID == zeroid ) { LogPrintf( "Restart deamon with -earlytxid.\n"); StartShutdown(); return; } - if ( ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_SNAPSHOT_INTERVAL == 0 ) - { - LogPrintf( "Prices->paymentsCC contract must have -ac_snapshot enabled to pay out.\n"); - StartShutdown(); - return; - } if ( chainActive.Height() < KOMODO_EARLYTXID_HEIGHT ) { LogPrintf("Cannot fetch -earlytxid before block %d.\n",KOMODO_EARLYTXID_HEIGHT); @@ -1995,13 +1925,10 @@ int32_t komodo_checkPOW(int64_t stakeTxValue, int32_t slowflag,CBlock *pblock,in if ( height == 0 ) return(0); } - //if ( ASSETCHAINS_ADAPTIVEPOW > 0 ) - // bnTarget = komodo_adaptivepow_target(height,bnTarget,pblock->nTime); - - if ( (ASSETCHAINS_SYMBOL[0] != 0 || height > 792000) && bhash > bnTarget ) + if ( ( !chainName.isKMD() || height > 792000) && bhash > bnTarget ) { failed = 1; - if ( height > 0 && ASSETCHAINS_SYMBOL[0] == 0 ) // for the fast case + if ( height > 0 && chainName.isKMD() ) // for the fast case { if ( (n= komodo_notaries(pubkeys,height,pblock->nTime)) > 0 ) { @@ -2013,7 +1940,7 @@ int32_t komodo_checkPOW(int64_t stakeTxValue, int32_t slowflag,CBlock *pblock,in } } } - else if ( possible == 0 || ASSETCHAINS_SYMBOL[0] != 0 ) + else if ( possible == 0 || !chainName.isKMD() ) { if ( KOMODO_TEST_ASSETCHAIN_SKIP_POW ) return(0); @@ -2054,7 +1981,7 @@ int32_t komodo_checkPOW(int64_t stakeTxValue, int32_t slowflag,CBlock *pblock,in // PoW fake blocks will be rejected here. If a staking tx is included in a block that meets PoW min diff after block 100, then this will reject it. if ( pblock->vtx.size() > 1 && pblock->vtx[pblock->vtx.size()-1].vout.size() == 2 && DecodeStakingOpRet(pblock->vtx[pblock->vtx.size()-1].vout[1].scriptPubKey, merkleroot) != 0 ) { - LogPrintf( "[%s:%d] staking tx in PoW block, nBits.%u < target.%u\n", ASSETCHAINS_SYMBOL,height,bhash.GetCompact(),bnTarget.GetCompact()); + LogPrintf( "[%s:%d] staking tx in PoW block, nBits.%u < target.%u\n", chainName.symbol().c_str(),height,bhash.GetCompact(),bnTarget.GetCompact()); return(-1); } // set the pindex->segid as this is now fully validated to be a PoW block. @@ -2070,7 +1997,7 @@ int32_t komodo_checkPOW(int64_t stakeTxValue, int32_t slowflag,CBlock *pblock,in } else if ( is_PoSblock < 0 ) { - LogPrintf("[%s:%d] unexpected negative is_PoSblock.%d\n",ASSETCHAINS_SYMBOL,height,is_PoSblock); + LogPrintf("[%s:%d] unexpected negative is_PoSblock.%d\n",chainName.symbol().c_str(),height,is_PoSblock); return(-1); } else @@ -2082,12 +2009,12 @@ int32_t komodo_checkPOW(int64_t stakeTxValue, int32_t slowflag,CBlock *pblock,in // the coinbase must pay the fees from the last transaction and the block reward at a minimum. if ( pblock->vtx.size() < 1 || pblock->vtx[0].vout.size() < 1 ) { - LogPrintf( "[%s:%d] missing coinbase.\n", ASSETCHAINS_SYMBOL, height); + LogPrintf( "[%s:%d] missing coinbase.\n", chainName.symbol().c_str(), height); return(-1); } else if ( pblock->vtx[0].vout[0].nValue < stakeTxValue ) { - LogPrintf( "[%s:%d] coinbase vout0.%lld < blockreward+stakingtxfee.%lld\n", ASSETCHAINS_SYMBOL, height, (long long)pblock->vtx[0].vout[0].nValue, (long long)stakeTxValue); + LogPrintf( "[%s:%d] coinbase vout0.%lld < blockreward+stakingtxfee.%lld\n", chainName.symbol().c_str(), height, (long long)pblock->vtx[0].vout[0].nValue, (long long)stakeTxValue); return(-1); } // set the pindex->segid as this is now fully validated to be a PoS block. @@ -2146,7 +2073,7 @@ int32_t komodo_checkPOW(int64_t stakeTxValue, int32_t slowflag,CBlock *pblock,in if ( slowflag == 0 && pblock->vtx[0].vout.size() > 1 ) { // Check the notarisation tx is to the crypto address. - if ( !komodo_is_notarytx(pblock->vtx[1]) == 1 ) + if ( !komodo_is_notarytx(pblock->vtx[1]) ) { LogPrintf( "notarisation is not to crypto address ht.%i\n",height); return(-1); @@ -2175,10 +2102,11 @@ int32_t komodo_acpublic(uint32_t tiptime) { if ( tiptime == 0 ) { + AssertLockHeld(cs_main); if ( (pindex= chainActive.Tip()) != 0 ) tiptime = pindex->nTime; } - if ( (ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"ZEX") == 0) && tiptime >= KOMODO_SAPLING_DEADLINE ) + if ( (chainName.isKMD() || chainName.isSymbol("ZEX")) && tiptime >= KOMODO_SAPLING_DEADLINE ) acpublic = 1; } return(acpublic); @@ -2233,7 +2161,7 @@ int64_t komodo_newcoins(int64_t *zfundsp,int64_t *sproutfundsp,int32_t nHeight,C } *zfundsp = zfunds; *sproutfundsp = sproutfunds; - if ( ASSETCHAINS_SYMBOL[0] == 0 && (voutsum-vinsum) == 100003*SATOSHIDEN ) // 15 times + if ( chainName.isKMD() && (voutsum-vinsum) == 100003*SATOSHIDEN ) // 15 times return(3 * SATOSHIDEN); //if ( voutsum-vinsum+zfunds > 100000*SATOSHIDEN || voutsum-vinsum+zfunds < 0 ) //. LogPrintf("ht.%d vins %.8f, vouts %.8f -> %.8f zfunds %.8f\n",nHeight,dstr(vinsum),dstr(voutsum),dstr(voutsum)-dstr(vinsum),dstr(zfunds)); @@ -2271,36 +2199,36 @@ int64_t komodo_coinsupply(int64_t *zfundsp,int64_t *sproutfundsp,int32_t height) return(supply); } - -struct komodo_staking *komodo_addutxo(struct komodo_staking *array,int32_t *numkp,int32_t *maxkp,uint32_t txtime,uint64_t nValue,uint256 txid,int32_t vout,char *address,uint8_t *hashbuf,CScript pk) +void komodo_addutxo(std::vector &array,uint32_t txtime,uint64_t nValue,uint256 txid,int32_t vout,char *address,uint8_t *hashbuf,CScript pk) { - uint256 hash; uint32_t segid32; struct komodo_staking *kp; + uint256 hash; uint32_t segid32; komodo_staking kp; segid32 = komodo_stakehash(&hash,address,hashbuf,txid,vout); - if ( *numkp >= *maxkp ) - { - *maxkp += 1000; - array = (struct komodo_staking *)realloc(array,sizeof(*array) * (*maxkp)); - //LogPrintf("realloc max.%d array.%p\n",*maxkp,array); - } - kp = &array[(*numkp)++]; - //LogPrintf("kp.%p num.%d\n",kp,*numkp); - memset(kp,0,sizeof(*kp)); - strcpy(kp->address,address); - kp->txid = txid; - kp->vout = vout; - kp->hashval = UintToArith256(hash); - kp->txtime = txtime; - kp->segid32 = segid32; - kp->nValue = nValue; - kp->scriptPubKey = pk; - return(array); + if ( array.size() >= array.capacity() ) + { + array.reserve(array.capacity() + 1000); + //LogPrintf("%s realloc array.size().%d array.capacity().%d\n", __func__, array.size(), array.capacity()); + } + //memset(&kp,0,sizeof(kp)); + strcpy(kp.address, address); + kp.txid = txid; + kp.vout = vout; + kp.hashval = UintToArith256(hash); + kp.txtime = txtime; + kp.segid32 = segid32; + kp.nValue = nValue; + kp.scriptPubKey = pk; + array.push_back(kp); + //LogPrintf("kp.%p array.size().%d\n",kp,array.size()); } int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig, uint256 merkleroot) { - static struct komodo_staking *array; static int32_t numkp,maxkp; static uint32_t lasttime; + // use thread_local to prevent crash in case of accidental thread overlapping + thread_local std::vector array; + thread_local uint32_t lasttime; + int32_t PoSperc = 0, newStakerActive; - std::set setAddress; struct komodo_staking *kp; int32_t winners,segid,minage,nHeight,counter=0,i,m,siglen=0,nMinDepth = 1,nMaxDepth = 99999999; std::vector vecOutputs; uint32_t block_from_future_rejecttime,besttime,eligible,earliest = 0; CScript best_scriptPubKey; arith_uint256 mindiff,ratio,bnTarget,tmpTarget; CBlockIndex *tipindex,*pindex; CTxDestination address; bool fNegative,fOverflow; uint8_t hashbuf[256]; CTransaction tx; uint256 hashBlock; + std::set setAddress; int32_t winners,segid,minage,nHeight,counter=0,i,m,siglen=0,nMinDepth = 1,nMaxDepth = 99999999; std::vector vecOutputs; uint32_t block_from_future_rejecttime,besttime,eligible,earliest = 0; CScript best_scriptPubKey; arith_uint256 mindiff,ratio,bnTarget,tmpTarget; CBlockIndex *pindex; CTxDestination address; bool fNegative,fOverflow; uint8_t hashbuf[256]; CTransaction tx; uint256 hashBlock; uint64_t cbPerc = *utxovaluep, tocoinbase = 0; if (!EnsureWalletIsAvailable(0)) return 0; @@ -2311,7 +2239,12 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt memset(utxotxidp,0,sizeof(*utxotxidp)); memset(utxovoutp,0,sizeof(*utxovoutp)); memset(utxosig,0,72); - if ( (tipindex= chainActive.Tip()) == 0 ) + CBlockIndex *tipindex = nullptr; + { + LOCK(cs_main); + tipindex = chainActive.Tip(); + } + if ( tipindex == nullptr ) return(0); nHeight = tipindex->nHeight + 1; if ( (minage= nHeight*3) > 6000 ) // about 100 blocks @@ -2322,7 +2255,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt // this was for VerusHash PoS64 //tmpTarget = komodo_PoWtarget(&PoSperc,bnTarget,nHeight,ASSETCHAINS_STAKED); bool resetstaker = false; - if ( array != 0 ) + if ( array.size() != 0 ) { LOCK(cs_main); CBlockIndex* pblockindex = chainActive[tipindex->nHeight]; @@ -2330,26 +2263,24 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt if ( ReadBlockFromDisk(block, pblockindex, 1) && komodo_isPoS(&block, nHeight, &addressout) != 0 && IsMine(*pwalletMain,addressout) != 0 ) { resetstaker = true; - LogPrintf( "[%s:%d] Reset ram staker after mining a block!\n",ASSETCHAINS_SYMBOL,nHeight); + LogPrintf( "[%s:%d] Reset ram staker after mining a block!\n",chainName.symbol().c_str(),nHeight); } } - if ( resetstaker || array == 0 || time(NULL) > lasttime+600 ) + if ( resetstaker || array.size() == 0 || time(NULL) > lasttime+600 ) { LOCK2(cs_main, pwalletMain->cs_wallet); pwalletMain->AvailableCoins(vecOutputs, false, NULL, true); - if ( array != 0 ) + if ( array.size() != 0 ) { - free(array); - array = 0; - maxkp = numkp = 0; + array.clear(); lasttime = 0; } BOOST_FOREACH(const COutput& out, vecOutputs) { if ( (tipindex= chainActive.Tip()) == 0 || tipindex->nHeight+1 > nHeight ) { - LogPrintf("[%s:%d] chain tip changed during staking loop t.%u counter.%d\n",ASSETCHAINS_SYMBOL,nHeight,(uint32_t)time(NULL),counter); + LogPrintf("[%s:%d] chain tip changed during staking loop t.%u counter.%d\n",chainName.symbol().c_str(),nHeight,(uint32_t)time(NULL),counter); return(0); } counter++; @@ -2368,41 +2299,45 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt continue; if ( myGetTransaction(out.tx->GetHash(),tx,hashBlock) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 ) { - array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk); - //LogPrintf("addutxo numkp.%d vs max.%d\n",numkp,maxkp); + komodo_addutxo(array,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk); + //LogPrintf("%s array.size().%d vs array.capacity().%d\n", __func__,array.size(),array.capacity()); } } } lasttime = (uint32_t)time(NULL); - //LogPrintf("finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp); + //LogPrintf("%s finished kp data of utxo for staking %u ht.%d array.size().%d array.capacity().%d\n", __func__,(uint32_t)time(NULL),nHeight,array.size(),array.capacity()); } block_from_future_rejecttime = (uint32_t)GetTime() + ASSETCHAINS_STAKED_BLOCK_FUTURE_MAX; - for (i=winners=0; inHeight+1 > nHeight ) { - LogPrintf("[%s:%d] chain tip changed during staking loop t.%u counter.%d\n",ASSETCHAINS_SYMBOL,nHeight,(uint32_t)time(NULL),i); - return(0); + LOCK(cs_main); + tipindex = chainActive.Tip(); } - kp = &array[i]; - eligible = komodo_stake(0,bnTarget,nHeight,kp->txid,kp->vout,0,(uint32_t)tipindex->nTime+ASSETCHAINS_STAKED_BLOCK_FUTURE_HALF,kp->address,PoSperc); + if ( tipindex == nullptr || tipindex->nHeight+1 > nHeight ) + { + LogPrintf("[%s:%d] chain tip changed during staking loop t.%u counter.%d\n",chainName.symbol().c_str(),nHeight,(uint32_t)time(NULL),i); + return 0; + } + komodo_staking &kp = array[i]; + eligible = komodo_stake(0,bnTarget,nHeight,kp.txid,kp.vout,0,(uint32_t)tipindex->nTime+ASSETCHAINS_STAKED_BLOCK_FUTURE_HALF,kp.address,PoSperc); if ( eligible > 0 ) { besttime = 0; - if ( eligible == komodo_stake(1,bnTarget,nHeight,kp->txid,kp->vout,eligible,(uint32_t)tipindex->nTime+ASSETCHAINS_STAKED_BLOCK_FUTURE_HALF,kp->address,PoSperc) ) + if ( eligible == komodo_stake(1,bnTarget,nHeight,kp.txid,kp.vout,eligible,(uint32_t)tipindex->nTime+ASSETCHAINS_STAKED_BLOCK_FUTURE_HALF,kp.address,PoSperc) ) { // have elegible utxo to stake with. - if ( earliest == 0 || eligible < earliest || (eligible == earliest && (*utxovaluep == 0 || kp->nValue < *utxovaluep)) ) + if ( earliest == 0 || eligible < earliest || (eligible == earliest && (*utxovaluep == 0 || kp.nValue < *utxovaluep)) ) { // is better than the previous best, so use it instead. earliest = eligible; - best_scriptPubKey = kp->scriptPubKey; - *utxovaluep = (uint64_t)kp->nValue; - decode_hex((uint8_t *)utxotxidp,32,kp->txid.GetHex().c_str()); - *utxovoutp = kp->vout; - *txtimep = kp->txtime; + best_scriptPubKey = kp.scriptPubKey; + *utxovaluep = (uint64_t)kp.nValue; + decode_hex((uint8_t *)utxotxidp,32,(char *)kp.txid.GetHex().c_str()); + *utxovoutp = kp.vout; + *txtimep = kp.txtime; } /*if ( eligible < block_from_future_rejecttime ) { @@ -2413,17 +2348,20 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt } } } - if ( numkp < 500 && array != 0 ) + if ( array.size() < 500 && array.size() != 0 ) { - free(array); - array = 0; - maxkp = numkp = 0; + array.clear(); lasttime = 0; } if ( earliest != 0 ) { bool signSuccess; SignatureData sigdata; uint64_t txfee; uint8_t *ptr; uint256 revtxid,utxotxid; - auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); + int newHeight = 0; + { + LOCK(cs_main); + newHeight = chainActive.Height() + 1; + } + auto consensusBranchId = CurrentEpochBranchId(newHeight, Params().GetConsensus()); const CKeyStore& keystore = *pwalletMain; txNew.vin.resize(1); txNew.vout.resize(1); diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 18b087fd..1269f785 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -21,19 +21,12 @@ #include "komodo_defs.h" #include "script/standard.h" #include "cc/CCinclude.h" +#include "komodo_globals.h" -int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); -int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp); -int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp); -unsigned int lwmaGetNextPOSRequired(const CBlockIndex* pindexLast, const Consensus::Params& params); bool EnsureWalletIsAvailable(bool avoidException); -extern bool fRequestShutdown; -extern CScript KOMODO_EARLYTXID_SCRIPTPUB; uint32_t komodo_heightstamp(int32_t height); -//#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"curl",(char *)"http://127.0.0.1:7776",0,0,(char *)(cmdstr)) - struct MemoryStruct { char *memory; size_t size; }; struct return_string { char *ptr; size_t len; }; @@ -128,13 +121,11 @@ uint256 komodo_calcmerkleroot(CBlock *pblock, uint256 prevBlockHash, int32_t nHe int32_t komodo_isPoS(CBlock *pblock, int32_t height,CTxDestination *addressout); -void komodo_disconnect(CBlockIndex *pindex,CBlock& block); - int32_t komodo_is_notarytx(const CTransaction& tx); int32_t komodo_block2height(CBlock *block); -int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block); +bool komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block); int32_t komodo_blockload(CBlock& block,CBlockIndex *pindex); @@ -142,8 +133,6 @@ uint32_t komodo_chainactive_timestamp(); CBlockIndex *komodo_chainactive(int32_t height); -uint32_t komodo_heightstamp(int32_t height); - void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height); int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height); @@ -169,15 +158,18 @@ uint32_t komodo_blocktime(uint256 hash); */ bool komodo_checkpoint(int32_t *notarized_heightp,int32_t nHeight,uint256 hash); -uint32_t komodo_interest_args(uint32_t *txheighttimep,int32_t *txheightp,uint32_t *tiptimep,uint64_t *valuep,uint256 hash,int32_t n); - -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); - int32_t komodo_nextheight(); int32_t komodo_isrealtime(int32_t *kmdheightp); -int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t cmptime,int32_t dispflag); +/******* + * @brief validate interest in processing a transaction + * @param tx the transaction + * @param txheight the desired chain height to evaluate + * @param cmptime the block time (often the median block time of a chunk of recent blocks) + * @returns true if tx seems okay, false if tx has been in mempool too long (currently an hour + some) + */ +bool komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t cmptime); /* komodo_checkPOW (fast) is called early in the process and should only refer to data immediately available. it is a filter to prevent bad blocks from going into the local DB. The more blocks we can filter out at this stage, the less junk in the local DB that will just get purged later on. @@ -198,8 +190,6 @@ void komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n); uint32_t komodo_stakehash(uint256 *hashp,char *address,uint8_t *hashbuf,uint256 txid,int32_t vout); -arith_uint256 komodo_adaptivepow_target(int32_t height,arith_uint256 bnTarget,uint32_t nTime); - arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc,int32_t newStakerActive); uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeight,uint256 txid,int32_t vout,uint32_t blocktime,uint32_t prevtime,char *destaddr,int32_t PoSperc); @@ -243,6 +233,6 @@ struct komodo_staking CScript scriptPubKey; }; -struct komodo_staking *komodo_addutxo(struct komodo_staking *array,int32_t *numkp,int32_t *maxkp,uint32_t txtime,uint64_t nValue,uint256 txid,int32_t vout,char *address,uint8_t *hashbuf,CScript pk); +void komodo_addutxo(std::vector &array,uint32_t txtime,uint64_t nValue,uint256 txid,int32_t vout,char *address,uint8_t *hashbuf,CScript pk); int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig, uint256 merkleroot); diff --git a/src/komodo_cJSON.c b/src/komodo_cJSON.c index c483c817..7a060e11 100644 --- a/src/komodo_cJSON.c +++ b/src/komodo_cJSON.c @@ -28,10 +28,6 @@ #include "hex.h" #include -#ifndef DBL_EPSILON -#define DBL_EPSILON 2.2204460492503131E-16 -#endif - static const char *ep; long stripquotes(char *str) diff --git a/src/komodo_cJSON.h b/src/komodo_cJSON.h index c3a06a3d..990cedf3 100644 --- a/src/komodo_cJSON.h +++ b/src/komodo_cJSON.h @@ -54,6 +54,10 @@ #define MAX_JSON_FIELD 4096 // on the big side +#ifndef DBL_EPSILON +#define DBL_EPSILON 2.2204460492503131E-16 +#endif + #ifdef __cplusplus extern "C" { diff --git a/src/komodo_ccdata.cpp b/src/komodo_ccdata.cpp index d4aebc96..09e385cd 100644 --- a/src/komodo_ccdata.cpp +++ b/src/komodo_ccdata.cpp @@ -13,12 +13,15 @@ * * ******************************************************************************/ #include "komodo_ccdata.h" +#include "komodo_globals.h" +#include "komodo_bitcoind.h" #include "komodo_extern_globals.h" #include "komodo_utils.h" // portable_mutex_lock #include "komodo_notary.h" // komodo_npptr struct komodo_ccdata *CC_data; -int32_t CC_firstheight; +// int32_t CC_firstheight; +pthread_mutex_t KOMODO_CC_mutex; uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth) { @@ -180,7 +183,7 @@ int32_t komodo_MoMoMdata(char *hexstr,int32_t hexsize,struct komodo_ccdataMoMoM void komodo_purge_ccdata(int32_t height) { struct komodo_ccdata *ccdata,*tmpptr; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) { portable_mutex_lock(&KOMODO_CC_mutex); DL_FOREACH_SAFE(CC_data,ccdata,tmpptr) diff --git a/src/komodo_curve25519.cpp b/src/komodo_curve25519.cpp index 52fa967f..120b19a8 100644 --- a/src/komodo_curve25519.cpp +++ b/src/komodo_curve25519.cpp @@ -237,7 +237,6 @@ bits256 curve25519_keypair(bits256 *pubkeyp) bits256 privkey; privkey = rand256(1); *pubkeyp = curve25519(privkey,curve25519_basepoint9()); - //LogPrintf("[%llx %llx] ",privkey.txid,(*pubkeyp).txid); return(privkey); } @@ -246,8 +245,6 @@ bits256 curve25519_shared(bits256 privkey,bits256 otherpub) bits256 shared,hash; shared = curve25519(privkey,otherpub); vcalc_sha256(0,hash.bytes,shared.bytes,sizeof(shared)); - //LogPrintf("priv.%llx pub.%llx shared.%llx -> hash.%llx\n",privkey.txid,pubkey.txid,shared.txid,hash.txid); - //hash.bytes[0] &= 0xf8, hash.bytes[31] &= 0x7f, hash.bytes[31] |= 64; return(hash); } @@ -261,74 +258,26 @@ int32_t curve25519_donna(uint8_t *mypublic,const uint8_t *secret,const uint8_t * return(0); } +/*** + * @param[out] mysecret a hash of pass + * @param[in] mypublic the public key + * @param[in] pass the password + * @param[in] passlen the length of pass + * @return a hash of mypublic (unused) + */ uint64_t conv_NXTpassword(unsigned char *mysecret,unsigned char *mypublic,uint8_t *pass,int32_t passlen) { static uint8_t basepoint[32] = {9}; - uint64_t addr; uint8_t hash[32]; + uint64_t addr; + uint8_t hash[32]; if ( pass != 0 && passlen != 0 ) vcalc_sha256(0,mysecret,pass,passlen); - mysecret[0] &= 248, mysecret[31] &= 127, mysecret[31] |= 64; + mysecret[0] &= 248; + mysecret[31] &= 127; + mysecret[31] |= 64; curve25519_donna(mypublic,mysecret,basepoint); + // hash mypublic vcalc_sha256(0,hash,mypublic,32); memcpy(&addr,hash,sizeof(addr)); - return(addr); + return addr; } - -uint256 komodo_kvprivkey(uint256 *pubkeyp,char *passphrase) -{ - uint256 privkey; - conv_NXTpassword((uint8_t *)&privkey,(uint8_t *)pubkeyp,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - return(privkey); -} - -uint256 komodo_kvsig(uint8_t *buf,int32_t len,uint256 _privkey) -{ - bits256 sig,hash,otherpub,checksig,pubkey,privkey; uint256 usig; - memcpy(&privkey,&_privkey,sizeof(privkey)); - vcalc_sha256(0,hash.bytes,buf,len); - otherpub = curve25519(hash,curve25519_basepoint9()); - pubkey = curve25519(privkey,curve25519_basepoint9()); - sig = curve25519_shared(privkey,otherpub); - checksig = curve25519_shared(hash,pubkey); - /*int32_t i; for (i=0; i "); - for (i=0; i<32; i++) - LogPrintf("%02x",((uint8_t *)&privkey)[i]); - LogPrintf(" -> "); - for (i=0; i<32; i++) - LogPrintf("%02x",((uint8_t *)&pubkey)[i]); - LogPrintf(" pubkey\n");*/ - memcpy(&usig,&sig,sizeof(usig)); - return(usig); -} - -int32_t komodo_kvsigverify(uint8_t *buf,int32_t len,uint256 _pubkey,uint256 sig) -{ - bits256 hash,checksig,pubkey; static uint256 zeroes; - memcpy(&pubkey,&_pubkey,sizeof(pubkey)); - if ( memcmp(&pubkey,&zeroes,sizeof(pubkey)) != 0 ) - { - vcalc_sha256(0,hash.bytes,buf,len); - checksig = curve25519_shared(hash,pubkey); - /*int32_t i; for (i=0; i "); - for (i=0; i<32; i++) - LogPrintf("%02x",((uint8_t *)&hash)[i]); - LogPrintf(" -> "); - for (i=0; i<32; i++) - LogPrintf("%02x",((uint8_t *)&pubkey)[i]); - LogPrintf(" verify pubkey\n"); - for (i=0; i<32; i++) - LogPrintf("%02x",((uint8_t *)&sig)[i]); - LogPrintf(" sig vs"); - for (i=0; i<32; i++) - LogPrintf("%02x",((uint8_t *)&checksig)[i]); - LogPrintf(" checksig\n");*/ - if ( memcmp(&checksig,&sig,sizeof(sig)) != 0 ) - return(-1); - //else LogPrintf("VALIDATED\n"); - } - return(0); -} \ No newline at end of file diff --git a/src/komodo_curve25519.h b/src/komodo_curve25519.h index 851a2482..a184b7af 100644 --- a/src/komodo_curve25519.h +++ b/src/komodo_curve25519.h @@ -902,12 +902,4 @@ int32_t curve25519_donna(uint8_t *mypublic,const uint8_t *secret,const uint8_t * uint64_t conv_NXTpassword(unsigned char *mysecret,unsigned char *mypublic,uint8_t *pass,int32_t passlen); -uint256 komodo_kvprivkey(uint256 *pubkeyp,char *passphrase); - -uint256 komodo_kvsig(uint8_t *buf,int32_t len,uint256 _privkey); - -int32_t komodo_kvsigverify(uint8_t *buf,int32_t len,uint256 _pubkey,uint256 sig); - - - // #endif diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 451c1a38..cf82ef4a 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -12,22 +12,23 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ +#pragma once -#ifndef KOMODO_DEFS_H -#define KOMODO_DEFS_H #include "arith_uint256.h" +#define ASSETCHAINS_MAX_ERAS 7 // needed by chain.h #include "chain.h" +#include "assetchain.h" #include "komodo_nk.h" +#define NUM_KMD_NOTARIES 64 + #define KOMODO_EARLYTXID_HEIGHT 100 -//#define ADAPTIVEPOW_CHANGETO_DEFAULTON 1572480000 #define ASSETCHAINS_MINHEIGHT 128 -#define ASSETCHAINS_MAX_ERAS 7 #define KOMODO_ELECTION_GAP 2000 #define KOMODO_ASSETCHAIN_MAXLEN 65 #define KOMODO_LIMITED_NETWORKSIZE 4 #define IGUANA_MAXSCRIPTSIZE 10001 -#define KOMODO_MAXMEMPOOLTIME 3600 // affects consensus +#define KOMODO_MAXMEMPOOLTIME 3600 // affects consensus, 3600 secs = 1hr #define CRYPTO777_PUBSECPSTR "020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9" #define KOMODO_FIRSTFUNGIBLEID 100 #define KOMODO_SAPLING_ACTIVATION 1544832000 // Dec 15th, 2018 @@ -35,18 +36,8 @@ #define ASSETCHAINS_STAKED_BLOCK_FUTURE_MAX 57 #define ASSETCHAINS_STAKED_BLOCK_FUTURE_HALF 27 #define ASSETCHAINS_STAKED_MIN_POW_DIFF 536900000 // 537000000 537300000 -#define _COINBASE_MATURITY 100 #define _ASSETCHAINS_TIMELOCKOFF 0xffffffffffffffff -// KMD Notary Seasons -// 1: May 1st 2018 1530921600 -// 2: July 15th 2019 1563148800 -> estimated height 1444000 -// 3: 3rd season ending isnt known, so use very far times in future. - // 1751328000 = dummy timestamp, 1 July 2025! - // 7113400 = 5x current KMD blockheight. -// to add 4th season, change NUM_KMD_SEASONS to 4, and add timestamp and height of activation to these arrays. - - #define SETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] |= (1 << ((bitoffset) & 7))) #define GETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] & (1 << ((bitoffset) & 7))) #define CLEARBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] &= ~(1 << ((bitoffset) & 7))) @@ -55,87 +46,53 @@ #define KOMODO_BIT63SET(x) ((x) & ((uint64_t)1 << 63)) #define KOMODO_VALUETOOBIG(x) ((x) > (uint64_t)10000000001*COIN) -//#ifndef TESTMODE -#define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) -//#else -//#define PRICES_DAYWINDOW (7) -//#endif -extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC; -extern int8_t ASSETCHAINS_ADAPTIVEPOW; +#define SATOSHIDEN ((uint64_t)100000000L) +#define dstr(x) ((double)(x) / SATOSHIDEN) +#define SMALLVAL 0.000000000000001 + +//#define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) + int32_t MAX_BLOCK_SIZE(int32_t height); -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; -extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; -extern uint32_t ASSETCHAIN_INIT, ASSETCHAINS_MAGIC; -extern int32_t ASSETCHAINS_SAPLING, ASSETCHAINS_OVERWINTER,ASSETCHAINS_BLOCKTIME; -extern uint64_t ASSETCHAINS_SUPPLY, ASSETCHAINS_FOUNDERS_REWARD; - -extern uint64_t ASSETCHAINS_TIMELOCKGTE; -extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH,KOMODO_INITDONE; - -extern bool IS_KOMODO_NOTARY; -extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,USE_EXTERNAL_PUBKEY,KOMODO_ON_DEMAND,KOMODO_PASSPORT_INITDONE,ASSETCHAINS_STAKED,KOMODO_NSPV; -extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_LASTERA,ASSETCHAINS_CBOPRET; -extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_TIMELOCKGTE, ASSETCHAINS_NONCEMASK[],ASSETCHAINS_NK[2]; + +extern int32_t ASSETCHAINS_BLOCKTIME; +extern uint32_t ASSETCHAINS_ALGO; +extern int32_t KOMODO_LONGESTCHAIN,USE_EXTERNAL_PUBKEY; +extern uint64_t ASSETCHAINS_COMMISSION; +extern uint64_t ASSETCHAINS_NONCEMASK[],ASSETCHAINS_NK[2]; extern const char *ASSETCHAINS_ALGORITHMS[]; -extern uint32_t ASSETCHAINS_NONCESHIFT[], ASSETCHAINS_HASHESPERROUND[]; -extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY,ASSETCHAINS_SCRIPTPUB; -extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33]; -extern std::vector ASSETCHAINS_PRICES,ASSETCHAINS_STOCKS; - -extern uint256 KOMODO_EARLYTXID; - -extern bool IS_KOMODO_DEALERNODE; -extern int32_t KOMODO_CONNECTING,KOMODO_CCACTIVATE; -extern uint32_t ASSETCHAINS_CC; -extern std::string CCerror,ASSETCHAINS_CCLIB; -extern uint8_t ASSETCHAINS_CCDISABLES[256]; - -extern int32_t USE_EXTERNAL_PUBKEY; -extern std::string NOTARY_PUBKEY,NOTARY_ADDRESS; -extern bool IS_MODE_EXCHANGEWALLET; -extern std::string DONATION_PUBKEY; -extern uint8_t ASSETCHAINS_PRIVATE; -extern int32_t USE_EXTERNAL_PUBKEY; +extern uint32_t ASSETCHAINS_NONCESHIFT[]; + +extern std::string CCerror; + extern bool IS_KOMODO_TESTNODE; -extern int32_t KOMODO_SNAPSHOT_INTERVAL,STAKED_NOTARY_ID,STAKED_ERA; +extern int32_t KOMODO_SNAPSHOT_INTERVAL; extern int32_t ASSETCHAINS_EARLYTXIDCONTRACT; extern int32_t ASSETCHAINS_STAKED_SPLIT_PERCENTAGE; -int tx_height( const uint256 &hash ); -extern std::vector vWhiteListAddress; extern std::map mapHeightEvalActivate; + +uint256 Parseuint256(const char *hexstr); // defined in cc/CCutilbits.cpp void komodo_netevent(std::vector payload); +/* TODO: remove +extern std::vector vWhiteListAddress; +extern std::map mapHeightEvalActivate; int32_t getacseason(uint32_t timestamp); int32_t getkmdseason(int32_t height); #define IGUANA_MAXSCRIPTSIZE 10001 +*/ #define KOMODO_KVDURATION 1440 -#define KOMODO_KVBINARY 2 -#define PRICES_SMOOTHWIDTH 1 -#define PRICES_MAXDATAPOINTS 8 -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); +#define KOMODO_KVPROTECTED 1 +/*#define PRICES_MAXDATAPOINTS 8 int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len); int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width); int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); uint32_t komodo_blocktime(uint256 hash); -int32_t komodo_longestchain(); int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int8_t komodo_segid(int32_t nocache,int32_t height); -int32_t komodo_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeight); -char *komodo_pricename(char *name,int32_t ind); -int32_t komodo_priceind(const char *symbol); -int32_t komodo_pricesinit(); -int64_t komodo_priceave(int64_t *tmpbuf,int64_t *correlated,int32_t cskip); -int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth); int32_t komodo_nextheight(); -uint32_t komodo_heightstamp(int32_t height); -int64_t komodo_pricemult(int32_t ind); -int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); -int32_t komodo_currentheight(); int32_t komodo_notarized_bracket(struct notarized_checkpoint *nps[2],int32_t height); arith_uint256 komodo_adaptivepow_target(int32_t height,arith_uint256 bnTarget,uint32_t nTime); bool komodo_hardfork_active(uint32_t time); @@ -152,7 +109,7 @@ bool komodo_txnotarizedconfirmed(uint256 txid); int32_t komodo_blockload(CBlock& block, CBlockIndex *pindex); uint32_t komodo_chainactive_timestamp(); uint32_t GetLatestTimestamp(int32_t height); - +*/ #ifndef KOMODO_NSPV_FULLNODE #define KOMODO_NSPV_FULLNODE (KOMODO_NSPV <= 0) #endif // !KOMODO_NSPV_FULLNODE @@ -160,4 +117,3 @@ uint32_t GetLatestTimestamp(int32_t height); #define KOMODO_NSPV_SUPERLITE (KOMODO_NSPV > 0) #endif // !KOMODO_NSPV_SUPERLITE -#endif diff --git a/src/komodo_events.cpp b/src/komodo_events.cpp index f79b5109..7c58cf9c 100644 --- a/src/komodo_events.cpp +++ b/src/komodo_events.cpp @@ -13,12 +13,18 @@ * * ******************************************************************************/ #include "komodo_events.h" -#include "komodo_extern_globals.h" +#include "komodo_globals.h" #include "komodo_bitcoind.h" // komodo_verifynotarization #include "komodo_notary.h" // komodo_notarized_update -#include "komodo_pax.h" // komodo_pvals -#include "komodo_gateway.h" // komodo_opreturn #include "komodo_utils.h" // portable_mutex_lock / unlock +#include "komodo_kv.h" + +#define KOMODO_EVENT_RATIFY 'P' +#define KOMODO_EVENT_NOTARIZED 'N' +#define KOMODO_EVENT_KMDHEIGHT 'K' +#define KOMODO_EVENT_REWIND 'B' +#define KOMODO_EVENT_PRICEFEED 'V' +#define KOMODO_EVENT_OPRETURN 'R' /***** * Add a notarized event to the collection @@ -27,24 +33,22 @@ * @param height * @param ntz the event */ -void komodo_eventadd_notarized( komodo_state *sp, char *symbol, int32_t height, std::shared_ptr ntz) +void komodo_eventadd_notarized( komodo_state *sp, char *symbol, int32_t height, komodo::event_notarized& ntz) { - char *coin = (ASSETCHAINS_SYMBOL[0] == 0) ? (char *)"KMD" : ASSETCHAINS_SYMBOL; - if ( IS_KOMODO_NOTARY - && komodo_verifynotarization(symbol,ntz->dest,height,ntz->notarizedheight,ntz->blockhash, ntz->desttxid) < 0 ) + && komodo_verifynotarization(symbol,ntz.dest,height,ntz.notarizedheight,ntz.blockhash, ntz.desttxid) < 0 ) { static uint32_t counter; if ( counter++ < 100 ) LogPrintf("[%s] error validating notarization ht.%d notarized_height.%d, if on a pruned %s node this can be ignored\n", - ASSETCHAINS_SYMBOL,height,ntz->notarizedheight, ntz->dest); + chainName.symbol().c_str(), height, ntz.notarizedheight, ntz.dest); } - else if ( strcmp(symbol,coin) == 0 ) + else if ( chainName.isSymbol(symbol) ) { if ( sp != nullptr ) { sp->add_event(symbol, height, ntz); - komodo_notarized_update(sp,height, ntz->notarizedheight, ntz->blockhash, ntz->desttxid, ntz->MoM, ntz->MoMdepth); + komodo_notarized_update(sp, height, ntz.notarizedheight, ntz.blockhash, ntz.desttxid, ntz.MoM, ntz.MoMdepth); } } } @@ -56,28 +60,28 @@ void komodo_eventadd_notarized( komodo_state *sp, char *symbol, int32_t height, * @param height * @param pk the event */ -void komodo_eventadd_pubkeys(komodo_state *sp, char *symbol, int32_t height, std::shared_ptr pk) +void komodo_eventadd_pubkeys(komodo_state *sp, char *symbol, int32_t height, komodo::event_pubkeys& pk) { if (sp != nullptr) { sp->add_event(symbol, height, pk); - komodo_notarysinit(height, pk->pubkeys, pk->num); + komodo_notarysinit(height, pk.pubkeys, pk.num); } } /******** * Add a pricefeed event to the collection + * @note was for PAX, deprecated * @param sp where to add * @param symbol * @param height * @param pf the event */ -void komodo_eventadd_pricefeed( komodo_state *sp, char *symbol, int32_t height, std::shared_ptr pf) +void komodo_eventadd_pricefeed( komodo_state *sp, char *symbol, int32_t height, komodo::event_pricefeed& pf) { if (sp != nullptr) { sp->add_event(symbol, height, pf); - komodo_pvals(height,pf->prices, pf->num); } } @@ -88,12 +92,16 @@ void komodo_eventadd_pricefeed( komodo_state *sp, char *symbol, int32_t height, * @param height * @param opret the event */ -void komodo_eventadd_opreturn( komodo_state *sp, char *symbol, int32_t height, std::shared_ptr opret) +void komodo_eventadd_opreturn( komodo_state *sp, char *symbol, int32_t height, komodo::event_opreturn& opret) { - if ( sp != nullptr && ASSETCHAINS_SYMBOL[0] != 0) + if ( sp != nullptr && !chainName.isKMD() ) { sp->add_event(symbol, height, opret); - komodo_opreturn(height, opret->value, opret->opret.data(), opret->opret.size(), opret->txid, opret->vout, symbol); + //komodo_opreturn(height, opret->value, opret->opret.data(), opret->opret.size(), opret->txid, opret->vout, symbol); + if ( opret.opret.data()[0] == 'K' && opret.opret.size() != 40 ) + { + komodo_kvupdate(opret.opret.data(), opret.opret.size(), opret.value); + } } } @@ -103,34 +111,25 @@ void komodo_eventadd_opreturn( komodo_state *sp, char *symbol, int32_t height, s * @param sp the state object * @param ev the event to undo */ -void komodo_event_undo(komodo_state *sp, std::shared_ptr ev) +template +void komodo_event_undo(komodo_state *sp, T& ev) { - switch ( ev->type ) +} + +template<> +void komodo_event_undo(komodo_state* sp, komodo::event_kmdheight& ev) { - case KOMODO_EVENT_RATIFY: - LogPrintf("rewind of ratify, needs to be coded.%d\n",ev->height); - break; - case KOMODO_EVENT_NOTARIZED: - break; - case KOMODO_EVENT_KMDHEIGHT: - if ( ev->height <= sp->SAVEDHEIGHT ) - sp->SAVEDHEIGHT = ev->height; - break; - case KOMODO_EVENT_PRICEFEED: - // backtrack prices; - break; - case KOMODO_EVENT_OPRETURN: - // backtrack opreturns - break; + if ( ev.height <= sp->SAVEDHEIGHT ) + sp->SAVEDHEIGHT = ev.height; } -} + void komodo_event_rewind(komodo_state *sp, char *symbol, int32_t height) { if ( sp != nullptr ) { - if ( ASSETCHAINS_SYMBOL[0] == 0 && height <= KOMODO_LASTMINED && prevKOMODO_LASTMINED != 0 ) + if ( chainName.isKMD() && height <= KOMODO_LASTMINED && prevKOMODO_LASTMINED != 0 ) { LogPrintf("undo KOMODO_LASTMINED %d <- %d\n",KOMODO_LASTMINED,prevKOMODO_LASTMINED); KOMODO_LASTMINED = prevKOMODO_LASTMINED; @@ -141,7 +140,7 @@ void komodo_event_rewind(komodo_state *sp, char *symbol, int32_t height) auto ev = sp->events.back(); if (ev-> height < height) break; - komodo_event_undo(sp, ev); + komodo_event_undo(sp, *ev); sp->events.pop_back(); } } @@ -168,22 +167,22 @@ void komodo_setkmdheight(struct komodo_state *sp,int32_t kmdheight,uint32_t time * @param height * @param kmdht the event */ -void komodo_eventadd_kmdheight(struct komodo_state *sp,char *symbol,int32_t height, std::shared_ptr kmdht) +void komodo_eventadd_kmdheight(struct komodo_state *sp,char *symbol,int32_t height, + komodo::event_kmdheight& kmdht) { if (sp != nullptr) { - if ( kmdht->kheight > 0 ) // height is advancing + if ( kmdht.kheight > 0 ) // height is advancing { sp->add_event(symbol, height, kmdht); - komodo_setkmdheight(sp, kmdht->kheight, kmdht->timestamp); + komodo_setkmdheight(sp, kmdht.kheight, kmdht.timestamp); } else // rewinding { - std::shared_ptr e = std::make_shared(height); + komodo::event_rewind e(height); sp->add_event(symbol, height, e); komodo_event_rewind(sp,symbol,height); } } } - \ No newline at end of file diff --git a/src/komodo_events.h b/src/komodo_events.h index 31cd2407..3098e1b3 100644 --- a/src/komodo_events.h +++ b/src/komodo_events.h @@ -16,17 +16,15 @@ #include "komodo_defs.h" #include "komodo_structs.h" -void komodo_eventadd_notarized(komodo_state *sp,char *symbol,int32_t height, std::shared_ptr ntz); +void komodo_eventadd_notarized(komodo_state *sp,char *symbol,int32_t height, komodo::event_notarized& ntz); -void komodo_eventadd_pubkeys(komodo_state *sp,char *symbol,int32_t height, std::shared_ptr pk); +void komodo_eventadd_pubkeys(komodo_state *sp,char *symbol,int32_t height, komodo::event_pubkeys& pk); -void komodo_eventadd_pricefeed(komodo_state *sp,char *symbol,int32_t height, std::shared_ptr pf); +void komodo_eventadd_pricefeed(komodo_state *sp,char *symbol,int32_t height, komodo::event_pricefeed& pf); -void komodo_eventadd_opreturn(komodo_state *sp,char *symbol,int32_t height, std::shared_ptr opret); +void komodo_eventadd_opreturn(komodo_state *sp,char *symbol,int32_t height, komodo::event_opreturn& opret); -void komodo_eventadd_kmdheight(komodo_state *sp,char *symbol,int32_t height,std::shared_ptr kmd_ht); - -void komodo_event_undo(komodo_state *sp, std::shared_ptr ep); +void komodo_eventadd_kmdheight(komodo_state *sp,char *symbol,int32_t height, komodo::event_kmdheight& kmd_ht); void komodo_event_rewind(komodo_state *sp,char *symbol,int32_t height); diff --git a/src/komodo_extern_globals.h b/src/komodo_extern_globals.h index 0001bda5..774340a5 100644 --- a/src/komodo_extern_globals.h +++ b/src/komodo_extern_globals.h @@ -17,7 +17,7 @@ * This file provides extern access to variables in komodo_globals.h * Please think twice before adding to this list. Can it be done with a better scope? */ -#include "komodo_structs.h" +#include "komodo_defs.h" #include #include @@ -25,7 +25,6 @@ extern bool IS_KOMODO_NOTARY; extern bool IS_KOMODO_DEALERNODE; extern char KMDUSERPASS[8192+512+1]; extern char BTCUSERPASS[8192]; -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; extern char ASSETCHAINS_USERPASS[4096]; extern uint8_t NOTARY_PUBKEY33[33]; extern uint8_t ASSETCHAINS_OVERRIDE_PUBKEY33[33]; @@ -45,16 +44,12 @@ extern int32_t KOMODO_LASTMINED; extern int32_t prevKOMODO_LASTMINED; extern int32_t KOMODO_CCACTIVATE; extern int32_t JUMBLR_PAUSE; -extern int32_t NUM_PRICES; extern int32_t KOMODO_MININGTHREADS; extern int32_t STAKED_NOTARY_ID; extern int32_t USE_EXTERNAL_PUBKEY; -extern int32_t ASSETCHAINS_SEED; +//extern int32_t ASSETCHAINS_SEED; extern int32_t KOMODO_ON_DEMAND; extern int32_t KOMODO_EXTERNAL_NOTARIES; -extern int32_t KOMODO_PASSPORT_INITDONE; -extern int32_t KOMODO_EXTERNAL_NOTARIES; -extern int32_t KOMODO_PAX; extern int32_t KOMODO_REWIND; extern int32_t STAKED_ERA; extern int32_t KOMODO_CONNECTING; @@ -62,15 +57,14 @@ extern int32_t KOMODO_EXTRASATOSHI; extern int32_t ASSETCHAINS_FOUNDERS; extern int32_t ASSETCHAINS_CBMATURITY; extern int32_t KOMODO_NSPV; -extern int32_t KOMODO_LOADINGBLOCKS; // not actually in komodo_globals.h, but used in several places -extern uint32_t *PVALS; +extern bool KOMODO_LOADINGBLOCKS; extern uint32_t ASSETCHAINS_CC; extern uint32_t KOMODO_STOPAT; extern uint32_t KOMODO_DPOWCONFS; extern uint32_t STAKING_MIN_DIFF; extern uint32_t ASSETCHAIN_INIT; extern uint32_t ASSETCHAINS_NUMALGOS; -extern uint32_t ASSETCHAINS_MINDIFF[3]; +extern uint32_t ASSETCHAINS_MINDIFF[]; extern uint64_t PENDING_KOMODO_TX; extern uint64_t ASSETCHAINS_TIMELOCKGTE; extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1]; @@ -81,17 +75,17 @@ extern uint64_t ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS+1]; extern uint64_t ASSETCHAINS_PEGSCCPARAMS[3]; extern uint64_t ASSETCHAINS_TIMEUNLOCKFROM; extern uint64_t ASSETCHAINS_TIMEUNLOCKTO; -extern uint64_t ASSETCHAINS_CBOPRET; //extern std::mutex komodo_mutex; extern pthread_mutex_t komodo_mutex; -extern std::vector Mineropret; -extern pthread_mutex_t KOMODO_KV_mutex; extern pthread_mutex_t KOMODO_CC_mutex; -extern komodo_kv *KOMODO_KV; -extern pax_transaction *PAX; -extern knotaries_entry *Pubkeys; -extern komodo_state KOMODO_STATES[34]; -int32_t komodo_baseid(char *origbase); +/** + * @brief Given a currency name, return the index in the KOMODO_STATES array + * + * @param origbase the currency name to look for + * @return the index in the array, or -1 + */ +int32_t komodo_baseid(const char *origbase); + uint64_t komodo_current_supply(uint32_t nHeight); diff --git a/src/komodo_gateway.cpp b/src/komodo_gateway.cpp index 5f6e6ad1..8cf7ebb9 100644 --- a/src/komodo_gateway.cpp +++ b/src/komodo_gateway.cpp @@ -12,618 +12,11 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ -//#include "komodo_gateway.h" #include "komodo.h" -#include "komodo_extern_globals.h" +#include "komodo_globals.h" #include "komodo_utils.h" // komodo_stateptrget #include "komodo_bitcoind.h" // komodo_checkcommission - -struct komodo_extremeprice -{ - uint256 blockhash; - uint32_t pricebits,timestamp; - int32_t height; - int16_t dir,ind; -} ExtremePrice; - -uint32_t PriceCache[KOMODO_LOCALPRICE_CACHESIZE][KOMODO_MAXPRICES];//4+sizeof(Cryptos)/sizeof(*Cryptos)+sizeof(Forex)/sizeof(*Forex)]; -int64_t PriceMult[KOMODO_MAXPRICES]; - -struct komodo_priceinfo -{ - FILE *fp; - char symbol[64]; -} PRICES[KOMODO_MAXPRICES]; - -const char *Cryptos[] = { "KMD", "ETH" }; // must be on binance (for now) -// "LTC", "BCHABC", "XMR", "IOTA", "ZEC", "WAVES", "LSK", "DCR", "RVN", "DASH", "XEM", "BTS", "ICX", "HOT", "STEEM", "ENJ", "STRAT" -const char *Forex[] = -{ "BGN","NZD","ILS","RUB","CAD","PHP","CHF","AUD","JPY","TRY","HKD","MYR","HRK","CZK","IDR","DKK","NOK","HUF","GBP","MXN","THB","ISK","ZAR","BRL","SGD","PLN","INR","KRW","RON","CNY","SEK","EUR" -}; // must be in ECB list - -int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base) -{ - int32_t baseid; struct komodo_state *sp; int64_t netliability,maxallowed,maxval; - *available = *deposited = *issued = *withdrawn = *approved = *redeemed = 0; - if ( (baseid= komodo_baseid(base)) >= 0 ) - { - if ( (sp= komodo_stateptrget(base)) != 0 ) - { - *deposited = sp->deposited; - *issued = sp->issued; - *withdrawn = sp->withdrawn; - *approved = sp->approved; - *redeemed = sp->redeemed; - maxval = sp->approved; - if ( sp->withdrawn > maxval ) - maxval = sp->withdrawn; - netliability = (sp->issued - maxval) - sp->shorted; - maxallowed = komodo_maxallowed(baseid); - if ( netliability < maxallowed ) - *available = (maxallowed - netliability); - //LogPrintf("%llu - %llu %s %.8f %.8f %.8f %.8f %.8f\n",(long long)maxallowed,(long long)netliability,base,dstr(*deposited),dstr(*issued),dstr(*withdrawn),dstr(*approved),dstr(*redeemed)); - return(0); - } else LogPrintf("pax_fiatstatus cant get basesp.%s\n",base); - } // else LogPrintf("pax_fiatstatus illegal base.%s\n",base); - return(-1); -} - -void pax_keyset(uint8_t *buf,uint256 txid,uint16_t vout,uint8_t type) -{ - memcpy(buf,&txid,32); - memcpy(&buf[32],&vout,2); - buf[34] = type; -} - -struct pax_transaction *komodo_paxfind(uint256 txid,uint16_t vout,uint8_t type) -{ - struct pax_transaction *pax; uint8_t buf[35]; - pthread_mutex_lock(&komodo_mutex); - pax_keyset(buf,txid,vout,type); - HASH_FIND(hh,PAX,buf,sizeof(buf),pax); - pthread_mutex_unlock(&komodo_mutex); - return(pax); -} - -struct pax_transaction *komodo_paxfinds(uint256 txid,uint16_t vout) -{ - struct pax_transaction *pax; int32_t i; uint8_t types[] = { 'I', 'D', 'X', 'A', 'W' }; - for (i=0; itxid = txid; - pax->vout = vout; - pax->type = type; - memcpy(pax->buf,buf,sizeof(pax->buf)); - HASH_ADD_KEYPTR(hh,PAX,pax->buf,sizeof(pax->buf),pax); - //LogPrintf("ht.%d create pax.%p mark.%d\n",height,pax,mark); - } - if ( pax != 0 ) - { - pax->marked = mark; - //if ( height > 214700 || pax->height > 214700 ) - // LogPrintf("mark ht.%d %.8f %.8f\n",pax->height,dstr(pax->komodoshis),dstr(pax->fiatoshis)); - - } - pthread_mutex_unlock(&komodo_mutex); - return(pax); -} - -void komodo_paxdelete(struct pax_transaction *pax) -{ - return; // breaks when out of order - pthread_mutex_lock(&komodo_mutex); - HASH_DELETE(hh,PAX,pax); - pthread_mutex_unlock(&komodo_mutex); -} - -void komodo_gateway_deposit(char *coinaddr,uint64_t value,char *symbol,uint64_t fiatoshis,uint8_t *rmd160,uint256 txid,uint16_t vout,uint8_t type,int32_t height,int32_t otherheight,char *source,int32_t approved) // assetchain context -{ - struct pax_transaction *pax; uint8_t buf[35]; int32_t addflag = 0; struct komodo_state *sp; char str[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN],*s; - //if ( KOMODO_PAX == 0 ) - // return; - //if ( strcmp(symbol,ASSETCHAINS_SYMBOL) != 0 ) - // return; - sp = komodo_stateptr(str,dest); - pthread_mutex_lock(&komodo_mutex); - pax_keyset(buf,txid,vout,type); - HASH_FIND(hh,PAX,buf,sizeof(buf),pax); - if ( pax == 0 ) - { - pax = (struct pax_transaction *)calloc(1,sizeof(*pax)); - pax->txid = txid; - pax->vout = vout; - pax->type = type; - memcpy(pax->buf,buf,sizeof(pax->buf)); - HASH_ADD_KEYPTR(hh,PAX,pax->buf,sizeof(pax->buf),pax); - addflag = 1; - if ( 0 && ASSETCHAINS_SYMBOL[0] == 0 ) - { - int32_t i; for (i=0; i<32; i++) - LogPrintf("%02x",((uint8_t *)&txid)[i]); - LogPrintf(" v.%d [%s] kht.%d ht.%d create pax.%p symbol.%s source.%s\n",vout,ASSETCHAINS_SYMBOL,height,otherheight,pax,symbol,source); - } - } - pthread_mutex_unlock(&komodo_mutex); - if ( coinaddr != 0 ) - { - strcpy(pax->coinaddr,coinaddr); - if ( value != 0 ) - pax->komodoshis = value; - if ( symbol != 0 ) - strcpy(pax->symbol,symbol); - if ( source != 0 ) - strcpy(pax->source,source); - if ( fiatoshis != 0 ) - pax->fiatoshis = fiatoshis; - if ( rmd160 != 0 ) - memcpy(pax->rmd160,rmd160,20); - if ( height != 0 ) - pax->height = height; - if ( otherheight != 0 ) - pax->otherheight = otherheight; - } - else - { - pax->marked = height; - //LogPrintf("pax.%p MARK DEPOSIT ht.%d other.%d\n",pax,height,otherheight); - } -} - -int32_t komodo_rwapproval(int32_t rwflag,uint8_t *opretbuf,struct pax_transaction *pax) -{ - int32_t i,len = 0; - if ( rwflag == 1 ) - { - for (i=0; i<32; i++) - opretbuf[len++] = ((uint8_t *)&pax->txid)[i]; - opretbuf[len++] = pax->vout & 0xff; - opretbuf[len++] = (pax->vout >> 8) & 0xff; - } - else - { - for (i=0; i<32; i++) - ((uint8_t *)&pax->txid)[i] = opretbuf[len++]; - //for (i=0; i<32; i++) - // LogPrintf("%02x",((uint8_t *)&pax->txid)[31-i]); - pax->vout = opretbuf[len++]; - pax->vout += ((uint32_t)opretbuf[len++] << 8); - //LogPrintf(" txid v.%d\n",pax->vout); - } - len += iguana_rwnum(rwflag,&opretbuf[len],sizeof(pax->komodoshis),&pax->komodoshis); - len += iguana_rwnum(rwflag,&opretbuf[len],sizeof(pax->fiatoshis),&pax->fiatoshis); - len += iguana_rwnum(rwflag,&opretbuf[len],sizeof(pax->height),&pax->height); - len += iguana_rwnum(rwflag,&opretbuf[len],sizeof(pax->otherheight),&pax->otherheight); - if ( rwflag != 0 ) - { - memcpy(&opretbuf[len],pax->rmd160,20), len += 20; - for (i=0; i<4; i++) - opretbuf[len++] = pax->source[i]; - } - else - { - memcpy(pax->rmd160,&opretbuf[len],20), len += 20; - for (i=0; i<4; i++) - pax->source[i] = opretbuf[len++]; - } - return(len); -} - -int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t *values,int64_t *srcvalues,int32_t *kmdheights,int32_t *otherheights,int8_t *baseids,uint8_t *rmd160s,uint8_t *opretbuf,int32_t opretlen,int32_t iskomodo) -{ - struct pax_transaction p,*pax; int32_t i,n=0,j,len=0,incr,height,otherheight; uint8_t type,rmd160[20]; uint64_t fiatoshis; char symbol[KOMODO_ASSETCHAIN_MAXLEN]; - //if ( KOMODO_PAX == 0 ) - // return(0); - incr = 34 + (iskomodo * (2*sizeof(fiatoshis) + 2*sizeof(height) + 20 + 4)); - //41e77b91cb68dc2aa02fa88550eae6b6d44db676a7e935337b6d1392d9718f03cb0200305c90660400000000fbcbeb1f000000bde801006201000058e7945ad08ddba1eac9c9b6c8e1e97e8016a2d152 - - // 41e94d736ec69d88c08b5d238abeeca609c02357a8317e0d56c328bcb1c259be5d0200485bc80200000000404b4c000000000059470200b80b000061f22ba7d19fe29ac3baebd839af8b7127d1f9075553440046bb4cc7a3b5cd39dffe7206507a3482a00780e617f68b273cce9817ed69298d02001069ca1b0000000080f0fa02000000005b470200b90b000061f22ba7d19fe29ac3baebd839af8b7127d1f90755 - - //for (i=0; i>>>>>> %s: (%s) fiat %.8f kmdheight.%d other.%d -> %s %.8f\n",type=='A'?"approvedA":"issuedX",baseids[n]>=0?CURRENCIES[baseids[n]]:"???",dstr(p.fiatoshis),kmdheights[n],otherheights[n],coinaddr,dstr(values[n])); - } - } - } - else - { - for (i=0; i<4; i++) - base[i] = opretbuf[opretlen-4+i]; - for (j=0; j<32; j++) - { - ((uint8_t *)&txids[n])[j] = opretbuf[len++]; - //LogPrintf("%02x",((uint8_t *)&txids[n])[j]); - } - vouts[n] = opretbuf[len++]; - vouts[n] = (opretbuf[len++] << 8) | vouts[n]; - baseids[n] = komodo_baseid(base); - if ( (pax= komodo_paxfinds(txids[n],vouts[n])) != 0 ) - { - values[n] = (strcmp("KMD",base) == 0) ? pax->komodoshis : pax->fiatoshis; - srcvalues[n] = (strcmp("KMD",base) == 0) ? pax->fiatoshis : pax->komodoshis; - kmdheights[n] = pax->height; - otherheights[n] = pax->otherheight; - memcpy(&rmd160s[n * 20],pax->rmd160,20); - } - } - //LogPrintf(" komodo_issued_opreturn issuedtxid v%d i.%d opretlen.%d\n",vouts[n],n,opretlen); - } - } - return(n); -} - -int32_t komodo_paxcmp(char *symbol,int32_t kmdheight,uint64_t value,uint64_t checkvalue,uint64_t seed) -{ - int32_t ratio; - if ( seed == 0 && checkvalue != 0 ) - { - ratio = ((value << 6) / checkvalue); - if ( ratio >= 60 && ratio <= 67 ) - return(0); - else - { - if ( ASSETCHAINS_SYMBOL[0] != 0 ) - LogPrintf("ht.%d ignore mismatched %s value %lld vs checkvalue %lld -> ratio.%d\n",kmdheight,symbol,(long long)value,(long long)checkvalue,ratio); - return(-1); - } - } - else if ( checkvalue != 0 ) - { - ratio = ((value << 10) / checkvalue); - if ( ratio >= 1023 && ratio <= 1025 ) - return(0); - } - return(value != checkvalue); -} - -uint64_t komodo_paxtotal() -{ - struct pax_transaction *pax,*pax2,*tmp,*tmp2; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN],*str; int32_t i,ht; int64_t checktoshis; uint64_t seed,total = 0; struct komodo_state *basesp; - if ( KOMODO_PASSPORT_INITDONE == 0 ) //KOMODO_PAX == 0 || - return(0); - if ( komodo_isrealtime(&ht) == 0 ) - return(0); - else - { - HASH_ITER(hh,PAX,pax,tmp) - { - if ( pax->marked != 0 ) - continue; - if ( pax->type == 'A' || pax->type == 'D' || pax->type == 'X' ) - str = pax->symbol; - else str = pax->source; - basesp = komodo_stateptrget(str); - if ( basesp != 0 && pax->didstats == 0 ) - { - if ( pax->type == 'I' && (pax2= komodo_paxfind(pax->txid,pax->vout,'D')) != 0 ) - { - if ( pax2->fiatoshis != 0 ) - { - pax->komodoshis = pax2->komodoshis; - pax->fiatoshis = pax2->fiatoshis; - basesp->issued += pax->fiatoshis; - pax->didstats = 1; - if ( strcmp(str,ASSETCHAINS_SYMBOL) == 0 ) - LogPrintf("########### %p issued %s += %.8f kmdheight.%d %.8f other.%d\n",basesp,str,dstr(pax->fiatoshis),pax->height,dstr(pax->komodoshis),pax->otherheight); - pax2->marked = pax->height; - pax->marked = pax->height; - } - } - else if ( pax->type == 'W' ) - { - //bitcoin_address(coinaddr,addrtype,rmd160,20); - if ( (checktoshis= komodo_paxprice(&seed,pax->height,pax->source,(char *)"KMD",(uint64_t)pax->fiatoshis)) != 0 ) - { - if ( komodo_paxcmp(pax->source,pax->height,pax->komodoshis,checktoshis,seed) != 0 ) - { - pax->marked = pax->height; - //LogPrintf("WITHDRAW.%s mark <- %d %.8f != %.8f\n",pax->source,pax->height,dstr(checktoshis),dstr(pax->komodoshis)); - } - else if ( pax->validated == 0 ) - { - pax->validated = pax->komodoshis = checktoshis; - //int32_t j; for (j=0; j<32; j++) - // LogPrintf("%02x",((uint8_t *)&pax->txid)[j]); - //if ( strcmp(str,ASSETCHAINS_SYMBOL) == 0 ) - // LogPrintf(" v%d %p got WITHDRAW.%s kmd.%d ht.%d %.8f -> %.8f/%.8f\n",pax->vout,pax,pax->source,pax->height,pax->otherheight,dstr(pax->fiatoshis),dstr(pax->komodoshis),dstr(checktoshis)); - } - } - } - } - } - } - komodo_stateptr(symbol,dest); - HASH_ITER(hh,PAX,pax,tmp) - { - pax->ready = 0; - if ( 0 && pax->type == 'A' ) - LogPrintf("%p pax.%s <- %s marked.%d %.8f -> %.8f validated.%d approved.%d\n",pax,pax->symbol,pax->source,pax->marked,dstr(pax->komodoshis),dstr(pax->fiatoshis),pax->validated != 0,pax->approved != 0); - if ( pax->marked != 0 ) - continue; - if ( strcmp(symbol,pax->symbol) == 0 || pax->type == 'A' ) - { - if ( pax->marked == 0 ) - { - if ( komodo_is_issuer() != 0 ) - { - if ( pax->validated != 0 && pax->type == 'D' ) - { - total += pax->fiatoshis; - pax->ready = 1; - } - } - else if ( pax->approved != 0 && pax->type == 'A' ) - { - if ( pax->validated != 0 ) - { - total += pax->komodoshis; - pax->ready = 1; - } - else - { - seed = 0; - checktoshis = komodo_paxprice(&seed,pax->height,pax->source,(char *)"KMD",(uint64_t)pax->fiatoshis); - //LogPrintf("paxtotal PAX_fiatdest ht.%d price %s %.8f -> KMD %.8f vs %.8f\n",pax->height,pax->symbol,(double)pax->fiatoshis/COIN,(double)pax->komodoshis/COIN,(double)checktoshis/COIN); - //LogPrintf(" v%d %.8f k.%d ht.%d\n",pax->vout,dstr(pax->komodoshis),pax->height,pax->otherheight); - if ( seed != 0 && checktoshis != 0 ) - { - if ( checktoshis == pax->komodoshis ) - { - total += pax->komodoshis; - pax->validated = pax->komodoshis; - pax->ready = 1; - } else pax->marked = pax->height; - } - } - } - if ( 0 && pax->ready != 0 ) - LogPrintf("%p (%c) pax.%s marked.%d %.8f -> %.8f validated.%d approved.%d ready.%d ht.%d\n",pax,pax->type,pax->symbol,pax->marked,dstr(pax->komodoshis),dstr(pax->fiatoshis),pax->validated != 0,pax->approved != 0,pax->ready,pax->height); - } - } - } - //LogPrintf("paxtotal %.8f\n",dstr(total)); - return(total); -} - -int32_t komodo_pending_withdraws(char *opretstr) // todo: enforce deterministic order -{ - struct pax_transaction *pax,*pax2,*tmp,*paxes[64]; uint8_t opretbuf[16384*4]; int32_t i,n,ht,len=0; uint64_t total = 0; - if ( KOMODO_PAX == 0 || KOMODO_PASSPORT_INITDONE == 0 ) - return(0); - if ( komodo_isrealtime(&ht) == 0 || ASSETCHAINS_SYMBOL[0] != 0 ) - return(0); - n = 0; - HASH_ITER(hh,PAX,pax,tmp) - { - if ( pax->type == 'W' ) - { - if ( (pax2= komodo_paxfind(pax->txid,pax->vout,'A')) != 0 ) - { - if ( pax2->approved != 0 ) - pax->approved = pax2->approved; - } - else if ( (pax2= komodo_paxfind(pax->txid,pax->vout,'X')) != 0 ) - pax->approved = pax->height; - //LogPrintf("pending_withdraw: pax %s marked.%u approved.%u validated.%llu\n",pax->symbol,pax->marked,pax->approved,(long long)pax->validated); - if ( pax->marked == 0 && pax->approved == 0 && pax->validated != 0 ) //strcmp((char *)"KMD",pax->symbol) == 0 && - { - if ( n < sizeof(paxes)/sizeof(*paxes) ) - { - paxes[n++] = pax; - //int32_t j; for (j=0; j<32; j++) - // LogPrintf("%02x",((uint8_t *)&pax->txid)[j]); - //LogPrintf(" %s.(kmdht.%d ht.%d marked.%u approved.%d validated %.8f) %.8f\n",pax->source,pax->height,pax->otherheight,pax->marked,pax->approved,dstr(pax->validated),dstr(pax->komodoshis)); - } - } - } - } - opretstr[0] = 0; - if ( n > 0 ) - { - opretbuf[len++] = 'A'; - qsort(paxes,n,sizeof(*paxes),_paxorder); - for (i=0; i>3)*7 ) - len += komodo_rwapproval(1,&opretbuf[len],paxes[i]); - } - if ( len > 0 ) - init_hexbytes_noT(opretstr,opretbuf,len); - } - //LogPrintf("komodo_pending_withdraws len.%d PAXTOTAL %.8f\n",len,dstr(komodo_paxtotal())); - return(len); -} - -int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t tokomodo) -{ - struct pax_transaction *pax,*tmp; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; uint8_t *script,opcode,opret[16384*4],data[16384*4]; int32_t i,baseid,ht,len=0,opretlen=0,numvouts=1; struct komodo_state *sp; uint64_t available,deposited,issued,withdrawn,approved,redeemed,mask,sum = 0; - if ( KOMODO_PASSPORT_INITDONE == 0 )//KOMODO_PAX == 0 || - return(0); - struct komodo_state *kmdsp = komodo_stateptrget((char *)"KMD"); - sp = komodo_stateptr(symbol,dest); - strcpy(symbol,base); - if ( ASSETCHAINS_SYMBOL[0] != 0 && komodo_baseid(ASSETCHAINS_SYMBOL) < 0 ) - return(0); - PENDING_KOMODO_TX = 0; - for (i=0; i<3; i++) - { - if ( komodo_isrealtime(&ht) != 0 ) - break; -#ifdef WIN32 - boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); -#else - sleep(1); -#endif - } - if ( i == 3 ) - { - if ( tokomodo == 0 ) - LogPrintf("%s not realtime ht.%d\n",ASSETCHAINS_SYMBOL,ht); - return(0); - } - if ( tokomodo == 0 ) - { - opcode = 'I'; - } - else - { - opcode = 'X'; - if ( 1 || komodo_paxtotal() == 0 ) - return(0); - } - HASH_ITER(hh,PAX,pax,tmp) - { - if ( pax->type != 'D' && pax->type != 'A' ) - continue; - { -#ifdef KOMODO_ASSETCHAINS_WAITNOTARIZE - if ( pax->height > 236000 ) - { - if ( kmdsp != 0 && kmdsp->LastNotarizedHeight() >= pax->height ) - pax->validated = pax->komodoshis; - else if ( kmdsp->CURRENT_HEIGHT > pax->height+30 ) - pax->validated = pax->ready = 0; - } - else - { - if ( kmdsp != 0 && (kmdsp->LastNotarizedHeight() >= pax->height || kmdsp->CURRENT_HEIGHT > pax->height+30) ) // assumes same chain as notarize - pax->validated = pax->komodoshis; - else pax->validated = pax->ready = 0; - } -#else - pax->validated = pax->komodoshis; -#endif - } - if ( ASSETCHAINS_SYMBOL[0] != 0 && (pax_fiatstatus(&available,&deposited,&issued,&withdrawn,&approved,&redeemed,symbol) != 0 || available < pax->fiatoshis) ) - { - //if ( pax->height > 214700 || strcmp(ASSETCHAINS_SYMBOL,symbol) == 0 ) - // LogPrintf("miner.[%s]: skip %s %.8f when avail %.8f deposited %.8f, issued %.8f withdrawn %.8f approved %.8f redeemed %.8f\n",ASSETCHAINS_SYMBOL,symbol,dstr(pax->fiatoshis),dstr(available),dstr(deposited),dstr(issued),dstr(withdrawn),dstr(approved),dstr(redeemed)); - continue; - } - /*LogPrintf("pax.%s marked.%d %.8f -> %.8f ready.%d validated.%d\n",pax->symbol,pax->marked,dstr(pax->komodoshis),dstr(pax->fiatoshis),pax->ready!=0,pax->validated!=0); - if ( pax->marked != 0 || (pax->type != 'D' && pax->type != 'A') || pax->ready == 0 ) - { - LogPrintf("reject 2\n"); - continue; - }*/ - if ( ASSETCHAINS_SYMBOL[0] != 0 && (strcmp(pax->symbol,symbol) != 0 || pax->validated == 0 || pax->ready == 0) ) - { - if ( strcmp(pax->symbol,ASSETCHAINS_SYMBOL) == 0 ) - LogPrintf("pax->symbol.%s != %s or null pax->validated %.8f ready.%d ht.(%d %d)\n",pax->symbol,symbol,dstr(pax->validated),pax->ready,kmdsp->CURRENT_HEIGHT,pax->height); - pax->marked = pax->height; - continue; - } - if ( pax->ready == 0 ) - continue; - if ( pax->type == 'A' && ASSETCHAINS_SYMBOL[0] == 0 ) - { - if ( kmdsp != 0 ) - { - if ( (baseid= komodo_baseid(pax->symbol)) < 0 || ((1LL << baseid) & sp->RTmask) == 0 ) - { - LogPrintf("not RT for (%s) %llx baseid.%d %llx\n",pax->symbol,(long long)sp->RTmask,baseid,(long long)(1LL< %.8f ready.%d validated.%d approved.%d\n",tokomodo,pax->type,pax,pax->symbol,pax->marked,dstr(pax->komodoshis),dstr(pax->fiatoshis),pax->ready!=0,pax->validated!=0,pax->approved!=0); - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) - LogPrintf("pax.%s marked.%d %.8f -> %.8f\n",ASSETCHAINS_SYMBOL,pax->marked,dstr(pax->komodoshis),dstr(pax->fiatoshis)); - if ( opcode == 'I' ) - { - sum += pax->fiatoshis; - if ( sum > available ) - break; - } - txNew->vout.resize(numvouts+1); - txNew->vout[numvouts].nValue = (opcode == 'I') ? pax->fiatoshis : pax->komodoshis; - txNew->vout[numvouts].scriptPubKey.resize(25); - script = (uint8_t *)&txNew->vout[numvouts].scriptPubKey[0]; - *script++ = 0x76; - *script++ = 0xa9; - *script++ = 20; - memcpy(script,pax->rmd160,20), script += 20; - *script++ = 0x88; - *script++ = 0xac; - if ( tokomodo == 0 ) - { - for (i=0; i<32; i++) - data[len++] = ((uint8_t *)&pax->txid)[i]; - data[len++] = pax->vout & 0xff; - data[len++] = (pax->vout >> 8) & 0xff; - PENDING_KOMODO_TX += pax->fiatoshis; - } - else - { - len += komodo_rwapproval(1,&data[len],pax); - PENDING_KOMODO_TX += pax->komodoshis; - LogPrintf(" len.%d vout.%u DEPOSIT %.8f <- pax.%s pending ht %d %d %.8f | ",len,pax->vout,(double)txNew->vout[numvouts].nValue/COIN,symbol,pax->height,pax->otherheight,dstr(PENDING_KOMODO_TX)); - } - if ( numvouts++ >= 64 || sum > COIN ) - break; - } - if ( numvouts > 1 ) - { - if ( tokomodo != 0 ) - strcpy(symbol,(char *)"KMD"); - for (i=0; symbol[i]!=0; i++) - data[len++] = symbol[i]; - data[len++] = 0; - for (i=0; ivout.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); - for (i=0; i<8; i++) - LogPrintf("%02x",opret[i]); - LogPrintf(" <- opret, MINER deposits.%d (%s) vouts.%d %.8f opretlen.%d\n",tokomodo,ASSETCHAINS_SYMBOL,numvouts,dstr(PENDING_KOMODO_TX),opretlen); - return(1); - } - return(0); -} +#include "komodo_notary.h" const char *banned_txids[] = { @@ -657,58 +50,71 @@ const char *banned_txids[] = //"ce567928b5490a17244167af161b1d8dd6ff753fef222fe6855d95b2278a35b3", // missed }; -int32_t komodo_checkvout(int32_t vout,int32_t k,int32_t indallvouts) +/**** + * @brief Check if the n of the vout matches one that is banned + * @param vout the "n" of the vout + * @param k the index in the array of banned txids + * @param indallvouts the index at which all "n"s are banned + * @returns true if vout is banned + */ +bool komodo_checkvout(int32_t vout,int32_t k,int32_t indallvouts) { - if ( k < indallvouts ) - return(vout == 1); - else if ( k == indallvouts || k == indallvouts+1 ) - return(1); - else return(vout == 0); + if ( k < indallvouts ) // most banned txids are vout 1 + return vout == 1; + else if ( k == indallvouts || k == indallvouts+1 ) // all vouts are banned for the last 2 txids + return true; + return vout == 0; // unsure when this might get executed - JMJ } +/**** + * @brief retrieve list of banned txids + * @param[out] indallvoutsp lowest index where all txid "n"s are banned, not just vout 1 + * @param[out] array of txids + * @param[in] max the max size of the array + * @returns the number of txids placed into the array + */ int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max) { - int32_t i; if ( sizeof(banned_txids)/sizeof(*banned_txids) > max ) { - LogPrintf("komodo_bannedset: buffer too small %ld vs %d\n",sizeof(banned_txids)/sizeof(*banned_txids),max); + LogPrintf("komodo_bannedset: buffer too small %d vs %d\n",(int32_t)(sizeof(banned_txids)/sizeof(*banned_txids)),max); StartShutdown(); } + int32_t i; for (i=0; i 1 && block.vtx[txn_count-1].vout.size() > 0 && block.vtx[txn_count-1].vout[0].nValue == 5000 ) + if ( i == 0 && txn_count > 1 && block.vtx[txn_count-1].vout.size() > 0 + && block.vtx[txn_count-1].vout[0].nValue == 5000 ) { - /* - if ( block.vtx[txn_count-1].vin.size() == 1 && GetTransaction(block.vtx[txn_count-1].vin[0].prevout.hash,tx,hash,false) && block.vtx[0].vout[0].scriptPubKey == tx.vout[block.vtx[txn_count-1].vin[0].prevout.n].scriptPubKey ) - notmatched = 1; - */ - if ( block.vtx[txn_count-1].vin.size() == 1 ) { uint256 hashNotaryProofVin = block.vtx[txn_count-1].vin[0].prevout.hash; + CTransaction tx; + uint256 hash; int fNotaryProofVinTxFound = GetTransaction(hashNotaryProofVin,tx,hash,false); if (!fNotaryProofVinTxFound) { // try to search in the same block @@ -717,23 +123,24 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim fNotaryProofVinTxFound = 1; tx = txInThisBlock; hash = block.GetHash(); - // LogPrintf("Found \"same block\" issue in: %s\n",hash.ToString()); break; } } } - if ( fNotaryProofVinTxFound && block.vtx[0].vout[0].scriptPubKey == tx.vout[block.vtx[txn_count-1].vin[0].prevout.n].scriptPubKey ) - { - notmatched = 1; - } + if ( fNotaryProofVinTxFound + && block.vtx[0].vout[0].scriptPubKey == tx.vout[block.vtx[txn_count-1].vin[0].prevout.n].scriptPubKey ) + { + notmatched = 1; + } } } - n = block.vtx[i].vin.size(); - for (j=0; j= indallvouts) ) + if ( block.vtx[i].vin[j].prevout.hash == array[k] + && komodo_checkvout(block.vtx[i].vin[j].prevout.n,k,indallvouts) ) { LogPrintf("banned tx.%d being used at ht.%d txi.%d vini.%d\n",k,height,i,j); return(-1); @@ -743,16 +150,16 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim } } // we don't want these checks in VRSC, leave it at the Sapling upgrade - if ( ASSETCHAINS_SYMBOL[0] == 0 || + if ( chainName.isKMD() || ((ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD) && height > 1) || NetworkUpgradeActive(height, Params().GetConsensus(), Consensus::UPGRADE_SAPLING) ) { - n = block.vtx[0].vout.size(); + int32_t n = block.vtx[0].vout.size(); int64_t val,prevtotal = 0; int32_t strangeout=0,overflow = 0; - total = 0; - for (i=1; i= MAX_MONEY ) { overflow = 1; @@ -768,7 +175,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim } prevtotal = total; } - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) { if ( overflow != 0 || total > COIN/10 ) { @@ -794,18 +201,14 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim } else if ( height > 814000 ) { - script = (uint8_t *)&block.vtx[0].vout[0].scriptPubKey[0]; - //int32_t notary = komodo_electednotary(&num,script+1,height,0); - //if ( (-1 * (komodo_electednotary(&num,script+1,height,0) >= 0) * (height > 1000000)) < 0 ) - // LogPrintf( ">>>>>>> FAILED BLOCK.%d notary.%d insync.%d\n",height,notary,KOMODO_INSYNC); - //else - // LogPrintf( "<<<<<<< VALID BLOCK.%d notary.%d insync.%d\n",height,notary,KOMODO_INSYNC); + uint8_t *script = (uint8_t *)&block.vtx[0].vout[0].scriptPubKey[0]; + int32_t num; return(-1 * (komodo_electednotary(&num,script+1,height,0) >= 0) * (height > 1000000)); } } else { - checktoshis = 0; + int64_t checktoshis = 0; if ( (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD) && height > 1 ) { if ( (checktoshis= komodo_checkcommission((CBlock *)&block,height)) < 0 ) @@ -824,7 +227,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim { LogPrintf("checkdeposit: ht.%d checktoshis %.8f overflow.%d total %.8f strangeout.%d\n",height,dstr(checktoshis),overflow,dstr(total),strangeout); if ( strangeout != 0 ) - LogPrintf(">>>>>>>>>>>>> %s DUST ht.%d strangeout.%d notmatched.%d <<<<<<<<<\n",ASSETCHAINS_SYMBOL,height,strangeout,notmatched); + LogPrintf(">>>>>>>>>>>>> %s DUST ht.%d strangeout.%d notmatched.%d <<<<<<<<<\n",chainName.symbol().c_str(),height,strangeout,notmatched); return(-1); } } @@ -832,389 +235,62 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim return(0); } -const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen,uint256 txid,uint16_t vout,char *source) +void komodo_stateind_set(struct komodo_state *sp,uint32_t *inds,int32_t n,uint8_t *filedata,long datalen,char *symbol,char *dest) { - uint8_t rmd160[20],rmd160s[64*20],addrtype,shortflag,pubkey33[33]; int32_t didstats,i,j,n,kvheight,len,tokomodo,kmdheight,otherheights[64],kmdheights[64]; int8_t baseids[64]; char base[4],coinaddr[64],destaddr[64]; uint256 txids[64]; uint16_t vouts[64]; uint64_t convtoshis,seed; int64_t fee,fiatoshis,komodoshis,checktoshis,values[64],srcvalues[64]; struct pax_transaction *pax,*pax2; struct komodo_state *basesp; double diff; - const char *typestr = "unknown"; - if ( ASSETCHAINS_SYMBOL[0] != 0 && komodo_baseid(ASSETCHAINS_SYMBOL) < 0 && opretbuf[0] != 'K' ) - { - //LogPrintf("komodo_opreturn skip %s\n",ASSETCHAINS_SYMBOL); - return("assetchain"); - } - memset(baseids,0xff,sizeof(baseids)); - memset(values,0,sizeof(values)); - memset(srcvalues,0,sizeof(srcvalues)); - memset(rmd160s,0,sizeof(rmd160s)); - memset(kmdheights,0,sizeof(kmdheights)); - memset(otherheights,0,sizeof(otherheights)); - tokomodo = (komodo_is_issuer() == 0); - if ( opretbuf[0] == 'K' && opretlen != 40 ) - { - komodo_kvupdate(opretbuf,opretlen,value); - return("kv"); - } - else if ( ASSETCHAINS_SYMBOL[0] == 0 && KOMODO_PAX == 0 ) - return("nopax"); - if ( opretbuf[0] == 'D' ) + uint8_t func; long lastK,lastT,lastN,lastV,fpos,lastfpos; int32_t i,count,doissue,iter,numn,numv,numN,numV,numR; uint32_t tmp,prevpos100,offset; + count = numR = numN = numV = numn = numv = 0; + lastK = lastT = lastN = lastV = -1; + for (iter=0; iter<2; iter++) { - tokomodo = 0; - if ( opretlen == 38 ) // any KMD tx + for (lastfpos=fpos=prevpos100=i=0; i 195000 || kmdheight <= height) ) + tmp = inds[i]; + if ( (i % 100) == 0 ) + prevpos100 = tmp; + else { - didstats = 0; - if ( komodo_paxcmp(base,kmdheight,value,checktoshis,kmdheight < 225000 ? seed : 0) == 0 ) + func = (tmp & 0xff); + offset = (tmp >> 8); + fpos = prevpos100 + offset; + if ( lastfpos >= datalen || (filedata[lastfpos] != func && func != 0) ) + LogPrintf(i.%d/n.%d lastfpos.%ld >= datalen.%ld or [%d] != func.%d\n",i,n,lastfpos,datalen,filedata[lastfpos],func); + else if ( iter == 0 ) { - if ( (pax= komodo_paxfind(txid,vout,'D')) == 0 ) - { - if ( (basesp= komodo_stateptrget(base)) != 0 ) - { - basesp->deposited += fiatoshis; - didstats = 1; - if ( 0 && strcmp(base,ASSETCHAINS_SYMBOL) == 0 ) - LogPrintf("########### %p deposited %s += %.8f kmdheight.%d %.8f\n",basesp,base,dstr(fiatoshis),kmdheight,dstr(value)); - } else LogPrintf("cant get stateptr.(%s)\n",base); - komodo_gateway_deposit(coinaddr,value,base,fiatoshis,rmd160,txid,vout,'D',kmdheight,height,(char *)"KMD",0); - } - if ( (pax= komodo_paxfind(txid,vout,'D')) != 0 ) + switch ( func ) { - pax->height = kmdheight; - pax->validated = value; - pax->komodoshis = value; - pax->fiatoshis = fiatoshis; - if ( didstats == 0 && pax->didstats == 0 ) - { - if ( (basesp= komodo_stateptrget(base)) != 0 ) - { - basesp->deposited += fiatoshis; - didstats = 1; - if ( 0 && strcmp(base,ASSETCHAINS_SYMBOL) == 0 ) - LogPrintf("########### %p depositedB %s += %.8f/%.8f kmdheight.%d/%d %.8f/%.8f\n",basesp,base,dstr(fiatoshis),dstr(pax->fiatoshis),kmdheight,pax->height,dstr(value),dstr(pax->komodoshis)); - } - } // - if ( didstats != 0 ) - pax->didstats = 1; - if ( (pax2= komodo_paxfind(txid,vout,'I')) != 0 ) - { - pax2->fiatoshis = pax->fiatoshis; - pax2->komodoshis = pax->komodoshis; - pax->marked = pax2->marked = pax->height; - pax2->height = pax->height = height; - if ( pax2->didstats == 0 ) - { - if ( (basesp= komodo_stateptrget(base)) != 0 ) - { - basesp->issued += pax2->fiatoshis; - pax2->didstats = 1; - if ( 0 && strcmp(base,"USD") == 0 ) - LogPrintf("########### %p issueda %s += %.8f kmdheight.%d %.8f other.%d [%d]\n",basesp,base,dstr(pax2->fiatoshis),pax2->height,dstr(pax2->komodoshis),pax2->otherheight,height); - } - } - } + default: case 'P': case 'U': case 'D': + inds[i] &= 0xffffff00; + break; + case 'K': + lastK = lastfpos; + inds[i] &= 0xffffff00; + break; + case 'T': + lastT = lastfpos; + inds[i] &= 0xffffff00; + break; + case 'N': + lastN = lastfpos; + numN++; + break; + case 'V': + lastV = lastfpos; + numV++; + break; + case 'R': + numR++; + break; } } else { - if ( (pax= komodo_paxfind(txid,vout,'D')) != 0 ) - pax->marked = checktoshis; - if ( kmdheight > 238000 && (kmdheight > 214700 || strcmp(base,ASSETCHAINS_SYMBOL) == 0) ) //seed != 0 && - LogPrintf("pax %s deposit %.8f rejected kmdheight.%d %.8f KMD check %.8f seed.%llu\n",base,dstr(fiatoshis),kmdheight,dstr(value),dstr(checktoshis),(long long)seed); - } - } //else LogPrintf("[%s] %s paxdeposit height.%d vs kmdheight.%d\n",ASSETCHAINS_SYMBOL,base,height,kmdheight); - } //else LogPrintf("unsupported size.%d for opreturn D\n",opretlen); - } - else if ( opretbuf[0] == 'I' ) - { - tokomodo = 0; - if ( strncmp((char *)"KMD",(char *)&opretbuf[opretlen-4],3) != 0 && strncmp(ASSETCHAINS_SYMBOL,(char *)&opretbuf[opretlen-4],3) == 0 ) - { - if ( (n= komodo_issued_opreturn(base,txids,vouts,values,srcvalues,kmdheights,otherheights,baseids,rmd160s,opretbuf,opretlen,0)) > 0 ) - { - for (i=0; itype = opretbuf[0]; - strcpy(pax->source,(char *)&opretbuf[opretlen-4]); - if ( (pax2= komodo_paxfind(txids[i],vouts[i],'D')) != 0 && pax2->fiatoshis != 0 && pax2->komodoshis != 0 ) - { - // realtime path? - pax->fiatoshis = pax2->fiatoshis; - pax->komodoshis = pax2->komodoshis; - pax->marked = pax2->marked = pax2->height; - if ( pax->didstats == 0 ) - { - if ( (basesp= komodo_stateptrget(CURRENCIES[baseids[i]])) != 0 ) - { - basesp->issued += pax->fiatoshis; - pax->didstats = 1; - pax->height = pax2->height; - pax->otherheight = height; - if ( 1 && strcmp(CURRENCIES[baseids[i]],"USD") == 0 ) - LogPrintf("########### %p issuedb %s += %.8f kmdheight.%d %.8f other.%d [%d]\n",basesp,CURRENCIES[baseids[i]],dstr(pax->fiatoshis),pax->height,dstr(pax->komodoshis),pax->otherheight,height); - } - } - } - } - if ( (pax= komodo_paxmark(height,txids[i],vouts[i],'I',height)) != 0 ) - komodo_paxdelete(pax); - if ( (pax= komodo_paxmark(height,txids[i],vouts[i],'D',height)) != 0 ) - komodo_paxdelete(pax); - } - } //else LogPrintf("opreturn none issued?\n"); - } - } - else if ( height < 236000 && opretbuf[0] == 'W' && strncmp(ASSETCHAINS_SYMBOL,(char *)&opretbuf[opretlen-4],3) == 0 )//&& opretlen >= 38 ) - { - if ( komodo_baseid((char *)&opretbuf[opretlen-4]) >= 0 && strcmp(ASSETCHAINS_SYMBOL,(char *)&opretbuf[opretlen-4]) == 0 ) - { - for (i=0; i (%s) len.%d\n",ASSETCHAINS_SYMBOL,base,kmdheight,height,dstr(checktoshis),dstr(komodoshis),dstr(value),komodo_is_issuer(),strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0,(long long)seed,coinaddr,opretlen); - didstats = 0; - //if ( komodo_paxcmp(base,kmdheight,komodoshis,checktoshis,seed) == 0 ) - { - if ( value != 0 && ((pax= komodo_paxfind(txid,vout,'W')) == 0 || pax->didstats == 0) ) - { - if ( (basesp= komodo_stateptrget(base)) != 0 ) - { - basesp->withdrawn += value; - didstats = 1; - if ( 0 && strcmp(base,ASSETCHAINS_SYMBOL) == 0 ) - LogPrintf("########### %p withdrawn %s += %.8f check %.8f\n",basesp,base,dstr(value),dstr(checktoshis)); - } - if ( 0 && strcmp(base,"RUB") == 0 && (pax == 0 || pax->approved == 0) ) - LogPrintf("notarize %s %.8f -> %.8f kmd.%d other.%d\n",ASSETCHAINS_SYMBOL,dstr(value),dstr(komodoshis),kmdheight,height); - } - komodo_gateway_deposit(coinaddr,0,(char *)"KMD",value,rmd160,txid,vout,'W',kmdheight,height,source,0); - if ( (pax= komodo_paxfind(txid,vout,'W')) != 0 ) - { - pax->type = opretbuf[0]; - strcpy(pax->source,base); - strcpy(pax->symbol,"KMD"); - pax->height = kmdheight; - pax->otherheight = height; - pax->komodoshis = komodoshis; - } - } // else LogPrintf("withdraw %s paxcmp ht.%d %d error value %.8f -> %.8f vs %.8f\n",base,kmdheight,height,dstr(value),dstr(komodoshis),dstr(checktoshis)); - // need to allocate pax - } - else if ( height < 236000 && tokomodo != 0 && opretbuf[0] == 'A' && ASSETCHAINS_SYMBOL[0] == 0 ) - { - tokomodo = 1; - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) - { - for (i=0; i 0 ) - { - for (i=0; isymbol); - LogPrintf("override neg1 with (%s)\n",pax->symbol); - } - if ( baseids[i] < 0 ) - continue; - } - didstats = 0; - seed = 0; - checktoshis = komodo_paxprice(&seed,kmdheights[i],CURRENCIES[baseids[i]],(char *)"KMD",(uint64_t)values[i]); - //LogPrintf("PAX_fiatdest ht.%d price %s %.8f -> KMD %.8f vs %.8f\n",kmdheights[i],CURRENCIES[baseids[i]],(double)values[i]/COIN,(double)srcvalues[i]/COIN,(double)checktoshis/COIN); - if ( srcvalues[i] == checktoshis ) - { - if ( (pax= komodo_paxfind(txids[i],vouts[i],'A')) == 0 ) - { - bitcoin_address(coinaddr,60,&rmd160s[i*20],20); - komodo_gateway_deposit(coinaddr,srcvalues[i],CURRENCIES[baseids[i]],values[i],&rmd160s[i*20],txids[i],vouts[i],'A',kmdheights[i],otherheights[i],CURRENCIES[baseids[i]],kmdheights[i]); - if ( (pax= komodo_paxfind(txids[i],vouts[i],'A')) == 0 ) - LogPrintf("unexpected null pax for approve\n"); - else pax->validated = checktoshis; - if ( (pax2= komodo_paxfind(txids[i],vouts[i],'W')) != 0 ) - pax2->approved = kmdheights[i]; - komodo_paxmark(height,txids[i],vouts[i],'W',height); - //komodo_paxmark(height,txids[i],vouts[i],'A',height); - if ( values[i] != 0 && (basesp= komodo_stateptrget(CURRENCIES[baseids[i]])) != 0 ) - { - basesp->approved += values[i]; - didstats = 1; - //LogPrintf("pax.%p ########### %p approved %s += %.8f -> %.8f/%.8f kht.%d %d\n",pax,basesp,CURRENCIES[baseids[i]],dstr(values[i]),dstr(srcvalues[i]),dstr(checktoshis),kmdheights[i],otherheights[i]); - } - //LogPrintf(" i.%d (%s) <- %.8f ADDFLAG APPROVED\n",i,coinaddr,dstr(values[i])); - } - else if ( pax->didstats == 0 && srcvalues[i] != 0 ) - { - if ( (basesp= komodo_stateptrget(CURRENCIES[baseids[i]])) != 0 ) - { - basesp->approved += values[i]; - didstats = 1; - //LogPrintf("pax.%p ########### %p approved %s += %.8f -> %.8f/%.8f kht.%d %d\n",pax,basesp,CURRENCIES[baseids[i]],dstr(values[i]),dstr(srcvalues[i]),dstr(checktoshis),kmdheights[i],otherheights[i]); - } - } //else LogPrintf(" i.%d of n.%d pax.%p baseids[] %d\n",i,n,pax,baseids[i]); - if ( (pax= komodo_paxfind(txids[i],vouts[i],'A')) != 0 ) - { - pax->type = opretbuf[0]; - pax->approved = kmdheights[i]; - pax->validated = checktoshis; - if ( didstats != 0 ) - pax->didstats = 1; - //if ( strcmp(CURRENCIES[baseids[i]],ASSETCHAINS_SYMBOL) == 0 ) - //LogPrintf(" i.%d approved.%d <<<<<<<<<<<<< APPROVED %p\n",i,kmdheights[i],pax); - } - } - } - } //else LogPrintf("n.%d from opreturns\n",n); - //LogPrintf("extra.[%d] after %.8f\n",n,dstr(komodo_paxtotal())); - } - else if ( height < 236000 && opretbuf[0] == 'X' && ASSETCHAINS_SYMBOL[0] == 0 ) - { - tokomodo = 1; - if ( (n= komodo_issued_opreturn(base,txids,vouts,values,srcvalues,kmdheights,otherheights,baseids,rmd160s,opretbuf,opretlen,1)) > 0 ) - { - for (i=0; itype = opretbuf[0]; - if ( height < 121842 ) // fields got switched around due to legacy issues and approves - value = srcvalues[i]; - else value = values[i]; - if ( baseids[i] >= 0 && value != 0 && (basesp= komodo_stateptrget(CURRENCIES[baseids[i]])) != 0 ) - { - basesp->redeemed += value; - pax->didstats = 1; - if ( strcmp(CURRENCIES[baseids[i]],ASSETCHAINS_SYMBOL) == 0 ) - LogPrintf("ht.%d %.8f ########### %p redeemed %s += %.8f %.8f kht.%d ht.%d\n",height,dstr(value),basesp,CURRENCIES[baseids[i]],dstr(value),dstr(srcvalues[i]),kmdheights[i],otherheights[i]); - } - } - if ( (pax= komodo_paxmark(height,txids[i],vouts[i],'W',height)) != 0 ) - komodo_paxdelete(pax); - if ( (pax= komodo_paxmark(height,txids[i],vouts[i],'A',height)) != 0 ) - komodo_paxdelete(pax); - if ( (pax= komodo_paxmark(height,txids[i],vouts[i],'X',height)) != 0 ) - komodo_paxdelete(pax); - } - } //else LogPrintf("komodo_issued_opreturn returned %d\n",n); - } - return(typestr); -} - -int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long *fposp,long datalen,char *symbol,char *dest); - -void komodo_stateind_set(struct komodo_state *sp,uint32_t *inds,int32_t n,uint8_t *filedata,long datalen,char *symbol,char *dest) -{ - uint8_t func; long lastK,lastT,lastN,lastV,fpos,lastfpos; int32_t i,count,doissue,iter,numn,numv,numN,numV,numR; uint32_t tmp,prevpos100,offset; - count = numR = numN = numV = numn = numv = 0; - lastK = lastT = lastN = lastV = -1; - for (iter=0; iter<2; iter++) - { - for (lastfpos=fpos=prevpos100=i=0; i> 8); - fpos = prevpos100 + offset; - if ( lastfpos >= datalen || (filedata[lastfpos] != func && func != 0) ) - LogPrintf("i.%d/n.%d lastfpos.%ld >= datalen.%ld or [%d] != func.%d\n",i,n,lastfpos,datalen,filedata[lastfpos],func); - else if ( iter == 0 ) - { - switch ( func ) - { - default: case 'P': case 'U': case 'D': - inds[i] &= 0xffffff00; - break; - case 'K': - lastK = lastfpos; - inds[i] &= 0xffffff00; - break; - case 'T': - lastT = lastfpos; - inds[i] &= 0xffffff00; - break; - case 'N': - lastN = lastfpos; - numN++; - break; - case 'V': - lastV = lastfpos; - numV++; - break; - case 'R': - numR++; - break; - } - } - else - { - doissue = 0; - if ( func == 'K' ) - { - if ( lastK == lastfpos ) - doissue = 1; - } - else if ( func == 'T' ) + else if ( func == 'T' ) { if ( lastT == lastfpos ) doissue = 1; @@ -1227,15 +303,12 @@ void komodo_stateind_set(struct komodo_state *sp,uint32_t *inds,int32_t n,uint8_ } else if ( func == 'V' ) { - if ( KOMODO_PAX != 0 && numv > numV-1440 ) - doissue = 1; numv++; } else if ( func == 'R' ) doissue = 1; if ( doissue != 0 ) { - //LogPrintf("issue %c total.%d lastfpos.%ld\n",func,count,lastfpos); komodo_parsestatefiledata(sp,filedata,&lastfpos,datalen,symbol,dest); count++; } @@ -1245,15 +318,9 @@ void komodo_stateind_set(struct komodo_state *sp,uint32_t *inds,int32_t n,uint8_ } } LogPrintf("numR.%d numV.%d numN.%d count.%d\n",numR,numV,numN,count); - /*else if ( func == 'K' ) // KMD height: stop after 1st - else if ( func == 'T' ) // KMD height+timestamp: stop after 1st - - else if ( func == 'N' ) // notarization, scan backwards 1440+ blocks; - else if ( func == 'V' ) // price feed: can stop after 1440+ - else if ( func == 'R' ) // opreturn:*/ } -void *OS_loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep) +void *OS_loadfile(const char *fname,uint8_t **bufp,long *lenp,long *allocsizep) { FILE *fp; long filesize,buflen = *allocsizep; @@ -1267,7 +334,7 @@ void *OS_loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep) { fclose(fp); *lenp = 0; - LogPrintf("OS_loadfile null size.(%s)\n",fname); + printf("OS_loadfile null size.(%s)\n",fname); return(0); } if ( filesize > buflen ) @@ -1277,21 +344,21 @@ void *OS_loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep) } rewind(fp); if ( buf == 0 ) - LogPrintf("Null buf ???\n"); + printf("Null buf ???\n"); else { if ( fread(buf,1,(long)filesize,fp) != (unsigned long)filesize ) - LogPrintf("error reading filesize.%ld\n",(long)filesize); + printf("error reading filesize.%ld\n",(long)filesize); buf[filesize] = 0; } fclose(fp); *lenp = filesize; - //LogPrintf("loaded.(%s)\n",buf); - } //else LogPrintf("OS_loadfile couldnt load.(%s)\n",fname); + //printf("loaded.(%s)\n",buf); + } //else printf("OS_loadfile couldnt load.(%s)\n",fname); return(buf); } -uint8_t *OS_fileptr(long *allocsizep,char *fname) +uint8_t *OS_fileptr(long *allocsizep,const char *fname) { long filesize = 0; uint8_t *buf = 0; void *retptr; *allocsizep = 0; @@ -1299,33 +366,49 @@ uint8_t *OS_fileptr(long *allocsizep,char *fname) return((uint8_t *)retptr); } -long komodo_stateind_validate(struct komodo_state *sp,char *indfname,uint8_t *filedata,long datalen,uint32_t *prevpos100p,uint32_t *indcounterp,char *symbol,char *dest) +/** + * @brief Validate the index of the komodostate file + * + * @param[in] sp the komodo_state struct + * @param[in] indfname the index filename + * @param filedata bytes of data + * @param datalen length of filedata + * @param[out] prevpos100p + * @param[out] indcounterp + * @param symbol + * @param dest + * @return -1 on error + */ +long komodo_stateind_validate(struct komodo_state *sp,const std::string& indfname,uint8_t *filedata,long datalen, + uint32_t *prevpos100p,uint32_t *indcounterp,char *symbol,char *dest) { - FILE *fp; long fsize,lastfpos=0,fpos=0; uint8_t *inds,func; int32_t i,n; uint32_t offset,tmp,prevpos100 = 0; *indcounterp = *prevpos100p = 0; - if ( (inds= OS_fileptr(&fsize,indfname)) != 0 ) + long fsize; + uint8_t *inds; + if ( (inds= OS_fileptr(&fsize,indfname.c_str())) != 0 ) { - lastfpos = 0; - LogPrintf("inds.%p validate %s fsize.%ld datalen.%ld n.%ld lastfpos.%ld\n",inds,indfname,fsize,datalen,fsize / sizeof(uint32_t),lastfpos); + long lastfpos = 0; + fprintf(stderr,"inds.%p validate %s fsize.%ld datalen.%ld n.%d lastfpos.%ld\n",inds,indfname.c_str(),fsize,datalen,(int32_t)(fsize / sizeof(uint32_t)),lastfpos); if ( (fsize % sizeof(uint32_t)) == 0 ) { - n = (int32_t)(fsize / sizeof(uint32_t)); - for (i=0; i n-10 ) - LogPrintf("%d: tmp.%08x [%c] prevpos100.%u\n",i,tmp,tmp&0xff,prevpos100); if ( (i % 100) == 0 ) prevpos100 = tmp; else { - func = (tmp & 0xff); - offset = (tmp >> 8); + uint8_t func = (tmp & 0xff); + uint32_t offset = (tmp >> 8); fpos = prevpos100 + offset; if ( lastfpos >= datalen || filedata[lastfpos] != func ) { - LogPrintf("validate.%d error (%u %d) prev100 %u -> fpos.%ld datalen.%ld [%d] (%c) vs (%c) lastfpos.%ld\n",i,offset,func,prevpos100,fpos,datalen,lastfpos < datalen ? filedata[lastfpos] : -1,func,filedata[lastfpos],lastfpos); - return(-1); + printf("validate.%d error (%u %d) prev100 %u -> fpos.%ld datalen.%ld [%d] (%c) vs (%c) lastfpos.%ld\n",i,offset,func,prevpos100,fpos,datalen,lastfpos < datalen ? filedata[lastfpos] : -1,func,filedata[lastfpos],lastfpos); + return -1; } } lastfpos = fpos; @@ -1334,25 +417,24 @@ long komodo_stateind_validate(struct komodo_state *sp,char *indfname,uint8_t *fi *prevpos100p = prevpos100; if ( sp != 0 ) komodo_stateind_set(sp,(uint32_t *)inds,n,filedata,fpos,symbol,dest); - //LogPrintf("free inds.%p %s validated[%d] fpos.%ld datalen.%ld, offset %ld vs fsize.%ld\n",inds,indfname,i,fpos,datalen,i * sizeof(uint32_t),fsize); free(inds); - return(fpos); - } else LogPrintf("wrong filesize %s %ld\n",indfname,fsize); + return fpos; + } + else + printf("wrong filesize %s %ld\n",indfname.c_str(),fsize); } free(inds); - LogPrintf("indvalidate return -1\n"); - return(-1); + fprintf(stderr,"indvalidate return -1\n"); + return -1; } long komodo_indfile_update(FILE *indfp,uint32_t *prevpos100p,long lastfpos,long newfpos,uint8_t func,uint32_t *indcounterp) { - uint32_t tmp; if ( indfp != 0 ) { - tmp = ((uint32_t)(newfpos - *prevpos100p) << 8) | (func & 0xff); + uint32_t tmp = ((uint32_t)(newfpos - *prevpos100p) << 8) | (func & 0xff); if ( ftell(indfp)/sizeof(uint32_t) != *indcounterp ) - LogPrintf("indfp fpos %ld -> ind.%ld vs counter.%u\n",ftell(indfp),ftell(indfp)/sizeof(uint32_t),*indcounterp); - //LogPrintf("ftell.%ld indcounter.%u lastfpos.%ld newfpos.%ld func.%02x\n",ftell(indfp),*indcounterp,lastfpos,newfpos,func); + printf("indfp fpos %ld -> ind.%ld vs counter.%u\n",ftell(indfp),ftell(indfp)/sizeof(uint32_t),*indcounterp); fwrite(&tmp,1,sizeof(tmp),indfp), (*indcounterp)++; if ( (*indcounterp % 100) == 0 ) { @@ -1360,1417 +442,78 @@ long komodo_indfile_update(FILE *indfp,uint32_t *prevpos100p,long lastfpos,long fwrite(prevpos100p,1,sizeof(*prevpos100p),indfp), (*indcounterp)++; } } - return(newfpos); + return newfpos; } -int32_t komodo_faststateinit(struct komodo_state *sp,char *fname,char *symbol,char *dest) +/*** + * @brief read the komodostate file + * @param sp the komodo_state struct + * @param fname the filename + * @param symbol the chain symbol + * @param dest the "parent" chain + * @return true on success + */ +bool komodo_faststateinit(komodo_state *sp,const char *fname,char *symbol,char *dest) { - FILE *indfp; char indfname[1024]; uint8_t *filedata; long validated=-1,datalen,fpos,lastfpos; uint32_t tmp,prevpos100,indcounter,starttime; int32_t func,finished = 0; - starttime = (uint32_t)time(NULL); - safecopy(indfname,fname,sizeof(indfname)-4); - strcat(indfname,".ind"); + uint32_t starttime = (uint32_t)time(NULL); + + uint8_t *filedata = nullptr; + long datalen; if ( (filedata= OS_fileptr(&datalen,fname)) != 0 ) { - if ( 1 )//datalen >= (1LL << 32) || GetArg("-genind",0) != 0 || (validated= komodo_stateind_validate(0,indfname,filedata,datalen,&prevpos100,&indcounter,symbol,dest)) < 0 ) - { - lastfpos = fpos = 0; - indcounter = prevpos100 = 0; - if ( (indfp= fopen(indfname,"wb")) != 0 ) - fwrite(&prevpos100,1,sizeof(prevpos100),indfp), indcounter++; - LogPrintf("processing %s %ldKB, validated.%ld\n",fname,datalen/1024,validated); - while ( (func= komodo_parsestatefiledata(sp,filedata,&fpos,datalen,symbol,dest)) >= 0 ) - { - lastfpos = komodo_indfile_update(indfp,&prevpos100,lastfpos,fpos,func,&indcounter); - } - if ( indfp != 0 ) - { - fclose(indfp); - if ( (fpos= komodo_stateind_validate(0,indfname,filedata,datalen,&prevpos100,&indcounter,symbol,dest)) < 0 ) - LogPrintf("unexpected komodostate.ind validate failure %s datalen.%ld\n",indfname,datalen); - else LogPrintf("%s validated fpos.%ld\n",indfname,fpos); - } - finished = 1; - LogPrintf("took %d seconds to process %s %ldKB\n",(int32_t)(time(NULL)-starttime),fname,datalen/1024); - } - else if ( validated > 0 ) - { - if ( (indfp= fopen(indfname,"rb+")) != 0 ) - { - lastfpos = fpos = validated; - LogPrintf("datalen.%ld validated %ld -> indcounter %u, prevpos100 %u offset.%ld\n",datalen,validated,indcounter,prevpos100,indcounter * sizeof(uint32_t)); - if ( fpos < datalen ) - { - fseek(indfp,indcounter * sizeof(uint32_t),SEEK_SET); - if ( ftell(indfp) == indcounter * sizeof(uint32_t) ) - { - while ( (func= komodo_parsestatefiledata(sp,filedata,&fpos,datalen,symbol,dest)) >= 0 ) - { - lastfpos = komodo_indfile_update(indfp,&prevpos100,lastfpos,fpos,func,&indcounter); - if ( lastfpos != fpos ) - LogPrintf("unexpected lastfpos.%ld != %ld\n",lastfpos,fpos); - } - } - fclose(indfp); - } - if ( komodo_stateind_validate(sp,indfname,filedata,datalen,&prevpos100,&indcounter,symbol,dest) < 0 ) - LogPrintf("unexpected komodostate.ind validate failure %s datalen.%ld\n",indfname,datalen); - else - { - LogPrintf("%s validated updated from validated.%ld to %ld new.[%ld] -> indcounter %u, prevpos100 %u offset.%ld | elapsed %d seconds\n",indfname,validated,fpos,fpos-validated,indcounter,prevpos100,indcounter * sizeof(uint32_t),(int32_t)(time(NULL) - starttime)); - finished = 1; - } - } - } else LogPrintf("komodo_faststateinit unexpected case\n"); - free(filedata); - return(finished == 1); - } - return(-1); -} + long fpos = 0; + long lastfpos = 0; + uint32_t indcounter = 0; + uint32_t prevpos100 = 0; -uint64_t komodo_interestsum(); + std::string indfname(fname); + indfname += ".ind"; + FILE *indfp = fopen(indfname.c_str(), "wb"); + if ( indfp != nullptr ) + fwrite(&prevpos100,1,sizeof(prevpos100),indfp), indcounter++; -void komodo_passport_iteration() -{ - static long lastpos[34]; static char userpass[33][1024]; static uint32_t lasttime,callcounter,lastinterest; - int32_t maxseconds = 10; - FILE *fp; uint8_t *filedata; long fpos,datalen,lastfpos; int32_t baseid,limit,n,ht,isrealtime,expired,refid,blocks,longest; struct komodo_state *sp,*refsp; char *retstr,fname[512],*base,symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; uint32_t buf[3],starttime; uint64_t RTmask = 0; //CBlockIndex *pindex; - expired = 0; - while ( 0 && KOMODO_INITDONE == 0 ) - { - LogPrintf("[%s] PASSPORT iteration waiting for KOMODO_INITDONE\n",ASSETCHAINS_SYMBOL); -#ifdef WIN32 - boost::this_thread::sleep(boost::posix_time::milliseconds(3000)); -#else - sleep(3); -#endif - } - if ( komodo_chainactive_timestamp() > lastinterest ) - { - if ( ASSETCHAINS_SYMBOL[0] == 0 ) - komodo_interestsum(); - //komodo_longestchain(); - lastinterest = komodo_chainactive_timestamp(); - } - refsp = komodo_stateptr(symbol,dest); - if ( ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"KMDCC") == 0 ) - { - refid = 33; - limit = 10000000; - jumblr_iteration(); - } - else - { - limit = 10000000; - refid = komodo_baseid(ASSETCHAINS_SYMBOL)+1; // illegal base -> baseid.-1 -> 0 - if ( refid == 0 ) - { - KOMODO_PASSPORT_INITDONE = 1; - return; - } - } - /*if ( KOMODO_PAX == 0 ) - { - KOMODO_PASSPORT_INITDONE = 1; - return; - }*/ - starttime = (uint32_t)time(NULL); - if ( callcounter++ < 1 ) - limit = 10000; - lasttime = starttime; - for (baseid=32; baseid>=0; baseid--) - { - if ( time(NULL) >= starttime+maxseconds ) - break; - sp = 0; - isrealtime = 0; - base = (char *)CURRENCIES[baseid]; - //LogPrintf("PASSPORT %s baseid+1 %d refid.%d\n",ASSETCHAINS_SYMBOL,baseid+1,refid); - if ( baseid+1 != refid ) // only need to import state from a different coin + fprintf(stderr,"processing %s %ldKB, validated.%d\n",fname,datalen/1024,-1); + int32_t func; + while (!ShutdownRequested() && (func= komodo_parsestatefiledata(sp,filedata,&fpos,datalen,symbol,dest)) >= 0) { - if ( baseid == 32 ) // only care about KMD's state - { - refsp->RTmask &= ~(1LL << baseid); - komodo_statefname(fname,baseid<32?base:(char *)"",(char *)"komodostate"); - komodo_nameset(symbol,dest,base); - sp = komodo_stateptrget(symbol); - n = 0; - if ( lastpos[baseid] == 0 && (filedata= OS_fileptr(&datalen,fname)) != 0 ) - { - fpos = 0; - LogPrintf("%s processing %s %ldKB\n",ASSETCHAINS_SYMBOL,fname,datalen/1024); - while ( komodo_parsestatefiledata(sp,filedata,&fpos,datalen,symbol,dest) >= 0 ) - lastfpos = fpos; - LogPrintf("%s took %d seconds to process %s %ldKB\n",ASSETCHAINS_SYMBOL,(int32_t)(time(NULL)-starttime),fname,datalen/1024); - lastpos[baseid] = lastfpos; - free(filedata), filedata = 0; - datalen = 0; - } - else if ( (fp= fopen(fname,"rb")) != 0 && sp != 0 ) - { - fseek(fp,0,SEEK_END); - //LogPrintf("couldnt OS_fileptr(%s), freading %ldKB\n",fname,ftell(fp)/1024); - if ( ftell(fp) > lastpos[baseid] ) - { - if ( ASSETCHAINS_SYMBOL[0] != 0 ) - LogPrintf("%s passport refid.%d %s fname.(%s) base.%s %ld %ld\n",ASSETCHAINS_SYMBOL,refid,symbol,fname,base,ftell(fp),lastpos[baseid]); - fseek(fp,lastpos[baseid],SEEK_SET); - while ( komodo_parsestatefile(sp,fp,symbol,dest) >= 0 && n < limit ) - { - if ( n == limit-1 ) - { - if ( time(NULL) < starttime+maxseconds ) - n = 0; - else - { - //LogPrintf("expire passport loop %s -> %s at %ld\n",ASSETCHAINS_SYMBOL,base,lastpos[baseid]); - expired++; - } - } - n++; - } - lastpos[baseid] = ftell(fp); - if ( 0 && lastpos[baseid] == 0 && strcmp(symbol,"KMD") == 0 ) - LogPrintf("from.(%s) lastpos[%s] %ld isrt.%d\n",ASSETCHAINS_SYMBOL,CURRENCIES[baseid],lastpos[baseid],komodo_isrealtime(&ht)); - } //else LogPrintf("%s.%ld ",CURRENCIES[baseid],ftell(fp)); - fclose(fp); - } else LogPrintf("load error.(%s) %p\n",fname,sp); - komodo_statefname(fname,baseid<32?base:(char *)"",(char *)"realtime"); - if ( (fp= fopen(fname,"rb")) != 0 ) - { - if ( fread(buf,1,sizeof(buf),fp) == sizeof(buf) ) - { - sp->CURRENT_HEIGHT = buf[0]; - if ( buf[0] != 0 && buf[0] >= buf[1] && buf[2] > time(NULL)-60 ) - { - isrealtime = 1; - RTmask |= (1LL << baseid); - memcpy(refsp->RTbufs[baseid+1],buf,sizeof(refsp->RTbufs[baseid+1])); - } - else if ( KOMODO_PAX != 0 && (time(NULL)-buf[2]) > 60 && ASSETCHAINS_SYMBOL[0] != 0 ) - LogPrintf("[%s]: %s not RT %u %u %d\n",ASSETCHAINS_SYMBOL,base,buf[0],buf[1],(int32_t)(time(NULL)-buf[2])); - } //else LogPrintf("%s size error RT\n",base); - fclose(fp); - } //else LogPrintf("%s open error RT\n",base); - } + lastfpos = komodo_indfile_update(indfp,&prevpos100,lastfpos,fpos,func,&indcounter); } - else + if (ShutdownRequested()) { fclose(indfp); return false; } + if ( indfp != nullptr ) { - refsp->RTmask &= ~(1LL << baseid); - komodo_statefname(fname,baseid<32?base:(char *)"",(char *)"realtime"); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - buf[0] = (uint32_t)chainActive.Tip()->nHeight; - buf[1] = (uint32_t)komodo_longestchain(); - if ( buf[0] != 0 && buf[0] == buf[1] ) - { - buf[2] = (uint32_t)time(NULL); - RTmask |= (1LL << baseid); - memcpy(refsp->RTbufs[baseid+1],buf,sizeof(refsp->RTbufs[baseid+1])); - if ( refid != 0 ) - memcpy(refsp->RTbufs[0],buf,sizeof(refsp->RTbufs[0])); - } - if ( fwrite(buf,1,sizeof(buf),fp) != sizeof(buf) ) - LogPrintf("[%s] %s error writing realtime\n",ASSETCHAINS_SYMBOL,base); - fclose(fp); - } else LogPrintf("%s create error RT\n",base); + fclose(indfp); + if ( (fpos= komodo_stateind_validate(0,indfname,filedata,datalen,&prevpos100,&indcounter,symbol,dest)) < 0 ) + printf("unexpected komodostate.ind validate failure %s datalen.%ld\n",indfname.c_str(),datalen); + else + printf("%s validated fpos.%ld\n",indfname.c_str(),fpos); } - if ( sp != 0 && isrealtime == 0 ) - refsp->RTbufs[0][2] = 0; - } - //komodo_paxtotal(); // calls komodo_isrealtime(), which calls komodo_longestchain() - refsp->RTmask |= RTmask; - if ( expired == 0 && KOMODO_PASSPORT_INITDONE == 0 ) - { - KOMODO_PASSPORT_INITDONE = 1; - LogPrintf("READY for %s RPC calls at %u! done PASSPORT %s refid.%d\n",ASSETCHAINS_SYMBOL,(uint32_t)time(NULL),ASSETCHAINS_SYMBOL,refid); - } -} - -void komodo_PriceCache_shift() -{ - int32_t i; - for (i=KOMODO_LOCALPRICE_CACHESIZE-1; i>0; i--) - memcpy(PriceCache[i],PriceCache[i-1],sizeof(PriceCache[i])); - memcpy(PriceCache[0],Mineropret.data(),Mineropret.size()); -} - -int32_t _komodo_heightpricebits(uint64_t *seedp,uint32_t *heightbits,CBlock *block) -{ - CTransaction tx; int32_t numvouts; std::vector vopret; - tx = block->vtx[0]; - numvouts = (int32_t)tx.vout.size(); - GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret); - if ( vopret.size() >= PRICES_SIZEBIT0 ) - { - if ( seedp != 0 ) - memcpy(seedp,&block->hashMerkleRoot,sizeof(*seedp)); - memcpy(heightbits,vopret.data(),vopret.size()); - return((int32_t)(vopret.size()/sizeof(uint32_t))); + fprintf(stderr,"took %d seconds to process %s %ldKB\n",(int32_t)(time(NULL)-starttime),fname,datalen/1024); + free(filedata); + return true; } - return(-1); + return false; } -// komodo_heightpricebits() extracts the price data in the coinbase for nHeight -int32_t komodo_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeight) -{ - CBlockIndex *pindex; CBlock block; - if ( seedp != 0 ) - *seedp = 0; - if ( (pindex= komodo_chainactive(nHeight)) != 0 ) - { - if ( komodo_blockload(block,pindex) == 0 ) - { - return(_komodo_heightpricebits(seedp,heightbits,&block)); - } - } - LogPrintf("couldnt get pricebits for %d\n",nHeight); - return(-1); -} +//uint64_t komodo_interestsum(); // in wallet/rpcwallet.cpp -/* - komodo_pricenew() is passed in a reference price, the change tolerance and the proposed price. it needs to return a clipped price if it is too big and also set a flag if it is at or above the limit +/*** + * @brief update wallet balance / interest + * @note called only on KMD chain every 10 seconds ( see ThreadUpdateKomodoInternals() ) */ -uint32_t komodo_pricenew(char *maxflagp,uint32_t price,uint32_t refprice,int64_t tolerance) -{ - uint64_t highprice,lowprice; - if ( refprice < 2 ) - return(0); - highprice = ((uint64_t)refprice * (COIN + tolerance)) / COIN; // calc highest acceptable price - lowprice = ((uint64_t)refprice * (COIN - tolerance)) / COIN; // and lowest - if ( highprice == refprice ) - highprice++; - if ( lowprice == refprice ) - lowprice--; - if ( price >= highprice ) - { - //LogPrintf("high %u vs h%llu l%llu tolerance.%llu\n",price,(long long)highprice,(long long)lowprice,(long long)tolerance); - if ( price > highprice ) // return non-zero only if we violate the tolerance - { - *maxflagp = 2; - return(highprice); - } - *maxflagp = 1; - } - else if ( price <= lowprice ) - { - //LogPrintf("low %u vs h%llu l%llu tolerance.%llu\n",price,(long long)highprice,(long long)lowprice,(long long)tolerance); - if ( price < lowprice ) - { - *maxflagp = -2; - return(lowprice); - } - *maxflagp = -1; - } - return(0); -} - -// komodo_pricecmp() returns -1 if any of the prices are beyond the tolerance -int32_t komodo_pricecmp(int32_t nHeight,int32_t n,char *maxflags,uint32_t *pricebitsA,uint32_t *pricebitsB,int64_t tolerance) -{ - int32_t i; uint32_t newprice; - for (i=1; i newprice.%u out of tolerance maxflag.%d\n",nHeight,i,n,pricebitsB[i],pricebitsA[i],newprice,maxflags[i]); - return(-1); - } - } - return(0); -} - -// komodo_priceclamp() clamps any price that is beyond tolerance -int32_t komodo_priceclamp(int32_t n,uint32_t *pricebits,uint32_t *refprices,int64_t tolerance) -{ - int32_t i; uint32_t newprice; char maxflags[KOMODO_MAXPRICES]; - memset(maxflags,0,sizeof(maxflags)); - for (i=1; i %u\n",i,n,refprices[i],pricebits[i],newprice); - pricebits[i] = newprice; - } - } - return(0); -} - -// komodo_mineropret() returns a valid pricedata to add to the coinbase opreturn for nHeight -CScript komodo_mineropret(int32_t nHeight) +void komodo_update_interest() { - CScript opret; char maxflags[KOMODO_MAXPRICES]; uint32_t pricebits[KOMODO_MAXPRICES],prevbits[KOMODO_MAXPRICES]; int32_t maxflag,i,n,numzero=0; - if ( Mineropret.size() >= PRICES_SIZEBIT0 ) + static uint32_t lastinterest; // prevent needless komodo_interestsum calls + if (komodo_chainactive_timestamp() > lastinterest) { - n = (int32_t)(Mineropret.size() / sizeof(uint32_t)); - numzero = 1; - while ( numzero > 0 ) - { - memcpy(pricebits,Mineropret.data(),Mineropret.size()); - for (i=numzero=0; i 0 ) - { - memcpy(pricebits,Mineropret.data(),Mineropret.size()); - memset(maxflags,0,sizeof(maxflags)); - if ( komodo_pricecmp(0,n,maxflags,pricebits,prevbits,PRICES_ERRORRATE) < 0 ) - { - // if the new prices are outside tolerance, update Mineropret with clamped prices - komodo_priceclamp(n,pricebits,prevbits,PRICES_ERRORRATE); - //LogPrintf("update Mineropret to clamped prices\n"); - memcpy(Mineropret.data(),pricebits,Mineropret.size()); - } - } - int32_t i; - for (i=0; i vopret; char maxflags[KOMODO_MAXPRICES]; uint256 bhash; double btcusd,btcgbp,btceur; uint32_t localbits[KOMODO_MAXPRICES],pricebits[KOMODO_MAXPRICES],prevbits[KOMODO_MAXPRICES],newprice; int32_t i,j,prevtime,maxflag,lag,lag2,lag3,n,errflag,iter; uint32_t now; - now = (uint32_t)time(NULL); - if ( ASSETCHAINS_CBOPRET != 0 && nHeight > 0 ) - { - bhash = block->GetHash(); - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() >= PRICES_SIZEBIT0 ) - { - n = (int32_t)(vopret.size() / sizeof(uint32_t)); - memcpy(pricebits,vopret.data(),Mineropret.size()); - memset(maxflags,0,sizeof(maxflags)); - if ( nHeight > 2 ) - { - prevtime = previndex->nTime; - lag = (int32_t)(now - pricebits[0]); - lag2 = (int32_t)(pricebits[0] - prevtime); - lag3 = (int32_t)(block->nTime - pricebits[0]); - if ( lag < -60 ) // avoid data from future - { - LogPrintf("A ht.%d now.%u htstamp.%u %u - pricebits[0] %u -> lags.%d %d %d\n",nHeight,now,prevtime,block->nTime,pricebits[0],lag,lag2,lag3); - return(-1); - } - if ( lag2 < -60 ) //testchain_exemption ) // must be close to last block timestamp - { - LogPrintf("B ht.%d now.%u htstamp.%u %u - pricebits[0] %u -> lags.%d %d %d vs %d cmp.%d\n",nHeight,now,prevtime,block->nTime,pricebits[0],lag,lag2,lag3,ASSETCHAINS_BLOCKTIME,lag2<-ASSETCHAINS_BLOCKTIME); - if ( nHeight > testchain_exemption ) - return(-1); - } - if ( lag3 < -60 || lag3 > ASSETCHAINS_BLOCKTIME ) - { - LogPrintf("C ht.%d now.%u htstamp.%u %u - pricebits[0] %u -> lags.%d %d %d\n",nHeight,now,prevtime,block->nTime,pricebits[0],lag,lag2,lag3); - if ( nHeight > testchain_exemption ) - return(-1); - } - btcusd = (double)pricebits[1]/10000; - btcgbp = (double)pricebits[2]/10000; - btceur = (double)pricebits[3]/10000; - LogPrintf("ht.%d: lag.%d %.4f USD, %.4f GBP, %.4f EUR, GBPUSD %.6f, EURUSD %.6f, EURGBP %.6f [%d]\n",nHeight,lag,btcusd,btcgbp,btceur,btcusd/btcgbp,btcusd/btceur,btcgbp/btceur,lag2); - if ( komodo_heightpricebits(0,prevbits,nHeight-1) > 0 ) - { - if ( nHeight < testchain_exemption ) - { - for (i=0; i= PRICES_SIZEBIT0 ) - { - memcpy(localbits,Mineropret.data(),Mineropret.size()); - if ( nHeight < testchain_exemption ) - { - for (i=0; i 0 && localbits[i] < prevbits[i] ) - { - if ( iter == 0 ) - break; - // second iteration checks recent prices to see if within local volatility - for (j=0; j= prevbits[i] ) - { - LogPrintf("i.%d within recent localprices[%d] %u >= %u\n",i,j,PriceCache[j][i],prevbits[i]); - break; - } - if ( j == KOMODO_LOCALPRICE_CACHESIZE ) - { - komodo_queuelocalprice(1,nHeight,block->nTime,bhash,i,prevbits[i]); - break; - } - } - else if ( maxflag < 0 && localbits[i] > prevbits[i] ) - { - if ( iter == 0 ) - break; - for (j=0; jnTime,bhash,i,prevbits[i]); - break; - } - } - } - } - if ( i != n ) - { - if ( iter == 0 ) - { - LogPrintf("force update prices\n"); - komodo_cbopretupdate(1); - memcpy(localbits,Mineropret.data(),Mineropret.size()); - } else return(-1); - } - } - } - } - if ( bhash == ExtremePrice.blockhash ) - { - LogPrintf("approved a previously extreme price based on new data ht.%d vs %u vs %u\n",ExtremePrice.height,ExtremePrice.timestamp,(uint32_t)block->nTime); - memset(&ExtremePrice,0,sizeof(ExtremePrice)); - } - return(0); - } else LogPrintf("wrong size %d vs %d, scriptPubKey size %d [%02x]\n",(int32_t)vopret.size(),(int32_t)Mineropret.size(),(int32_t)scriptPubKey.size(),scriptPubKey[0]); - return(-1); - } - return(0); -} - -char *nonportable_path(char *str) -{ - int32_t i; - for (i=0; str[i]!=0; i++) - if ( str[i] == '/' ) - str[i] = '\\'; - return(str); -} - -char *portable_path(char *str) -{ -#ifdef _WIN32 - return(nonportable_path(str)); -#else -#ifdef __PNACL - /*int32_t i,n; - if ( str[0] == '/' ) - return(str); - else - { - n = (int32_t)strlen(str); - for (i=n; i>0; i--) - str[i] = str[i-1]; - str[0] = '/'; - str[n+1] = 0; - }*/ -#endif - return(str); -#endif -} - -void *loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep) -{ - FILE *fp; - long filesize,buflen = *allocsizep; - uint8_t *buf = *bufp; - *lenp = 0; - if ( (fp= fopen(portable_path(fname),"rb")) != 0 ) - { - fseek(fp,0,SEEK_END); - filesize = ftell(fp); - if ( filesize == 0 ) - { - fclose(fp); - *lenp = 0; - //LogPrintf("loadfile null size.(%s)\n",fname); - return(0); - } - if ( filesize > buflen ) - { - *allocsizep = filesize; - *bufp = buf = (uint8_t *)realloc(buf,(long)*allocsizep+64); - } - rewind(fp); - if ( buf == 0 ) - LogPrintf("Null buf ???\n"); - else - { - if ( fread(buf,1,(long)filesize,fp) != (unsigned long)filesize ) - LogPrintf("error reading filesize.%ld\n",(long)filesize); - buf[filesize] = 0; - } - fclose(fp); - *lenp = filesize; - //LogPrintf("loaded.(%s)\n",buf); - } //else LogPrintf("OS_loadfile couldnt load.(%s)\n",fname); - return(buf); -} - -void *filestr(long *allocsizep,char *_fname) -{ - long filesize = 0; char *fname,*buf = 0; void *retptr; - *allocsizep = 0; - fname = (char *)malloc(strlen(_fname)+1); - strcpy(fname,_fname); - retptr = loadfile(fname,(uint8_t **)&buf,&filesize,allocsizep); - free(fname); - return(retptr); -} - -cJSON *send_curl(char *url,char *fname) -{ - long fsize; char curlstr[1024],*jsonstr; cJSON *json=0; - sprintf(curlstr,"wget -q \"%s\" -O %s",url,fname); - if ( system(curlstr) == 0 ) - { - if ( (jsonstr= (char *)filestr((long *)&fsize,fname)) != 0 ) - { - json = cJSON_Parse(jsonstr); - free(jsonstr); - } - } - return(json); -} - -// get_urljson just returns the JSON returned by the URL using issue_curl - - -/* -const char *Techstocks[] = -{ "AAPL","ADBE","ADSK","AKAM","AMD","AMZN","ATVI","BB","CDW","CRM","CSCO","CYBR","DBX","EA","FB","GDDY","GOOG","GRMN","GSAT","HPQ","IBM","INFY","INTC","INTU","JNPR","MSFT","MSI","MU","MXL","NATI","NCR","NFLX","NTAP","NVDA","ORCL","PANW","PYPL","QCOM","RHT","S","SHOP","SNAP","SPOT","SYMC","SYNA","T","TRIP","TWTR","TXN","VMW","VOD","VRSN","VZ","WDC","XRX","YELP","YNDX","ZEN" -}; -const char *Metals[] = { "XAU", "XAG", "XPT", "XPD", }; - -const char *Markets[] = { "DJIA", "SPX", "NDX", "VIX" }; -*/ - -cJSON *get_urljson(char *url) -{ - char *jsonstr; cJSON *json = 0; - if ( (jsonstr= issue_curl(url)) != 0 ) - { - //LogPrintf("(%s) -> (%s)\n",url,jsonstr); - json = cJSON_Parse(jsonstr); - free(jsonstr); - } - return(json); -} - -int32_t get_stockprices(uint32_t now,uint32_t *prices,std::vector symbols) -{ - char url[32768],*symbol,*timestr; cJSON *json,*obj; int32_t i,n=0,retval=-1; uint32_t uprice,timestamp; - sprintf(url,"https://api.iextrading.com/1.0/tops/last?symbols=%s",GetArg("-ac_stocks","").c_str()); - LogPrintf("url.(%s)\n",url); - if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"iex")) != 0 ) // - { - LogPrintf("stocks.(%s)\n",jprint(json,0)); - if ( (n= cJSON_GetArraySize(json)) > 0 ) - { - retval = n; - for (i=0; i now+60 || timestamp < now-ASSETCHAINS_BLOCKTIME ) - { - LogPrintf("time error.%d (%u vs %u)\n",timestamp-now,timestamp,now); - retval = -1; - }*/ - if ( symbols[i] != symbol ) - { - retval = -1; - LogPrintf("MISMATCH."); - } - LogPrintf("(%s %u) ",symbol,uprice); - } - } - LogPrintf("numstocks.%d\n",n); - } - //https://api.iextrading.com/1.0/tops/last?symbols=AAPL -> [{"symbol":"AAPL","price":198.63,"size":100,"time":1555092606076}] - free_json(json); - } - return(retval); -} - -uint32_t get_dailyfx(uint32_t *prices) -{ - //{"base":"USD","rates":{"BGN":1.74344803,"NZD":1.471652701,"ILS":3.6329113924,"RUB":65.1997682296,"CAD":1.3430201462,"USD":1.0,"PHP":52.8641469068,"CHF":0.9970582992,"AUD":1.4129078267,"JPY":110.6792654662,"TRY":5.6523444464,"HKD":7.8499732573,"MYR":4.0824567659,"HRK":6.6232840078,"CZK":22.9862720628,"IDR":14267.4986628633,"DKK":6.6551078624,"NOK":8.6806917454,"HUF":285.131039401,"GBP":0.7626582278,"MXN":19.4183455161,"THB":31.8702085933,"ISK":122.5708682475,"ZAR":14.7033339276,"BRL":3.9750401141,"SGD":1.3573720806,"PLN":3.8286682118,"INR":69.33187734,"KRW":1139.1602781244,"RON":4.2423783206,"CNY":6.7387234801,"SEK":9.3385630237,"EUR":0.8914244963},"date":"2019-03-28"} - char url[512],*datestr; cJSON *json,*rates; int32_t i; uint32_t datenum=0,price = 0; - sprintf(url,"https://api.openrates.io/latest?base=USD"); - if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"dailyfx")) != 0 ) - { - if ( (rates= jobj(json,(char *)"rates")) != 0 ) - { - for (i=0; i strvec) -{ - int32_t i,errs=0; uint32_t price; char *symbol; - for (i=0; i 333 ) // for debug only! -// ASSETCHAINS_CBOPRET = 7; - size = komodo_cbopretsize(ASSETCHAINS_CBOPRET); - if ( Mineropret.size() < size ) - Mineropret.resize(size); - size = PRICES_SIZEBIT0; - if ( (forceflag != 0 || now > lastbtc+120) && get_btcusd(pricebits) == 0 ) - { - if ( flags == 0 ) - komodo_PriceCache_shift(); - memcpy(PriceCache[0],pricebits,PRICES_SIZEBIT0); - flags |= 1; - } - if ( (ASSETCHAINS_CBOPRET & 2) != 0 ) - { - if ( now > lasttime+3600*5 || forexprices[0] == 0 ) // cant assume timestamp is valid for forex price as it is a daily weekday changing thing anyway. - { - get_dailyfx(forexprices); - if ( flags == 0 ) - komodo_PriceCache_shift(); - flags |= 2; - memcpy(&PriceCache[0][size/sizeof(uint32_t)],forexprices,sizeof(forexprices)); - } - size += (sizeof(Forex)/sizeof(*Forex)) * sizeof(uint32_t); - } - if ( (ASSETCHAINS_CBOPRET & 4) != 0 ) - { - if ( forceflag != 0 || flags != 0 ) - { - get_cryptoprices(pricebuf,Cryptos,(int32_t)(sizeof(Cryptos)/sizeof(*Cryptos)),ASSETCHAINS_PRICES); - if ( flags == 0 ) - komodo_PriceCache_shift(); - memcpy(&PriceCache[0][size/sizeof(uint32_t)],pricebuf,(sizeof(Cryptos)/sizeof(*Cryptos)+ASSETCHAINS_PRICES.size()) * sizeof(uint32_t)); - flags |= 4; // very rarely we can see flags == 6 case - } - size += (sizeof(Cryptos)/sizeof(*Cryptos)+ASSETCHAINS_PRICES.size()) * sizeof(uint32_t); - } - now = (uint32_t)time(NULL); - if ( (ASSETCHAINS_CBOPRET & 8) != 0 ) - { - if ( forceflag != 0 || flags != 0 ) - { - if ( get_stockprices(now,pricebuf,ASSETCHAINS_STOCKS) == ASSETCHAINS_STOCKS.size() ) - { - if ( flags == 0 ) - komodo_PriceCache_shift(); - memcpy(&PriceCache[0][size/sizeof(uint32_t)],pricebuf,ASSETCHAINS_STOCKS.size() * sizeof(uint32_t)); - flags |= 8; // very rarely we can see flags == 10 case - } - } - size += (ASSETCHAINS_STOCKS.size()) * sizeof(uint32_t); - } - if ( flags != 0 ) - { - if ( (flags & 1) != 0 ) - lastbtc = now; - if ( (flags & 2) != 0 ) - lasttime = now; - memcpy(Mineropret.data(),PriceCache[0],size); - if ( ExtremePrice.dir != 0 && ExtremePrice.ind > 0 && ExtremePrice.ind < size/sizeof(uint32_t) && now < ExtremePrice.timestamp+3600 ) - { - LogPrintf("cmp dir.%d PriceCache[0][ExtremePrice.ind] %u >= %u ExtremePrice.pricebits\n",ExtremePrice.dir,PriceCache[0][ExtremePrice.ind],ExtremePrice.pricebits); - if ( (ExtremePrice.dir > 0 && PriceCache[0][ExtremePrice.ind] >= ExtremePrice.pricebits) || (ExtremePrice.dir < 0 && PriceCache[0][ExtremePrice.ind] <= ExtremePrice.pricebits) ) - { - LogPrintf("future price is close enough to allow approving previously rejected block ind.%d %u vs %u\n",ExtremePrice.ind,PriceCache[0][ExtremePrice.ind],ExtremePrice.pricebits); - if ( (pindex= komodo_blockindex(ExtremePrice.blockhash)) != 0 ) - pindex->nStatus &= ~BLOCK_FAILED_MASK; - else LogPrintf("couldnt find block.%s\n",ExtremePrice.blockhash.GetHex().c_str()); - } - } - // high volatility still strands nodes so we need to check new prices to approve a stuck block - // scan list of stuck blocks (one?) and auto reconsiderblock if it changed state - - //int32_t i; for (i=0; i= KOMODO_MAXPRICES ) - return(-1); - mult = komodo_pricemult(ind); - if ( nonzprices != 0 ) - memset(nonzprices,0,sizeof(*nonzprices)*PRICES_DAYWINDOW); - //for (i=0; i= PRICES_DAYWINDOW ) - i = 0; - if ( (price= rawprices[i*rawskip]) == 0 ) - { - LogPrintf("null rawprice.[%d]\n",i); - return(-1); - } - if ( price >= lowprice && price <= highprice ) - { - //LogPrintf("%.1f ",(double)price/10000); - sum += price; - correlation++; - if ( correlation > (PRICES_DAYWINDOW>>1) ) - { - if ( nonzprices == 0 ) - return(refprice * mult); - //LogPrintf("-> %.4f\n",(double)sum*mult/correlation); - //return(sum*mult/correlation); - n = 0; - i = (iter + seed) % PRICES_DAYWINDOW; - for (k=0; k= PRICES_DAYWINDOW ) - i = 0; - if ( n > (PRICES_DAYWINDOW>>1) ) - nonzprices[i] = 0; - else - { - price = rawprices[i*rawskip]; - if ( price < lowprice || price > highprice ) - nonzprices[i] = 0; - else - { - nonzprices[i] = price; - //LogPrintf("(%d %u) ",i,rawprices[i*rawskip]); - n++; - } - } - } - //LogPrintf("ind.%d iter.%d j.%d i.%d n.%d correlation.%d ref %llu -> %llu\n",ind,iter,j,i,n,correlation,(long long)refprice,(long long)sum/correlation); - if ( n != correlation ) - return(-1); - sum = den = n = 0; - for (i=0; i %.8f\n",(long long)firstprice,((double)(sum*mult) / den) / COIN); - return((sum * mult) / den); - } - } - } - if ( correlation > maxcorrelation ) - maxcorrelation = correlation; - } - LogPrintf("ind.%d iter.%d maxcorrelation.%d ref.%llu high.%llu low.%llu\n",ind,iter,maxcorrelation,(long long)refprice,(long long)highprice,(long long)lowprice); - return(0); -} - -int64_t _pairave64(int64_t valA,int64_t valB) -{ - if ( valA != 0 && valB != 0 ) - return((valA + valB) / 2); - else if ( valA != 0 ) return(valA); - else return(valB); -} - -int64_t _pairdiff64(register int64_t valA,register int64_t valB) -{ - if ( valA != 0 && valB != 0 ) - return(valA - valB); - else return(0); -} - -int64_t balanced_ave64(int64_t buf[],int32_t i,int32_t width) -{ - register int32_t nonz,j; register int64_t sum,price; - nonz = 0; - sum = 0; - for (j=-width; j<=width; j++) - { - price = buf[i + j]; - if ( price != 0 ) - { - sum += price; - nonz++; - } - } - if ( nonz != 0 ) - sum /= nonz; - return(sum); -} - -void buf_trioave64(int64_t dest[],int64_t src[],int32_t n) -{ - register int32_t i,j,width = 3; - for (i=0; i<128; i++) - src[i] = 0; - //for (i=n-width-1; i>width; i--) - // dest[i] = balanced_ave(src,i,width); - //for (i=width; i>0; i--) - // dest[i] = balanced_ave(src,i,i); - for (i=1; i price ) // rising prices - sort64(buf,PRICES_DAYWINDOW); - else revsort64(buf,PRICES_DAYWINDOW); - decayprice = buf[0]; - for (i=0; i %.8f\n",halfave 0 && PRICES[0].fp != 0 && createflag != 0 ) - { - fseek(PRICES[0].fp,(2*PRICES_DAYWINDOW+PRICES_SMOOTHWIDTH) * sizeof(uint32_t) * i,SEEK_SET); - fputc(0,PRICES[0].fp); - fflush(PRICES[0].fp); - } - LogPrintf("pricesinit done i.%d num.%d numprices.%d\n",i,num,(int32_t)(komodo_cbopretsize(ASSETCHAINS_CBOPRET)/sizeof(uint32_t))); - if ( i != num || i != komodo_cbopretsize(ASSETCHAINS_CBOPRET)/sizeof(uint32_t) ) - { - LogPrintf("fatal error opening prices files, start shutdown\n"); - StartShutdown(); - } - return(0); -} - -pthread_mutex_t pricemutex; - -// PRICES file layouts -// [0] rawprice32 / timestamp -// [1] correlated -// [2] 24hr ave -// [3] to [7] reserved - -void komodo_pricesupdate(int32_t height,CBlock *pblock) -{ - static int numprices; static uint32_t *ptr32; static int64_t *ptr64,*tmpbuf; - int32_t ind,offset,width; int64_t correlated,smoothed; uint64_t seed,rngval; uint32_t rawprices[KOMODO_MAXPRICES],buf[PRICES_MAXDATAPOINTS*2]; - width = PRICES_DAYWINDOW;//(2*PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH); - if ( numprices == 0 ) - { - pthread_mutex_init(&pricemutex,0); - numprices = (int32_t)(komodo_cbopretsize(ASSETCHAINS_CBOPRET) / sizeof(uint32_t)); - ptr32 = (uint32_t *)calloc(sizeof(uint32_t),numprices * width); - ptr64 = (int64_t *)calloc(sizeof(int64_t),PRICES_DAYWINDOW*PRICES_MAXDATAPOINTS); - tmpbuf = (int64_t *)calloc(sizeof(int64_t),2*PRICES_DAYWINDOW); - LogPrintf("prices update: numprices.%d %p %p\n",numprices,ptr32,ptr64); - } - if ( _komodo_heightpricebits(&seed,rawprices,pblock) == numprices ) - { - //for (ind=0; ind PRICES_DAYWINDOW ) - { - fseek(PRICES[0].fp,(height-width+1) * numprices * sizeof(uint32_t),SEEK_SET); - if ( fread(ptr32,sizeof(uint32_t),width*numprices,PRICES[0].fp) == width*numprices ) - { - rngval = seed; - for (ind=1; ind 0 ) - { - fseek(PRICES[ind].fp,height * sizeof(int64_t) * PRICES_MAXDATAPOINTS,SEEK_SET); - memset(buf,0,sizeof(buf)); - buf[0] = rawprices[ind]; - buf[1] = rawprices[0]; // timestamp - memcpy(&buf[2],&correlated,sizeof(correlated)); - if ( fwrite(buf,1,sizeof(buf),PRICES[ind].fp) != sizeof(buf) ) - LogPrintf("error fwrite buf for ht.%d ind.%d\n",height,ind); - else if ( height > PRICES_DAYWINDOW*2 ) - { - fseek(PRICES[ind].fp,(height-PRICES_DAYWINDOW+1) * PRICES_MAXDATAPOINTS * sizeof(int64_t),SEEK_SET); - if ( fread(ptr64,sizeof(int64_t),PRICES_DAYWINDOW*PRICES_MAXDATAPOINTS,PRICES[ind].fp) == PRICES_DAYWINDOW*PRICES_MAXDATAPOINTS ) - { - if ( (smoothed= komodo_priceave(tmpbuf,&ptr64[(PRICES_DAYWINDOW-1)*PRICES_MAXDATAPOINTS+1],-PRICES_MAXDATAPOINTS)) > 0 ) - { - fseek(PRICES[ind].fp,(height * PRICES_MAXDATAPOINTS + 2) * sizeof(int64_t),SEEK_SET); - if ( fwrite(&smoothed,1,sizeof(smoothed),PRICES[ind].fp) != sizeof(smoothed) ) - LogPrintf("error fwrite smoothed for ht.%d ind.%d\n",height,ind); - else fflush(PRICES[ind].fp); - } else LogPrintf("error price_smoothed ht.%d ind.%d\n",height,ind); - } else LogPrintf("error fread ptr64 for ht.%d ind.%d\n",height,ind); - } - } else LogPrintf("error komodo_pricecorrelated for ht.%d ind.%d\n",height,ind); - } - LogPrintf("height.%d\n",height); - } else LogPrintf("error reading rawprices for ht.%d\n",height); - } else LogPrintf("height.%d <= width.%d\n",height,width); - pthread_mutex_unlock(&pricemutex); - } else LogPrintf("null PRICES[0].fp\n"); - } else LogPrintf("numprices mismatch, height.%d\n",height); -} - -int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks) -{ - FILE *fp; int32_t retval = PRICES_MAXDATAPOINTS; - pthread_mutex_lock(&pricemutex); - if ( ind < KOMODO_MAXPRICES && (fp= PRICES[ind].fp) != 0 ) + static bool first_call = true; + if ( first_call ) { - fseek(fp,height * PRICES_MAXDATAPOINTS * sizeof(int64_t),SEEK_SET); - if ( fread(buf64,sizeof(int64_t),numblocks*PRICES_MAXDATAPOINTS,fp) != numblocks*PRICES_MAXDATAPOINTS ) - retval = -1; + first_call = false; + LogPrintf("READY for %s RPC calls at %u\n", + chainName.ToString().c_str(), (uint32_t)time(NULL)); } - pthread_mutex_unlock(&pricemutex); - return(retval); } diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 00925dc0..e8f49519 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -13,214 +13,49 @@ * * ******************************************************************************/ #pragma once -// paxdeposit equivalent in reverse makes opreturn and KMD does the same in reverse -#include "komodo_defs.h" -#include "komodo_cJSON.h" -#include "komodo_structs.h" // struct pax_transaction +#include -/*#include "secp256k1/include/secp256k1.h" -#include "secp256k1/include/secp256k1_schnorrsig.h" -#include "secp256k1/include/secp256k1_musig.h" - -int32_t dummy_linker_tricker() -{ - secp256k1_context *ctx = 0; std::vector musig64; CPubKey pk; secp256k1_schnorrsig musig; secp256k1_pubkey combined_pk; - if ( secp256k1_schnorrsig_parse((const secp256k1_context *)ctx,&musig,(const uint8_t *)&musig64[0]) > 0 && secp256k1_ec_pubkey_parse(ctx,&combined_pk,pk.begin(),33) > 0 ) - return(1); -}*/ -int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base); - -void pax_keyset(uint8_t *buf,uint256 txid,uint16_t vout,uint8_t type); - -struct pax_transaction *komodo_paxfind(uint256 txid,uint16_t vout,uint8_t type); - -struct pax_transaction *komodo_paxfinds(uint256 txid,uint16_t vout); - -struct pax_transaction *komodo_paxmark(int32_t height,uint256 txid,uint16_t vout,uint8_t type,int32_t mark); - -void komodo_paxdelete(struct pax_transaction *pax); - -void komodo_gateway_deposit(char *coinaddr,uint64_t value,char *symbol,uint64_t fiatoshis,uint8_t *rmd160,uint256 txid,uint16_t vout,uint8_t type,int32_t height,int32_t otherheight,char *source,int32_t approved); // assetchain context - -int32_t komodo_rwapproval(int32_t rwflag,uint8_t *opretbuf,struct pax_transaction *pax); - -int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t *values,int64_t *srcvalues,int32_t *kmdheights,int32_t *otherheights,int8_t *baseids,uint8_t *rmd160s,uint8_t *opretbuf,int32_t opretlen,int32_t iskomodo); - -int32_t komodo_paxcmp(char *symbol,int32_t kmdheight,uint64_t value,uint64_t checkvalue,uint64_t seed); - -uint64_t komodo_paxtotal(); - -static int _paxorder(const void *a,const void *b) -{ -#define pax_a (*(struct pax_transaction **)a) -#define pax_b (*(struct pax_transaction **)b) - uint64_t aval,bval; - aval = pax_a->fiatoshis + pax_a->komodoshis + pax_a->height; - bval = pax_b->fiatoshis + pax_b->komodoshis + pax_b->height; - if ( bval > aval ) - return(-1); - else if ( bval < aval ) - return(1); - return(0); -#undef pax_a -#undef pax_b -} - -int32_t komodo_pending_withdraws(char *opretstr); // todo: enforce deterministic order - -int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t tokomodo); - -int32_t komodo_checkvout(int32_t vout,int32_t k,int32_t indallvouts); +struct komodo_state; +class CBlock; +/**** + * @brief Check if the n of the vout matches one that is banned + * @param vout the "n" of the vout + * @param k the index in the array of banned txids + * @param indallvouts the index at which all "n"s are banned + * @returns true if vout is banned + */ +bool komodo_checkvout(int32_t vout,int32_t k,int32_t indallvouts); + +/**** + * @brief retrieve list of banned txids + * @param[out] indallvoutsp size of array - 2 + * @param[out] array of txids + * @param[in] max the max size of the array + * @returns the number of txids placed into the array + */ int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max); -int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime); // verify above block is valid pax pricing - -const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen,uint256 txid,uint16_t vout,char *source); - -void komodo_stateind_set(struct komodo_state *sp,uint32_t *inds,int32_t n,uint8_t *filedata,long datalen,char *symbol,char *dest); - -void *OS_loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep); - -uint8_t *OS_fileptr(long *allocsizep,char *fname); - -long komodo_stateind_validate(struct komodo_state *sp,char *indfname,uint8_t *filedata,long datalen,uint32_t *prevpos100p,uint32_t *indcounterp,char *symbol,char *dest); - -long komodo_indfile_update(FILE *indfp,uint32_t *prevpos100p,long lastfpos,long newfpos,uint8_t func,uint32_t *indcounterp); - -int32_t komodo_faststateinit(struct komodo_state *sp,char *fname,char *symbol,char *dest); - -void komodo_passport_iteration(); - -extern std::vector Mineropret; // opreturn data set by the data gathering code -#define PRICES_ERRORRATE (COIN / 100) // maximum acceptable change, set at 1% -#define PRICES_SIZEBIT0 (sizeof(uint32_t) * 4) // 4 uint32_t unixtimestamp, BTCUSD, BTCGBP and BTCEUR -#define KOMODO_LOCALPRICE_CACHESIZE 13 -#define KOMODO_MAXPRICES 2048 -#define PRICES_SMOOTHWIDTH 1 - -#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"CBCOINBASE",cmdstr,0,0,0) - -int32_t komodo_cbopretsize(uint64_t flags); - -void komodo_PriceCache_shift(); - -int32_t _komodo_heightpricebits(uint64_t *seedp,uint32_t *heightbits,CBlock *block); - -// komodo_heightpricebits() extracts the price data in the coinbase for nHeight -int32_t komodo_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeight); - -/* - komodo_pricenew() is passed in a reference price, the change tolerance and the proposed price. it needs to return a clipped price if it is too big and also set a flag if it is at or above the limit +/*** + * @brief update wallet balance / interest + * @note called only on KMD chain every 10 seconds ( see ThreadUpdateKomodoInternals() ) */ -uint32_t komodo_pricenew(char *maxflagp,uint32_t price,uint32_t refprice,int64_t tolerance); - -// komodo_pricecmp() returns -1 if any of the prices are beyond the tolerance -int32_t komodo_pricecmp(int32_t nHeight,int32_t n,char *maxflags,uint32_t *pricebitsA,uint32_t *pricebitsB,int64_t tolerance); - -// komodo_priceclamp() clamps any price that is beyond tolerance -int32_t komodo_priceclamp(int32_t n,uint32_t *pricebits,uint32_t *refprices,int64_t tolerance); - -// komodo_mineropret() returns a valid pricedata to add to the coinbase opreturn for nHeight -CScript komodo_mineropret(int32_t nHeight); +void komodo_update_interest(); -/* - komodo_opretvalidate() is the entire price validation! - it prints out some useful info for debugging, like the lag from current time and prev block and the prices encoded in the opreturn. - - The only way komodo_opretvalidate() doesnt return an error is if maxflag is set or it is within tolerance of both the prior block and the local data. The local data validation only happens if it is a recent block and not a block from the past as the local node is only getting the current price data. - +/*** + * @brief verify block is valid pax pricing + * @param height the height of the block + * @param block the block to check + * @returns <0 on error, 0 on success */ -void komodo_queuelocalprice(int32_t dir,int32_t height,uint32_t timestamp,uint256 blockhash,int32_t ind,uint32_t pricebits); - -int32_t komodo_opretvalidate(const CBlock *block,CBlockIndex * const previndex,int32_t nHeight,CScript scriptPubKey); - -char *nonportable_path(char *str); - -char *portable_path(char *str); - -void *loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep); - -void *filestr(long *allocsizep,char *_fname); - -cJSON *send_curl(char *url,char *fname); - -cJSON *get_urljson(char *url); - -int32_t get_stockprices(uint32_t now,uint32_t *prices,std::vector symbols); - -uint32_t get_dailyfx(uint32_t *prices); - -uint32_t get_binanceprice(const char *symbol); - -int32_t get_cryptoprices(uint32_t *prices,const char *list[],int32_t n,std::vector strvec); - -// parse the coindesk specific data. yes, if this changes, it will require an update. However, regardless if the format from the data source changes, then the code that extracts it must be changed. One way to mitigate this is to have a large variety of data sources so that there is only a very remote chance that all of them are not available. Certainly the data gathering needs to be made more robust, but it doesnt really affect the proof of concept for the decentralized trustless oracle. The trustlessness is achieved by having all nodes get the oracle data. - -int32_t get_btcusd(uint32_t pricebits[4]); - -int32_t komodo_cbopretsize(uint64_t flags); - -// komodo_cbopretupdate() obtains the external price data and encodes it into Mineropret, which will then be used by the miner and validation -// save history, use new data to approve past rejection, where is the auto-reconsiderblock? -void komodo_cbopretupdate(int32_t forceflag); - -extern uint256 Queued_reconsiderblock; - -int64_t komodo_pricemult(int32_t ind); - -char *komodo_pricename(char *name,int32_t ind); - -// finds index for its symbol name -int32_t komodo_priceind(const char *symbol); - -// returns price value which is in a 10% interval for more than 50% points for the preceding 24 hours -int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth); - -int64_t _pairave64(int64_t valA,int64_t valB); - -int64_t _pairdiff64(register int64_t valA,register int64_t valB); - -int64_t balanced_ave64(int64_t buf[],int32_t i,int32_t width); - -void buf_trioave64(int64_t dest[],int64_t src[],int32_t n); - -void smooth64(int64_t dest[],int64_t src[],int32_t width,int32_t smoothiters); - -// http://www.holoborodko.com/pavel/numerical-methods/noise-robust-smoothing-filter/ -//const int64_t coeffs[7] = { -2, 0, 18, 32, 18, 0, -2 }; -static int cmp_llu(const void *a, const void*b) -{ - if(*(int64_t *)a < *(int64_t *)b) return -1; - else if(*(int64_t *)a > *(int64_t *)b) return 1; - else if ( (uint64_t)a < (uint64_t)b ) // jl777 prevent nondeterminism - return(-1); - else return(1); -} - -static void sort64(int64_t *l, int32_t llen) -{ - qsort(l,llen,sizeof(uint64_t),cmp_llu); -} - -static int revcmp_llu(const void *a, const void*b) -{ - if(*(int64_t *)a < *(int64_t *)b) return 1; - else if(*(int64_t *)a > *(int64_t *)b) return -1; - else if ( (uint64_t)a < (uint64_t)b ) // jl777 prevent nondeterminism - return(-1); - else return(1); -} - -static void revsort64(int64_t *l, int32_t llen) -{ - qsort(l,llen,sizeof(uint64_t),revcmp_llu); -} - -int64_t komodo_priceave(int64_t *buf,int64_t *correlated,int32_t cskip); - -int32_t komodo_pricesinit(); - -void komodo_pricesupdate(int32_t height,CBlock *pblock); - -int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); +int32_t komodo_check_deposit(int32_t height,const CBlock& block); + +/*** + * @brief read the komodostate file + * @param sp the komodo_state struct + * @param fname the filename + * @param symbol the chain symbol + * @param dest the "parent" chain + * @return true on success + */ +bool komodo_faststateinit(komodo_state *sp,const char *fname,char *symbol,char *dest); diff --git a/src/komodo_globals.cpp b/src/komodo_globals.cpp index 2e5c7f1a..c1764add 100644 --- a/src/komodo_globals.cpp +++ b/src/komodo_globals.cpp @@ -12,175 +12,109 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ - +#include "komodo_defs.h" #include "komodo_globals.h" +#include "komodo_extern_globals.h" +#include "komodo_notary.h" -int32_t komodo_baseid(char *origbase) -{ - int32_t i; char base[64]; - for (i=0; origbase[i]!=0&&i= 0 && baseid < 32 ) - // cur_money = ASSETCHAINS_GENESISTXVAL + ASSETCHAINS_SUPPLY + nHeight * ASSETCHAINS_REWARD[0] / SATOSHIDEN; - //else - { - // figure out max_money by adding up supply to a maximum of 10,000,000 blocks - cur_money = (ASSETCHAINS_SUPPLY+1) * SATOSHIDEN + (ASSETCHAINS_MAGIC & 0xffffff) + ASSETCHAINS_GENESISTXVAL; - if ( ASSETCHAINS_LASTERA == 0 && ASSETCHAINS_REWARD[0] == 0 ) - { - cur_money += (nHeight * 10000);// / SATOSHIDEN; - } - else - { - for ( int j = 0; j <= ASSETCHAINS_LASTERA; j++ ) - { - // if any condition means we have no more rewards, break - if (j != 0 && (nHeight <= ASSETCHAINS_ENDSUBSIDY[j - 1] || (ASSETCHAINS_ENDSUBSIDY[j - 1] == 0 && - (ASSETCHAINS_REWARD[j] == 0 && (j == ASSETCHAINS_LASTERA || ASSETCHAINS_DECAY[j] != SATOSHIDEN))))) - break; - - // add rewards from this era, up to nHeight - int64_t reward = ASSETCHAINS_REWARD[j]; - - //LogPrintf("last.%d reward %llu period %llu\n",(int32_t)ASSETCHAINS_LASTERA,(long long)reward,(long long)ASSETCHAINS_HALVING[j]); - if ( reward > 0 ) - { - uint64_t lastEnd = j == 0 ? 0 : ASSETCHAINS_ENDSUBSIDY[j - 1]; - uint64_t curEnd = ASSETCHAINS_ENDSUBSIDY[j] == 0 ? nHeight : nHeight > ASSETCHAINS_ENDSUBSIDY[j] ? ASSETCHAINS_ENDSUBSIDY[j] : nHeight; - uint64_t period = ASSETCHAINS_HALVING[j]; - if ( period == 0 ) - period = 210000; - uint32_t nSteps = (curEnd - lastEnd) / period; - uint32_t modulo = (curEnd - lastEnd) % period; - uint64_t decay = ASSETCHAINS_DECAY[j]; - - //LogPrintf("period.%llu cur_money %.8f += %.8f * %d\n",(long long)period,(double)cur_money/COIN,(double)reward/COIN,nHeight); - if ( ASSETCHAINS_HALVING[j] == 0 ) - { - // no halving, straight multiply - cur_money += reward * (nHeight - 1); - //LogPrintf("cur_money %.8f\n",(double)cur_money/COIN); - } - // if exactly SATOSHIDEN, linear decay to zero or to next era, same as: - // (next_era_reward + (starting reward - next_era_reward) / 2) * num_blocks - else if ( decay == SATOSHIDEN ) - { - int64_t lowestSubsidy, subsidyDifference, stepDifference, stepTriangle; - int64_t denominator, modulo=1; - int32_t sign = 1; - - if ( j == ASSETCHAINS_LASTERA ) - { - subsidyDifference = reward; - lowestSubsidy = 0; - } - else - { - // Ex: -ac_eras=3 -ac_reward=0,384,24 -ac_end=1440,260640,0 -ac_halving=1,1440,2103840 -ac_decay 100000000,97750000,0 - subsidyDifference = reward - ASSETCHAINS_REWARD[j + 1]; - if (subsidyDifference < 0) - { - sign = -1; - subsidyDifference *= sign; - lowestSubsidy = reward; - } - else - { - lowestSubsidy = ASSETCHAINS_REWARD[j + 1]; - } - } - - // if we have not finished the current era, we need to caluclate a total as if we are at the end, with the current - // subsidy. we will calculate the total of a linear era as follows. Each item represents an area calculation: - // a) the rectangle from 0 to the lowest reward in the era * the number of blocks - // b) the rectangle of the remainder of blocks from the lowest point of the era to the highest point of the era if any remainder - // c) the minor triangle from the start of transition from the lowest point to the start of transition to the highest point - // d) one halving triangle (half area of one full step) - // - // we also need: - // e) number of steps = (n - erastart) / halving interval - // - // the total supply from era start up to height is: - // a + b + c + (d * e) - - // calculate amount in one step's triangular protrusion over minor triangle's hypotenuse - denominator = nSteps * period; - if ( denominator == 0 ) - denominator = 1; - // difference of one step vs. total - stepDifference = (period * subsidyDifference) / denominator; - - // area == coin holding of one step triangle, protruding from minor triangle's hypotenuse - stepTriangle = (period * stepDifference) >> 1; - - // sign is negative if slope is positive (start is less than end) - if (sign < 0) - { - // use steps minus one for our calculations, and add the potentially partial rectangle - // at the end - cur_money += stepTriangle * (nSteps - 1); - cur_money += stepTriangle * (nSteps - 1) * (nSteps - 1); - - // difference times number of steps is height of rectangle above lowest subsidy - cur_money += modulo * stepDifference * nSteps; - } - else - { - // if negative slope, the minor triangle is the full number of steps, as the highest - // level step is full. lowest subsidy is just the lowest so far - lowestSubsidy = reward - (stepDifference * nSteps); - - // add the step triangles, one per step - cur_money += stepTriangle * nSteps; - - // add the minor triangle - cur_money += stepTriangle * nSteps * nSteps; - } - - // add more for the base rectangle if lowest subsidy is not 0 - cur_money += lowestSubsidy * (curEnd - lastEnd); - } - else - { - for ( int k = lastEnd; k < curEnd; k += period ) - { - cur_money += period * reward; - // if zero, we do straight halving - reward = decay ? (reward * decay) / SATOSHIDEN : reward >> 1; - } - cur_money += modulo * reward; - } - } - } - } - } - if ( KOMODO_BIT63SET(cur_money) != 0 ) - return(KOMODO_MAXNVALUE); - if ( ASSETCHAINS_COMMISSION != 0 ) +struct komodo_state KOMODO_STATES[KOMODO_STATES_NUMBER]; // 0 == asset chain, 1 == KMD + +unsigned int WITNESS_CACHE_SIZE = _COINBASE_MATURITY+10; +uint256 KOMODO_EARLYTXID; + +bool KOMODO_LOADINGBLOCKS; // defined in pow.cpp, boolean, 1 if currently loading the block index, 0 if not +bool IS_KOMODO_NOTARY; +bool IS_MODE_EXCHANGEWALLET = false; +bool IS_KOMODO_DEALERNODE; +int32_t KOMODO_MININGTHREADS = -1,STAKED_NOTARY_ID,USE_EXTERNAL_PUBKEY,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_REWIND,STAKED_ERA,KOMODO_CONNECTING = -1,KOMODO_EXTRASATOSHI,ASSETCHAINS_FOUNDERS,ASSETCHAINS_CBMATURITY,KOMODO_NSPV; +int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1; +std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,NOTARY_ADDRESS,ASSETCHAINS_SELFIMPORT,ASSETCHAINS_CCLIB; +uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW; +int8_t ASSETCHAINS_ADAPTIVEPOW; +std::vector vWhiteListAddress; +char NOTARYADDRS[64][64]; +char NOTARY_ADDRESSES[NUM_KMD_SEASONS][64][64]; + +char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],ASSETCHAINS_USERPASS[4096]; +uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_BEAMPORT,ASSETCHAINS_CODAPORT; +uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC,KOMODO_STOPAT,KOMODO_DPOWCONFS = 1,STAKING_MIN_DIFF; +uint32_t ASSETCHAINS_MAGIC = 2387029918; +int64_t ASSETCHAINS_GENESISTXVAL = 5000000000; + +int64_t MAX_MONEY = 200000000 * 100000000LL; + +// consensus variables for coinbase timelock control and timelock transaction support +// time locks are specified enough to enable their use initially to lock specific coinbase transactions for emission control +// to be verifiable, timelocks require additional data that enables them to be validated and their ownership and +// release time determined from the blockchain. to do this, every time locked output according to this +// spec will use an op_return with CLTV at front and anything after |OP_RETURN|PUSH of rest|OPRETTYPE_TIMELOCK|script| +uint64_t ASSETCHAINS_TIMELOCKGTE = _ASSETCHAINS_TIMELOCKOFF; +uint64_t ASSETCHAINS_TIMEUNLOCKFROM = 0, ASSETCHAINS_TIMEUNLOCKTO = 0; + +uint64_t ASSETCHAINS_LASTERA = 1; +uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_PEGSCCPARAMS[3]; +uint8_t ASSETCHAINS_CCDISABLES[256]; +std::vector ASSETCHAINS_PRICES,ASSETCHAINS_STOCKS; + +uint32_t ASSETCHAINS_NUMALGOS = 1; +uint32_t ASSETCHAINS_EQUIHASH = _ASSETCHAINS_EQUIHASH; + +const char *ASSETCHAINS_ALGORITHMS[] = { "equihash" }; +uint64_t ASSETCHAINS_NONCEMASK[] = { 0xffff }; +uint32_t ASSETCHAINS_NONCESHIFT[] = { 32 }; +uint32_t ASSETCHAINS_HASHESPERROUND[] = { 1 }; +// min diff returned from GetNextWorkRequired needs to be added here for each algo, so they can work with ac_staked. +uint32_t ASSETCHAINS_MINDIFF[] = { 537857807 }; // KOMODO_MINDIFF_NBITS = 0x200f0f0f + +uint32_t ASSETCHAINS_ALGO = _ASSETCHAINS_EQUIHASH; + +int32_t ASSETCHAINS_SAPLING = -1; +int32_t ASSETCHAINS_OVERWINTER = -1; + +uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE; +int32_t ASSETCHAINS_STAKED; +uint64_t ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY = 10,ASSETCHAINS_FOUNDERS_REWARD; + +uint32_t KOMODO_INITDONE; +char KMDUSERPASS[8192+512+1],BTCUSERPASS[8192]; uint16_t KMD_PORT = 7771,BITCOIND_RPCPORT = 7771, DEST_PORT; +uint64_t PENDING_KOMODO_TX; +unsigned int MAX_BLOCK_SIGOPS = 20000; + +bool IS_KOMODO_TESTNODE; +int32_t KOMODO_SNAPSHOT_INTERVAL; +CScript KOMODO_EARLYTXID_SCRIPTPUB; +int32_t ASSETCHAINS_EARLYTXIDCONTRACT; +int32_t ASSETCHAINS_STAKED_SPLIT_PERCENTAGE; + +std::map mapHeightEvalActivate; + + +/** + * @brief Given a currency name, return the index in the KOMODO_STATES array + * + * @param origbase the currency name to look for + * @return 0 for an asset chain, 1 for KMD, or -1 + */ +int32_t komodo_baseid(const char *origbase) +{ + // convert to upper case + std::string base(origbase); + std::transform(base.begin(),base.end(),base.begin(),[](char s){return toupper(s & 0xff);}); + for(size_t i = 0; i < KOMODO_STATES_NUMBER; ++i) { - uint64_t newval = (cur_money + (cur_money/COIN * ASSETCHAINS_COMMISSION)); - if ( KOMODO_BIT63SET(newval) != 0 ) - return(KOMODO_MAXNVALUE); - else if ( newval < cur_money ) // check for underflow - return(KOMODO_MAXNVALUE); - return(newval); + if (KOMODO_STATES[i].symbol == base) + return i; } - //LogPrintf("cur_money %.8f\n",(double)cur_money/COIN); - return(cur_money); -} \ No newline at end of file + return -1; +} + +// todo remove +//#ifndef SATOSHIDEN +//#define SATOSHIDEN ((uint64_t)100000000L) +//#endif diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 5d8cd507..c285121b 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * + * Copyright © 2021 Komodo Core Developers * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -18,128 +18,105 @@ #include "komodo_hardfork.h" #include "komodo_structs.h" -//void komodo_prefetch(FILE *fp); -uint32_t komodo_heightstamp(int32_t height); -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,uint32_t ktime,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); -void komodo_init(int32_t height); -int32_t komodo_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); -int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp); -char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port); -void komodo_init(int32_t height); -int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); -int32_t komodo_isrealtime(int32_t *kmdheightp); -uint64_t komodo_paxtotal(); -int32_t komodo_longestchain(); -uint64_t komodo_maxallowed(int32_t baseid); -int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max); -int32_t komodo_checkvout(int32_t vout,int32_t k,int32_t indallvouts); - -pthread_mutex_t komodo_mutex; // TODO: change on std::mutex -pthread_mutex_t staked_mutex; - #define KOMODO_ELECTION_GAP 2000 //((ASSETCHAINS_SYMBOL[0] == 0) ? 2000 : 100) #define KOMODO_ASSETCHAIN_MAXLEN 65 -struct pax_transaction *PAX; -int32_t NUM_PRICES; uint32_t *PVALS; -struct knotaries_entry *Pubkeys; - -struct komodo_state KOMODO_STATES[34]; -const uint32_t nStakedDecemberHardforkTimestamp = 1576840000; //December 2019 hardfork 12/20/2019 @ 11:06am (UTC) -const int32_t nDecemberHardforkHeight = 1670000; //December 2019 hardfork - -const uint32_t nS4Timestamp = 1592146800; //dPoW Season 4 2020 hardfork Sunday, June 14th, 2020 03:00:00 PM UTC -const int32_t nS4HardforkHeight = 1922000; //dPoW Season 4 2020 hardfork Sunday, June 14th, 2020 - -const uint32_t nS5Timestamp = 1623682800; //dPoW Season 5 Monday, June 14th, 2021 (03:00:00 PM UTC) -const int32_t nS5HardforkHeight = 2437300; //dPoW Season 5 Monday, June 14th, 2021 - -const uint32_t nS6Timestamp = 1656077853; // dPoW Season 6, Fri Jun 24 2022 13:37:33 GMT+0000 -const int32_t nS6HardforkHeight = 2963330; // dPoW Season 6, Fri Jun 24 2022 +extern char CURRENCIES[][8]; + +//extern int COINBASE_MATURITY; +extern unsigned int WITNESS_CACHE_SIZE; + +extern uint256 KOMODO_EARLYTXID; +extern bool IS_KOMODO_NOTARY; + +extern bool IS_MODE_EXCHANGEWALLET; +extern bool IS_KOMODO_DEALERNODE; + +extern int32_t KOMODO_MININGTHREADS; +extern int32_t STAKED_NOTARY_ID; +extern int32_t USE_EXTERNAL_PUBKEY; +extern int32_t KOMODO_PAX; +extern int32_t KOMODO_REWIND; +extern int32_t STAKED_ERA; +extern int32_t KOMODO_CONNECTING; +extern int32_t KOMODO_EXTRASATOSHI; +extern int32_t ASSETCHAINS_FOUNDERS; +extern int32_t KOMODO_NSPV; +extern int32_t KOMODO_INSYNC; +extern int32_t KOMODO_LASTMINED; +extern int32_t prevKOMODO_LASTMINED; +extern int32_t KOMODO_CCACTIVATE; +extern int32_t JUMBLR_PAUSE; +extern std::string NOTARY_PUBKEY; +extern std::string ASSETCHAINS_OVERRIDE_PUBKEY; +extern std::string DONATION_PUBKEY; +extern std::string ASSETCHAINS_SCRIPTPUB; +extern std::string NOTARY_ADDRESS; +extern std::string ASSETCHAINS_SELFIMPORT; +extern std::string ASSETCHAINS_CCLIB; +extern uint8_t NOTARY_PUBKEY33[33]; +extern uint8_t ASSETCHAINS_OVERRIDE_PUBKEY33[33]; +extern uint8_t ASSETCHAINS_OVERRIDE_PUBKEYHASH[20]; +extern uint8_t ASSETCHAINS_PUBLIC; +extern uint8_t ASSETCHAINS_PRIVATE; +extern uint8_t ASSETCHAINS_TXPOW; +extern int8_t ASSETCHAINS_ADAPTIVEPOW; +extern char ASSETCHAINS_USERPASS[4096]; +extern uint16_t ASSETCHAINS_P2PPORT; +extern uint16_t ASSETCHAINS_RPCPORT; +extern uint16_t ASSETCHAINS_BEAMPORT; +extern uint16_t ASSETCHAINS_CODAPORT; +extern uint32_t ASSETCHAIN_INIT; +extern uint32_t ASSETCHAINS_MAGIC; +extern uint64_t ASSETCHAINS_CBOPRET; +extern uint64_t ASSETCHAINS_LASTERA; +extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1]; +extern uint64_t ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS+1]; +extern uint8_t ASSETCHAINS_CCDISABLES[256]; +extern std::vector ASSETCHAINS_PRICES; +extern std::vector ASSETCHAINS_STOCKS; + +extern uint32_t ASSETCHAINS_EQUIHASH; +extern uint32_t ASSETCHAINS_ALGO; +extern int32_t ASSETCHAINS_SAPLING; +extern int32_t ASSETCHAINS_OVERWINTER; +extern int32_t ASSETCHAINS_STAKED; +extern uint64_t ASSETCHAINS_COMMISSION; +extern uint64_t ASSETCHAINS_SUPPLY; +extern uint64_t ASSETCHAINS_FOUNDERS_REWARD; +extern uint32_t KOMODO_INITDONE; +extern char KMDUSERPASS[8192+512+1]; +extern char BTCUSERPASS[8192]; +extern uint16_t KMD_PORT; +extern uint16_t BITCOIND_RPCPORT; +extern uint16_t DEST_PORT; + +extern uint32_t ASSETCHAINS_CC; // set by -ac_cc, normally 0/1 +extern uint32_t KOMODO_STOPAT; // set by -stopat, will not add more blocks after specified height +extern uint32_t KOMODO_DPOWCONFS; // set by -dpowconfs, normally 0/1 +extern uint32_t STAKING_MIN_DIFF; // selected entry from ASSETCHAINS_MINDIFF +extern uint32_t ASSETCHAINS_NUMALGOS; // number of supported hash algos +extern uint32_t ASSETCHAINS_MINDIFF[]; // hash algo dependent +extern uint64_t ASSETCHAINS_TIMELOCKGTE; // set by -ac_timelockgte or consensus +extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1]; // can be set by -ac_end, array of heights indexed by era +extern uint64_t ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1]; // can be set by -ac_halving +extern uint64_t ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS+1]; // can be set by -ac_decay +extern uint64_t ASSETCHAINS_PEGSCCPARAMS[3]; // set by -ac_pegsccparams, used in pegs.cpp +extern uint64_t KOMODO_INTERESTSUM; // calculated value, returned in getinfo() RPC call +extern uint64_t KOMODO_WALLETBALANCE; // pwalletmain->GetBalance(), returned in getinfo() RPC call +extern int64_t ASSETCHAINS_GENESISTXVAL; // used in calculating money supply +extern int64_t MAX_MONEY; // consensus related sanity check. Not max supply. +extern std::mutex komodo_mutex; // seems to protect PAX values and Pubkey array +//extern std::vector Mineropret; // previous miner values +extern pthread_mutex_t KOMODO_CC_mutex; // mutex to help with CryptoConditions +extern CScript KOMODO_EARLYTXID_SCRIPTPUB; // used mainly in cc/prices.cpp -#define _COINBASE_MATURITY 100 -int COINBASE_MATURITY = _COINBASE_MATURITY;//100; -unsigned int WITNESS_CACHE_SIZE = _COINBASE_MATURITY+10; -uint256 KOMODO_EARLYTXID; -bool IS_KOMODO_NOTARY; -bool IS_MODE_EXCHANGEWALLET = false; -bool IS_KOMODO_DEALERNODE; -int32_t KOMODO_MININGTHREADS = -1,STAKED_NOTARY_ID,USE_EXTERNAL_PUBKEY,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_REWIND,STAKED_ERA,KOMODO_CONNECTING = -1,KOMODO_EXTRASATOSHI,ASSETCHAINS_FOUNDERS,ASSETCHAINS_CBMATURITY,KOMODO_NSPV; -int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1; -std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,NOTARY_ADDRESS,ASSETCHAINS_SELFIMPORT,ASSETCHAINS_CCLIB; -uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW; -int8_t ASSETCHAINS_ADAPTIVEPOW; -std::vector Mineropret; -std::vector vWhiteListAddress; -char NOTARYADDRS[64][64]; -char NOTARY_ADDRESSES[NUM_KMD_SEASONS][64][64]; - -char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],ASSETCHAINS_USERPASS[4096]; -uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_BEAMPORT,ASSETCHAINS_CODAPORT; -uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC,KOMODO_STOPAT,KOMODO_DPOWCONFS = 1,STAKING_MIN_DIFF; -uint32_t ASSETCHAINS_MAGIC = 2387029918; -int64_t ASSETCHAINS_GENESISTXVAL = 5000000000; +#define KOMODO_ELECTION_GAP 2000 //((ASSETCHAINS_SYMBOL[0] == 0) ? 2000 : 100) +#define KOMODO_ASSETCHAIN_MAXLEN 65 -int64_t MAX_MONEY = 200000000 * 100000000LL; +#define _COINBASE_MATURITY 100 // defauly maturity -// consensus variables for coinbase timelock control and timelock transaction support -// time locks are specified enough to enable their use initially to lock specific coinbase transactions for emission control -// to be verifiable, timelocks require additional data that enables them to be validated and their ownership and -// release time determined from the blockchain. to do this, every time locked output according to this -// spec will use an op_return with CLTV at front and anything after |OP_RETURN|PUSH of rest|OPRETTYPE_TIMELOCK|script| #define _ASSETCHAINS_TIMELOCKOFF 0xffffffffffffffff -uint64_t ASSETCHAINS_TIMELOCKGTE = _ASSETCHAINS_TIMELOCKOFF; -uint64_t ASSETCHAINS_TIMEUNLOCKFROM = 0, ASSETCHAINS_TIMEUNLOCKTO = 0,ASSETCHAINS_CBOPRET=0; - -uint64_t ASSETCHAINS_LASTERA = 1; -uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_PEGSCCPARAMS[3]; -uint8_t ASSETCHAINS_CCDISABLES[256]; -std::vector ASSETCHAINS_PRICES,ASSETCHAINS_STOCKS; #define _ASSETCHAINS_EQUIHASH 0 - -uint32_t ASSETCHAINS_NUMALGOS = 1; -uint32_t ASSETCHAINS_EQUIHASH = _ASSETCHAINS_EQUIHASH; - -const char *ASSETCHAINS_ALGORITHMS[] = { "equihash" }; -uint64_t ASSETCHAINS_NONCEMASK[] = { 0xffff }; -uint32_t ASSETCHAINS_NONCESHIFT[] = { 32 }; -uint32_t ASSETCHAINS_HASHESPERROUND[] = { 1 }; -// min diff returned from GetNextWorkRequired needs to be added here for each algo, so they can work with ac_staked. -uint32_t ASSETCHAINS_MINDIFF[] = { 537857807 }; // KOMODO_MINDIFF_NBITS = 0x200f0f0f - -uint32_t ASSETCHAINS_ALGO = _ASSETCHAINS_EQUIHASH; - -int32_t ASSETCHAINS_SAPLING = -1; -int32_t ASSETCHAINS_OVERWINTER = -1; - -uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE; -int32_t ASSETCHAINS_STAKED; -uint64_t ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY = 10,ASSETCHAINS_FOUNDERS_REWARD; - -uint32_t KOMODO_INITDONE; -char KMDUSERPASS[8192+512+1],BTCUSERPASS[8192]; uint16_t KMD_PORT = 7771,BITCOIND_RPCPORT = 7771, DEST_PORT; -uint64_t PENDING_KOMODO_TX; -extern int32_t KOMODO_LOADINGBLOCKS; // defined in pow.cpp, boolean, 1 if currently loading the block index, 0 if not -unsigned int MAX_BLOCK_SIGOPS = 20000; - -bool IS_KOMODO_TESTNODE; -int32_t KOMODO_SNAPSHOT_INTERVAL; -CScript KOMODO_EARLYTXID_SCRIPTPUB; -int32_t ASSETCHAINS_EARLYTXIDCONTRACT; -int32_t ASSETCHAINS_STAKED_SPLIT_PERCENTAGE; - -std::map mapHeightEvalActivate; - -struct komodo_kv *KOMODO_KV; -pthread_mutex_t KOMODO_KV_mutex,KOMODO_CC_mutex; - -#define MAX_CURRENCIES 32 -char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies - "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", - "KMD" }; - -int32_t komodo_baseid(char *origbase); - -uint64_t komodo_current_supply(uint32_t nHeight); diff --git a/src/komodo_hardfork.cpp b/src/komodo_hardfork.cpp new file mode 100644 index 00000000..eded0a18 --- /dev/null +++ b/src/komodo_hardfork.cpp @@ -0,0 +1,484 @@ +#include "komodo_hardfork.h" + +const uint32_t nStakedDecemberHardforkTimestamp = 1576840000; //December 2019 hardfork 12/20/2019 @ 11:06am (UTC) +const int32_t nDecemberHardforkHeight = 1670000; //December 2019 hardfork + +const uint32_t nS4Timestamp = 1592146800; //dPoW Season 4 2020 hardfork Sunday, June 14th, 2020 03:00:00 PM UTC +const int32_t nS4HardforkHeight = 1922000; //dPoW Season 4 2020 hardfork Sunday, June 14th, 2020 + +const uint32_t nS5Timestamp = 1623682800; //dPoW Season 5 Monday, June 14th, 2021 (03:00:00 PM UTC) +const int32_t nS5HardforkHeight = 2437300; //dPoW Season 5 Monday, June 14th, 2021 + +const uint32_t nS6Timestamp = 1656077853; // dPoW Season 6, Fri Jun 24 2022 13:37:33 GMT+0000 +const int32_t nS6HardforkHeight = 2963330; // dPoW Season 6, Fri Jun 24 2022 + +// Era array of pubkeys. Add extra seasons to bottom as requried, after adding appropriate info above. +const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = +{ + { + { "0_jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, + { "0_jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, + { "0_kolo_testA", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" }, + { "artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, + { "artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, + { "artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, + { "artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, + { "badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, + { "badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, + { "badass_SH", "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" }, + { "crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, // 10 + { "crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, + { "crackers_SH", "02be28310e6312d1dd44651fd96f6a44ccc269a321f907502aae81d246fabdb03e" }, + { "durerus_EU", "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" }, + { "etszombi_AR", "031c79168d15edabf17d9ec99531ea9baa20039d0cdc14d9525863b83341b210e9" }, + { "etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, // 15 + { "etszombi_SH", "025d7a193c0757f7437fad3431f027e7b5ed6c925b77daba52a8755d24bf682dde" }, + { "farl4web_EU", "0300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3f" }, + { "farl4web_SH", "0396bb5ed3c57aa1221d7775ae0ff751e4c7dc9be220d0917fa8bbdf670586c030" }, + { "fullmoon_AR", "0254b1d64840ce9ff6bec9dd10e33beb92af5f7cee628f999cb6bc0fea833347cc" }, + { "fullmoon_NA", "031fb362323b06e165231c887836a8faadb96eda88a79ca434e28b3520b47d235b" }, // 20 + { "fullmoon_SH", "030e12b42ec33a80e12e570b6c8274ce664565b5c3da106859e96a7208b93afd0d" }, + { "grewal_NA", "03adc0834c203d172bce814df7c7a5e13dc603105e6b0adabc942d0421aefd2132" }, + { "grewal_SH", "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" }, + { "indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + { "indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + { "indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, + { "indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + { "jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, + { "jsgalt_NA", "027b3fb6fede798cd17c30dbfb7baf9332b3f8b1c7c513f443070874c410232446" }, + { "karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, // 30 + { "kashifali_EU", "033777c52a0190f261c6f66bd0e2bb299d30f012dcb8bfff384103211edb8bb207" }, + { "kolo_AR", "03016d19344c45341e023b72f9fb6e6152fdcfe105f3b4f50b82a4790ff54e9dc6" }, + { "kolo_SH", "02aa24064500756d9b0959b44d5325f2391d8e95c6127e109184937152c384e185" }, + { "metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + { "movecrypto_AR", "022783d94518e4dc77cbdf1a97915b29f427d7bc15ea867900a76665d3112be6f3" }, + { "movecrypto_EU", "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" }, + { "movecrypto_NA", "02efb12f4d78f44b0542d1c60146738e4d5506d27ec98a469142c5c84b29de0a80" }, + { "movecrypto_SH", "031f9739a3ebd6037a967ce1582cde66e79ea9a0551c54731c59c6b80f635bc859" }, + { "muros_AR", "022d77402fd7179335da39479c829be73428b0ef33fb360a4de6890f37c2aa005e" }, + { "noashh_AR", "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" }, // 40 + { "noashh_EU", "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" }, + { "noashh_NA", "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" }, + { "nxtswe_EU", "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" }, + { "polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, + { "pondsea_AR", "032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735" }, + { "pondsea_EU", "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" }, + { "pondsea_NA", "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" }, + { "pondsea_SH", "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" }, + { "popcornbag_AR", "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, + { "popcornbag_NA", "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, // 50 + { "ptytrader_NA", "0328c61467148b207400b23875234f8a825cce65b9c4c9b664f47410b8b8e3c222" }, + { "ptytrader_SH", "0250c93c492d8d5a6b565b90c22bee07c2d8701d6118c6267e99a4efd3c7748fa4" }, + { "rnr_AR", "029bdb08f931c0e98c2c4ba4ef45c8e33a34168cb2e6bf953cef335c359d77bfcd" }, + { "rnr_EU", "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" }, + { "rnr_NA", "02e17c5f8c3c80f584ed343b8dcfa6d710dfef0889ec1e7728ce45ce559347c58c" }, + { "rnr_SH", "037536fb9bdfed10251f71543fb42679e7c52308bcd12146b2568b9a818d8b8377" }, + { "titomane_AR", "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" }, + { "titomane_EU", "02e41feded94f0cc59f55f82f3c2c005d41da024e9a805b41105207ef89aa4bfbd" }, + { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, + { "vanbreuk_EU", "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" }, // 60 + { "xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, + { "xxspot1_XX", "02ef445a392fcaf3ad4176a5da7f43580e8056594e003eba6559a713711a27f955" }, + { "xxspot2_XX", "03d85b221ea72ebcd25373e7961f4983d12add66a92f899deaf07bab1d8b6f5573" } + }, + { + {"0dev1_jl777", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, + {"0dev2_kolo", "030f34af4b908fb8eb2099accb56b8d157d49f6cfb691baa80fdd34f385efed961" }, + {"0dev3_kolo", "025af9d2b2a05338478159e9ac84543968fd18c45fd9307866b56f33898653b014" }, + {"0dev4_decker", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" }, + {"a-team_SH", "03b59ad322b17cb94080dc8e6dc10a0a865de6d47c16fb5b1a0b5f77f9507f3cce" }, + {"artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, + {"artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, + {"artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, + {"artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, + {"badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, + {"badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, // 10 + {"batman_AR", "033ecb640ec5852f42be24c3bf33ca123fb32ced134bed6aa2ba249cf31b0f2563" }, + {"batman_SH", "02ca5898931181d0b8aafc75ef56fce9c43656c0b6c9f64306e7c8542f6207018c" }, + {"ca333_EU", "03fc87b8c804f12a6bd18efd43b0ba2828e4e38834f6b44c0bfee19f966a12ba99" }, + {"chainmakers_EU", "02f3b08938a7f8d2609d567aebc4989eeded6e2e880c058fdf092c5da82c3bc5ee" }, + {"chainmakers_NA", "0276c6d1c65abc64c8559710b8aff4b9e33787072d3dda4ec9a47b30da0725f57a" }, + {"chainstrike_SH", "0370bcf10575d8fb0291afad7bf3a76929734f888228bc49e35c5c49b336002153" }, + {"cipi_AR", "02c4f89a5b382750836cb787880d30e23502265054e1c327a5bfce67116d757ce8" }, + {"cipi_NA", "02858904a2a1a0b44df4c937b65ee1f5b66186ab87a751858cf270dee1d5031f18" }, + {"crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, + {"crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, // 20 + {"dwy_EU", "0259c646288580221fdf0e92dbeecaee214504fdc8bbdf4a3019d6ec18b7540424" }, + {"emmanux_SH", "033f316114d950497fc1d9348f03770cd420f14f662ab2db6172df44c389a2667a" }, + {"etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, + {"fullmoon_AR", "03380314c4f42fa854df8c471618751879f9e8f0ff5dbabda2bd77d0f96cb35676" }, + {"fullmoon_NA", "030216211d8e2a48bae9e5d7eb3a42ca2b7aae8770979a791f883869aea2fa6eef" }, + {"fullmoon_SH", "03f34282fa57ecc7aba8afaf66c30099b5601e98dcbfd0d8a58c86c20d8b692c64" }, + {"goldenman_EU", "02d6f13a8f745921cdb811e32237bb98950af1a5952be7b3d429abd9152f8e388d" }, + {"indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + {"indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + {"indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, // 30 + {"indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + {"jackson_AR", "038ff7cfe34cb13b524e0941d5cf710beca2ffb7e05ddf15ced7d4f14fbb0a6f69" }, + {"jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, + {"karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, + {"komodoninja_EU", "038e567b99806b200b267b27bbca2abf6a3e8576406df5f872e3b38d30843cd5ba" }, + {"komodoninja_SH", "033178586896915e8456ebf407b1915351a617f46984001790f0cce3d6f3ada5c2" }, + {"komodopioneers_SH", "033ace50aedf8df70035b962a805431363a61cc4e69d99d90726a2d48fb195f68c" }, + {"libscott_SH", "03301a8248d41bc5dc926088a8cf31b65e2daf49eed7eb26af4fb03aae19682b95" }, + {"lukechilds_AR", "031aa66313ee024bbee8c17915cf7d105656d0ace5b4a43a3ab5eae1e14ec02696" }, + {"madmax_AR", "03891555b4a4393d655bf76f0ad0fb74e5159a615b6925907678edc2aac5e06a75" }, // 40 + {"meshbits_AR", "02957fd48ae6cb361b8a28cdb1b8ccf5067ff68eb1f90cba7df5f7934ed8eb4b2c" }, + {"meshbits_SH", "025c6e94877515dfd7b05682b9cc2fe4a49e076efe291e54fcec3add78183c1edb" }, + {"metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, + {"patchkez_SH", "0296270f394140640f8fa15684fc11255371abb6b9f253416ea2734e34607799c4" }, + {"pbca26_NA", "0276aca53a058556c485bbb60bdc54b600efe402a8b97f0341a7c04803ce204cb5" }, + {"peer2cloud_AR", "034e5563cb885999ae1530bd66fab728e580016629e8377579493b386bf6cebb15" }, + {"peer2cloud_SH", "03396ac453b3f23e20f30d4793c5b8ab6ded6993242df4f09fd91eb9a4f8aede84" }, + {"polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, + {"hyper_AR", "020f2f984d522051bd5247b61b080b4374a7ab389d959408313e8062acad3266b4" }, // 50 + {"hyper_EU", "03d00cf9ceace209c59fb013e112a786ad583d7de5ca45b1e0df3b4023bb14bf51" }, + {"hyper_SH", "0383d0b37f59f4ee5e3e98a47e461c861d49d0d90c80e9e16f7e63686a2dc071f3" }, + {"hyper_NA", "03d91c43230336c0d4b769c9c940145a8c53168bf62e34d1bccd7f6cfc7e5592de" }, + {"popcornbag_AR", "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, + {"popcornbag_NA", "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, + {"alien_AR", "0348d9b1fc6acf81290405580f525ee49b4749ed4637b51a28b18caa26543b20f0" }, + {"alien_EU", "020aab8308d4df375a846a9e3b1c7e99597b90497efa021d50bcf1bbba23246527" }, + {"thegaltmines_NA", "031bea28bec98b6380958a493a703ddc3353d7b05eb452109a773eefd15a32e421" }, + {"titomane_AR", "029d19215440d8cb9cc6c6b7a4744ae7fb9fb18d986e371b06aeb34b64845f9325" }, + {"titomane_EU", "0360b4805d885ff596f94312eed3e4e17cb56aa8077c6dd78d905f8de89da9499f" }, // 60 + {"titomane_SH", "03573713c5b20c1e682a2e8c0f8437625b3530f278e705af9b6614de29277a435b" }, + {"webworker01_NA", "03bb7d005e052779b1586f071834c5facbb83470094cff5112f0072b64989f97d7" }, + {"xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, + }, + { + {"madmax_NA", "0237e0d3268cebfa235958808db1efc20cc43b31100813b1f3e15cc5aa647ad2c3" }, // 0 + {"alright_AR", "020566fe2fb3874258b2d3cf1809a5d650e0edc7ba746fa5eec72750c5188c9cc9" }, + {"strob_NA", "0206f7a2e972d9dfef1c424c731503a0a27de1ba7a15a91a362dc7ec0d0fb47685" }, + {"dwy_EU", "021c7cf1f10c4dc39d13451123707ab780a741feedab6ac449766affe37515a29e" }, + {"phm87_SH", "021773a38db1bc3ede7f28142f901a161c7b7737875edbb40082a201c55dcf0add" }, + {"chainmakers_NA", "02285d813c30c0bf7eefdab1ff0a8ad08a07a0d26d8b95b3943ce814ac8e24d885" }, + {"indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + {"blackjok3r_SH", "021eac26dbad256cbb6f74d41b10763183ee07fb609dbd03480dd50634170547cc" }, + {"chainmakers_EU", "03fdf5a3fce8db7dee89724e706059c32e5aa3f233a6b6cc256fea337f05e3dbf7" }, + {"titomane_AR", "023e3aa9834c46971ff3e7cb86a200ec9c8074a9566a3ea85d400d5739662ee989" }, + {"fullmoon_SH", "023b7252968ea8a955cd63b9e57dee45a74f2d7ba23b4e0595572138ad1fb42d21" }, // 10 + {"indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, + {"chmex_EU", "0281304ebbcc39e4f09fda85f4232dd8dacd668e20e5fc11fba6b985186c90086e" }, + {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, + {"ca333_DEV", "02856843af2d9457b5b1c907068bef6077ea0904cc8bd4df1ced013f64bf267958" }, + {"cipi_NA", "02858904a2a1a0b44df4c937b65ee1f5b66186ab87a751858cf270dee1d5031f18" }, + {"pungocloud_SH", "024dfc76fa1f19b892be9d06e985d0c411e60dbbeb36bd100af9892a39555018f6" }, + {"voskcoin_EU", "034190b1c062a04124ad15b0fa56dfdf34aa06c164c7163b6aec0d654e5f118afb" }, + {"decker_DEV", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" }, + {"cryptoeconomy_EU", "0290ab4937e85246e048552df3e9a66cba2c1602db76e03763e16c671e750145d1" }, + {"etszombi_EU", "0293ea48d8841af7a419a24d9da11c34b39127ef041f847651bae6ab14dcd1f6b4" }, // 20 + {"karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, + {"pirate_AR", "03e29c90354815a750db8ea9cb3c1b9550911bb205f83d0355a061ac47c4cf2fde" }, + {"metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + {"zatjum_SH", "02d6b0c89cacd58a0af038139a9a90c9e02cd1e33803a1f15fceabea1f7e9c263a" }, + {"madmax_AR", "03c5941fe49d673c094bc8e9bb1a95766b4670c88be76d576e915daf2c30a454d3" }, + {"lukechilds_NA", "03f1051e62c2d280212481c62fe52aab0a5b23c95de5b8e9ad5f80d8af4277a64b" }, + {"cipi_AR", "02c4f89a5b382750836cb787880d30e23502265054e1c327a5bfce67116d757ce8" }, + {"tonyl_AR", "02cc8bc862f2b65ad4f99d5f68d3011c138bf517acdc8d4261166b0be8f64189e1" }, + {"infotech_DEV", "0345ad4ab5254782479f6322c369cec77a7535d2f2162d103d666917d5e4f30c4c" }, + {"fullmoon_NA", "032c716701fe3a6a3f90a97b9d874a9d6eedb066419209eed7060b0cc6b710c60b" }, // 30 + {"etszombi_AR", "02e55e104aa94f70cde68165d7df3e162d4410c76afd4643b161dea044aa6d06ce" }, + {"node-9_EU", "0372e5b51e86e2392bb15039bac0c8f975b852b45028a5e43b324c294e9f12e411" }, + {"phba2061_EU", "03f6bd15dba7e986f0c976ea19d8a9093cb7c989d499f1708a0386c5c5659e6c4e" }, + {"indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + {"and1-89_EU", "02736cbf8d7b50835afd50a319f162dd4beffe65f2b1dc6b90e64b32c8e7849ddd" }, + {"komodopioneers_SH", "032a238a5747777da7e819cfa3c859f3677a2daf14e4dce50916fc65d00ad9c52a" }, + {"komodopioneers_EU", "036d02425916444fff8cc7203fcbfc155c956dda5ceb647505836bef59885b6866" }, + {"d0ct0r_NA", "0303725d8525b6f969122faf04152653eb4bf34e10de92182263321769c334bf58" }, + {"kolo_DEV", "02849e12199dcc27ba09c3902686d2ad0adcbfcee9d67520e9abbdda045ba83227" }, + {"peer2cloud_AR", "02acc001fe1fe8fd68685ba26c0bc245924cb592e10cec71e9917df98b0e9d7c37" }, // 40 + {"webworker01_SH", "031e50ba6de3c16f99d414bb89866e578d963a54bde7916c810608966fb5700776" }, + {"webworker01_NA", "032735e9cad1bb00eaababfa6d27864fa4c1db0300c85e01e52176be2ca6a243ce" }, + {"pbca26_NA", "03a97606153d52338bcffd1bf19bb69ef8ce5a7cbdc2dbc3ff4f89d91ea6bbb4dc" }, + {"indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + {"pirate_NA", "0255e32d8a56671dee8aa7f717debb00efa7f0086ee802de0692f2d67ee3ee06ee" }, + {"lukechilds_AR", "025c6a73ff6d750b9ddf6755b390948cffdd00f344a639472d398dd5c6b4735d23" }, + {"dragonhound_NA", "0224a9d951d3a06d8e941cc7362b788bb1237bb0d56cc313e797eb027f37c2d375" }, + {"fullmoon_AR", "03da64dd7cd0db4c123c2f79d548a96095a5a103e5b9d956e9832865818ffa7872" }, + {"chainzilla_SH", "0360804b8817fd25ded6e9c0b50e3b0782ac666545b5416644198e18bc3903d9f9" }, + {"titomane_EU", "03772ac0aad6b0e9feec5e591bff5de6775d6132e888633e73d3ba896bdd8e0afb" }, // 50 + {"jeezy_EU", "037f182facbad35684a6e960699f5da4ba89e99f0d0d62a87e8400dd086c8e5dd7" }, + {"titomane_SH", "03850fdddf2413b51790daf51dd30823addb37313c8854b508ea6228205047ef9b" }, + {"alien_AR", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f" }, + {"pirate_EU", "03fff24efd5648870a23badf46e26510e96d9e79ce281b27cfe963993039dd1351" }, + {"thegaltmines_NA", "02db1a16c7043f45d6033ccfbd0a51c2d789b32db428902f98b9e155cf0d7910ed" }, + {"computergenie_NA", "03a78ae070a5e9e935112cf7ea8293f18950f1011694ea0260799e8762c8a6f0a4" }, + {"nutellalicka_SH", "02f7d90d0510c598ce45915e6372a9cd0ba72664cb65ce231f25d526fc3c5479fc" }, + {"chainstrike_SH", "03b806be3bf7a1f2f6290ec5c1ea7d3ea57774dcfcf2129a82b2569e585100e1cb" }, + {"dwy_SH", "036536d2d52d85f630b68b050f29ea1d7f90f3b42c10f8c5cdf3dbe1359af80aff" }, + {"alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd" }, // 60 + {"gt_AR", "0348430538a4944d3162bb4749d8c5ed51299c2434f3ee69c11a1f7815b3f46135" }, + {"patchkez_SH", "03f45e9beb5c4cd46525db8195eb05c1db84ae7ef3603566b3d775770eba3b96ee" }, + {"decker_AR", "03ffdf1a116300a78729608d9930742cd349f11a9d64fcc336b8f18592dd9c91bc" }, // 63 + }, + { + // Season 3.5 + {"madmax_NA", "0237e0d3268cebfa235958808db1efc20cc43b31100813b1f3e15cc5aa647ad2c3" }, // 0 + {"alright_AR", "020566fe2fb3874258b2d3cf1809a5d650e0edc7ba746fa5eec72750c5188c9cc9" }, + {"strob_NA", "0206f7a2e972d9dfef1c424c731503a0a27de1ba7a15a91a362dc7ec0d0fb47685" }, + {"hunter_EU", "0378224b4e9d8a0083ce36f2963ec0a4e231ec06b0c780de108e37f41181a89f6a" }, // FIXME verify this, kolo. Change name if you want + {"phm87_SH", "021773a38db1bc3ede7f28142f901a161c7b7737875edbb40082a201c55dcf0add" }, + {"chainmakers_NA", "02285d813c30c0bf7eefdab1ff0a8ad08a07a0d26d8b95b3943ce814ac8e24d885" }, + {"indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + {"blackjok3r_SH", "021eac26dbad256cbb6f74d41b10763183ee07fb609dbd03480dd50634170547cc" }, + {"chainmakers_EU", "03fdf5a3fce8db7dee89724e706059c32e5aa3f233a6b6cc256fea337f05e3dbf7" }, + {"titomane_AR", "023e3aa9834c46971ff3e7cb86a200ec9c8074a9566a3ea85d400d5739662ee989" }, + {"fullmoon_SH", "023b7252968ea8a955cd63b9e57dee45a74f2d7ba23b4e0595572138ad1fb42d21" }, // 10 + {"indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, + {"chmex_EU", "0281304ebbcc39e4f09fda85f4232dd8dacd668e20e5fc11fba6b985186c90086e" }, + {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, + {"ca333_DEV", "02856843af2d9457b5b1c907068bef6077ea0904cc8bd4df1ced013f64bf267958" }, + {"cipi_NA", "02858904a2a1a0b44df4c937b65ee1f5b66186ab87a751858cf270dee1d5031f18" }, + {"pungocloud_SH", "024dfc76fa1f19b892be9d06e985d0c411e60dbbeb36bd100af9892a39555018f6" }, + {"voskcoin_EU", "034190b1c062a04124ad15b0fa56dfdf34aa06c164c7163b6aec0d654e5f118afb" }, + {"decker_DEV", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" }, + {"cryptoeconomy_EU", "0290ab4937e85246e048552df3e9a66cba2c1602db76e03763e16c671e750145d1" }, + {"etszombi_EU", "0293ea48d8841af7a419a24d9da11c34b39127ef041f847651bae6ab14dcd1f6b4" }, // 20 + {"karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, + {"pirate_AR", "03e29c90354815a750db8ea9cb3c1b9550911bb205f83d0355a061ac47c4cf2fde" }, + {"metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + {"zatjum_SH", "02d6b0c89cacd58a0af038139a9a90c9e02cd1e33803a1f15fceabea1f7e9c263a" }, + {"madmax_AR", "03c5941fe49d673c094bc8e9bb1a95766b4670c88be76d576e915daf2c30a454d3" }, + {"lukechilds_NA", "03f1051e62c2d280212481c62fe52aab0a5b23c95de5b8e9ad5f80d8af4277a64b" }, + {"cipi_AR", "02c4f89a5b382750836cb787880d30e23502265054e1c327a5bfce67116d757ce8" }, + {"tonyl_AR", "02cc8bc862f2b65ad4f99d5f68d3011c138bf517acdc8d4261166b0be8f64189e1" }, + {"infotech_DEV", "0345ad4ab5254782479f6322c369cec77a7535d2f2162d103d666917d5e4f30c4c" }, + {"fullmoon_NA", "032c716701fe3a6a3f90a97b9d874a9d6eedb066419209eed7060b0cc6b710c60b" }, // 30 + {"etszombi_AR", "02e55e104aa94f70cde68165d7df3e162d4410c76afd4643b161dea044aa6d06ce" }, + {"node-9_EU", "0372e5b51e86e2392bb15039bac0c8f975b852b45028a5e43b324c294e9f12e411" }, + {"phba2061_EU", "03f6bd15dba7e986f0c976ea19d8a9093cb7c989d499f1708a0386c5c5659e6c4e" }, + {"indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + {"and1-89_EU", "02736cbf8d7b50835afd50a319f162dd4beffe65f2b1dc6b90e64b32c8e7849ddd" }, + {"komodopioneers_SH", "032a238a5747777da7e819cfa3c859f3677a2daf14e4dce50916fc65d00ad9c52a" }, + {"komodopioneers_EU", "036d02425916444fff8cc7203fcbfc155c956dda5ceb647505836bef59885b6866" }, + {"d0ct0r_NA", "0303725d8525b6f969122faf04152653eb4bf34e10de92182263321769c334bf58" }, + {"kolo_DEV", "02849e12199dcc27ba09c3902686d2ad0adcbfcee9d67520e9abbdda045ba83227" }, + {"peer2cloud_AR", "02acc001fe1fe8fd68685ba26c0bc245924cb592e10cec71e9917df98b0e9d7c37" }, // 40 + {"webworker01_SH", "031e50ba6de3c16f99d414bb89866e578d963a54bde7916c810608966fb5700776" }, + {"webworker01_NA", "032735e9cad1bb00eaababfa6d27864fa4c1db0300c85e01e52176be2ca6a243ce" }, + {"pbca26_NA", "03a97606153d52338bcffd1bf19bb69ef8ce5a7cbdc2dbc3ff4f89d91ea6bbb4dc" }, + {"indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + {"pirate_NA", "0255e32d8a56671dee8aa7f717debb00efa7f0086ee802de0692f2d67ee3ee06ee" }, + {"lukechilds_AR", "025c6a73ff6d750b9ddf6755b390948cffdd00f344a639472d398dd5c6b4735d23" }, + {"dragonhound_NA", "0224a9d951d3a06d8e941cc7362b788bb1237bb0d56cc313e797eb027f37c2d375" }, + {"fullmoon_AR", "03da64dd7cd0db4c123c2f79d548a96095a5a103e5b9d956e9832865818ffa7872" }, + {"chainzilla_SH", "0360804b8817fd25ded6e9c0b50e3b0782ac666545b5416644198e18bc3903d9f9" }, + {"titomane_EU", "03772ac0aad6b0e9feec5e591bff5de6775d6132e888633e73d3ba896bdd8e0afb" }, // 50 + {"jeezy_EU", "037f182facbad35684a6e960699f5da4ba89e99f0d0d62a87e8400dd086c8e5dd7" }, + {"titomane_SH", "03850fdddf2413b51790daf51dd30823addb37313c8854b508ea6228205047ef9b" }, + {"alien_AR", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f" }, + {"pirate_EU", "03fff24efd5648870a23badf46e26510e96d9e79ce281b27cfe963993039dd1351" }, + {"thegaltmines_NA", "02db1a16c7043f45d6033ccfbd0a51c2d789b32db428902f98b9e155cf0d7910ed" }, + {"computergenie_NA", "03a78ae070a5e9e935112cf7ea8293f18950f1011694ea0260799e8762c8a6f0a4" }, + {"nutellalicka_SH", "02f7d90d0510c598ce45915e6372a9cd0ba72664cb65ce231f25d526fc3c5479fc" }, + {"chainstrike_SH", "03b806be3bf7a1f2f6290ec5c1ea7d3ea57774dcfcf2129a82b2569e585100e1cb" }, + {"hunter_SH", "02407db70ad30ce4dfaee8b4ae35fae88390cad2b0ba0373fdd6231967537ccfdf" }, + {"alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd" }, // 60 + {"gt_AR", "0348430538a4944d3162bb4749d8c5ed51299c2434f3ee69c11a1f7815b3f46135" }, + {"patchkez_SH", "03f45e9beb5c4cd46525db8195eb05c1db84ae7ef3603566b3d775770eba3b96ee" }, + {"decker_AR", "03ffdf1a116300a78729608d9930742cd349f11a9d64fcc336b8f18592dd9c91bc" }, // 63 + }, + { + // Season 4 + { "alien_AR", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f" }, + { "alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd" }, + { "strob_NA", "02a1c0bd40b294f06d3e44a52d1b2746c260c475c725e9351f1312e49e01c9a405" }, + { "titomane_SH", "020014ad4eedf6b1aeb0ad3b101a58d0a2fc570719e46530fd98d4e585f63eb4ae" }, + { "fullmoon_AR", "03b251095e747f759505ec745a4bbff9a768b8dce1f65137300b7c21efec01a07a" }, + { "phba2061_EU", "03a9492d2a1601d0d98cfe94d8adf9689d1bb0e600088127a4f6ca937761fb1c66" }, + { "fullmoon_NA", "03931c1d654a99658998ce0ddae108d825943a821d1cddd85e948ac1d483f68fb6" }, + { "fullmoon_SH", "03c2a1ed9ddb7bb8344328946017b9d8d1357b898957dd6aaa8c190ae26740b9ff" }, + { "madmax_AR", "022be5a2829fa0291f9a51ff7aeceef702eef581f2611887c195e29da49092e6de" }, + { "titomane_EU", "0285cf1fdba761daf6f1f611c32d319cd58214972ef822793008b69dde239443dd" }, + { "cipi_NA", "022c6825a24792cc3b010b1531521eba9b5e2662d640ed700fd96167df37e75239" }, + { "indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + { "decker_AR", "03ffdf1a116300a78729608d9930742cd349f11a9d64fcc336b8f18592dd9c91bc" }, + { "indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + { "madmax_NA", "02997b7ab21b86bbea558ae79acc35d62c9cedf441578f78112f986d72e8eece08" }, + { "chainzilla_SH", "02288ba6dc57936b59d60345e397d62f5d7e7d975f34ed5c2f2e23288325661563" }, + { "peer2cloud_AR", "0250e7e43a3535731b051d1bcc7dc88fbb5163c3fe41c5dee72bd973bcc4dca9f2" }, + { "pirate_EU", "0231c0f50a06655c3d2edf8d7e722d290195d49c78d50de7786b9d196e8820c848" }, + { "webworker01_NA", "02dfd5f3cef1142879a7250752feb91ddd722c497fb98c7377c0fcc5ccc201bd55" }, + { "zatjum_SH", "036066fd638b10e555597623e97e032b28b4d1fa5a13c2b0c80c420dbddad236c2" }, + { "titomane_AR", "0268203a4c80047edcd66385c22e764ea5fb8bc42edae389a438156e7dca9a8251" }, + { "chmex_EU", "025b7209ba37df8d9695a23ea706ea2594863ab09055ca6bf485855937f3321d1d" }, + { "indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, + { "patchkez_SH", "02cabd6c5fc0b5476c7a01e9d7b907e9f0a051d7f4f731959955d3f6b18ee9a242" }, + { "metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + { "etszombi_EU", "0341adbf238f33a33cc895633db996c3ad01275313ac6641e046a3db0b27f1c880" }, + { "pirate_NA", "02207f27a13625a0b8caef6a7bb9de613ff16e4a5f232da8d7c235c7c5bad72ffe" }, + { "metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, + { "indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + { "chainmakers_NA", "029415a1609c33dfe4a1016877ba35f9265d25d737649f307048efe96e76512877" }, + { "mihailo_EU", "037f9563f30c609b19fd435a19b8bde7d6db703012ba1aba72e9f42a87366d1941" }, + { "tonyl_AR", "0299684d7291abf90975fa493bf53212cf1456c374aa36f83cc94daece89350ae9" }, + { "alien_NA", "03bea1ac333b95c8669ec091907ea8713cae26f74b9e886e13593400e21c4d30a8" }, + { "pungocloud_SH", "025b97d8c23effaca6fa7efacce20bf54df73081b63004a0fe22f3f98fece5669f" }, + { "node9_EU", "029ffa793b5c3248f8ea3da47fa3cf1810dada5af032ecd0e37bab5b92dd63b34e" }, + { "smdmitry_AR", "022a2a45979a6631a25e4c96469423de720a2f4c849548957c35a35c91041ee7ac" }, + { "nodeone_NA", "03f9dd0484e81174fd50775cb9099691c7d140ff00c0f088847e38dc87da67eb9b" }, + { "gcharang_SH", "02ec4172eab854a0d8cd32bc691c83e93975a3df5a4a453a866736c56e025dc359" }, + { "cipi_EU", "02f2b6defff1c544202f66e47cfd6909c54d67c7c39b9c2a99f137dbaf6d0bd8fa" }, + { "etszombi_AR", "0329944b0ac65b6760787ede042a2fde0be9fca1d80dd756bc0ee0b98d389b7682" }, + { "pbca26_NA", "0387e0fb6f2ca951154c87e16c6cbf93a69862bb165c1a96bcd8722b3af24fe533" }, + { "mylo_SH", "03b58f57822e90fe105e6efb63fd8666033ea503d6cc165b1e479bbd8c2ba033e8" }, + { "swisscertifiers_EU", "03ebcc71b42d88994b8b2134bcde6cb269bd7e71a9dd7616371d9294ec1c1902c5" }, + { "marmarachain_AR", "035bbd81a098172592fe97f50a0ce13cbbf80e55cc7862eccdbd7310fab8a90c4c" }, + { "karasugoi_NA", "0262cf2559703464151153c12e00c4b67a969e39b330301fdcaa6667d7eb02c57d" }, + { "phm87_SH", "021773a38db1bc3ede7f28142f901a161c7b7737875edbb40082a201c55dcf0add" }, + { "oszy_EU", "03d1ffd680491b98a3ec5541715681d1a45293c8efb1722c32392a1d792622596a" }, + { "chmex_AR", "036c856ea778ea105b93c0be187004d4e51161eda32888aa307b8f72d490884005" }, + { "dragonhound_NA", "0227e5cad3731e381df157de189527aac8eb50d82a13ce2bd81153984ebc749515" }, + { "strob_SH", "025ceac4256cef83ca4b110f837a71d70a5a977ecfdf807335e00bc78b560d451a" }, + { "madmax_EU", "02ea0cf4d6d151d0528b07efa79cc7403d77cb9195e2e6c8374f5074b9a787e287" }, + { "dudezmobi_AR", "027ecd974ff2a27a37ee69956cd2e6bb31a608116206f3e31ef186823420182450" }, + { "daemonfox_NA", "022d6f4885f53cbd668ad7d03d4f8e830c233f74e3a918da1ed247edfc71820b3d" }, + { "nutellalicka_SH", "02f4b1e71bc865a79c05fe333952b97cb040d8925d13e83925e170188b3011269b" }, + { "starfleet_EU", "025c7275bd750936862b47793f1f0bb3cbed60fb75a48e7da016e557925fe375eb" }, + { "mrlynch_AR", "031987dc82b087cd53e23df5480e265a5928e9243e0e11849fa12359739d8b18a4" }, + { "greer_NA", "03e0995615d7d3cf1107effa6bdb1133e0876cf1768e923aa533a4e2ee675ec383" }, + { "mcrypt_SH", "025faab3cc2e83bf7dad6a9463cbff86c08800e937942126f258cf219bc2320043" }, + { "decker_EU", "03777777caebce56e17ca3aae4e16374335b156f1dd62ee3c7f8799c6b885f5560" }, + { "dappvader_SH", "02962e2e5af746632016bc7b24d444f7c90141a5f42ce54e361b302cf455d90e6a" }, + { "alright_DEV", "02b73a589d61691efa2ada15c006d27bc18493fea867ce6c14db3d3d28751f8ce3" }, + { "artemii235_DEV", "03bb616b12430bdd0483653de18733597a4fd416623c7065c0e21fe9d96460add1" }, + { "tonyl_DEV", "02d5f7fd6e25d34ab2f3318d60cdb89ff3a812ec5d0212c4c113bb12d12616cfdc" }, + { "decker_DEV", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" } + }, + { + // Season 5 + {"alrighttt_DEV", "03483166d8663beeb48a493eec161bf506df1906153b6259f7ca617e4cb8110260"}, // 0 + {"alien_AR", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f"}, + {"artempikulin_AR", "026a8ed1e4eeeb023cfb8e003e1c1de6a2b771f37e112745ffb8b6e375a9cbfdec"}, + {"chmex_AR", "036c856ea778ea105b93c0be187004d4e51161eda32888aa307b8f72d490884005"}, + {"cipi_AR", "033ae024cdb748e083406a2e20037017a1292079ad6a8161ae5b43f398724fea74"}, + {"shadowbit_AR", "02909c79a198179c193fb85bbd4ba09b875a5a9bd481fec284658188b96ed43519"}, + {"goldenman_AR", "0345b888e5de9c11871c080212ccaebf8a3d77b05fe3d535336efc5c7df334bbc7"}, + {"kolo_AR", "0281d3c7bf067088b9572b4d906afca2083a71a38b1011878ecd347651d00af433"}, + {"madmax_AR", "02f729b8df4dacdc8d811416eb32e98a5cc37023b42c81b77d1c00881de879a99a"}, + {"mcrypt_AR", "029bdb33b08f96524082490f4373bc6026b92bcaef9bc521a840a799c73b75ed80"}, + {"mrlynch_AR", "031987dc82b087cd53e23df5480e265a5928e9243e0e11849fa12359739d8b18a4"}, // 10 + {"ocean_AR", "03c2bc8c57a001a788851fedc33ce72797ee8fe26eaa3abb1b807727e4867a3105"}, + {"smdmitry_AR", "022a2a45979a6631a25e4c96469423de720a2f4c849548957c35a35c91041ee7ac"}, + {"tokel_AR", "03f3bf697173e47de7bae2ae02b3d3bcf28133a47db72f2a0266061597aaa7779d"}, + {"tonyl_AR", "029ad03929ec295e9164e2bfb9f0e0102c280d5e5212503d079d2d99ab492a9106"}, + {"tonyl_DEV", "02342ec82b31a016b71cd1eb2f482a74f63172e1029ba2fb18f0def3bd4fc0668a"}, + {"artem_DEV", "036b9848396ddcdb9bb58ddab2c24b710b8e4e9b0ee084a00518505ecd9e9fe174"}, + {"alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd"}, + {"alienx_EU", "026afe5b112d1b39e0edafd5e051e261a676104460581f3673f26ceff7f1e6c56c"}, + {"ca333_EU", "03ffb8072f78304c42ae9b60435f6c3296cbc72de129ae49bba175a65c31c9a7e2"}, + {"chmex_EU", "025b7209ba37df8d9695a23ea706ea2594863ab09055ca6bf485855937f3321d1d"}, // 20 + {"cipi_EU", "03d6e1f3a693b5d69049791005d7cb64c259a1ad85833f5a9c545d4fee29905009"}, + {"cipi2_EU", "0202e430157486503f4bde3d3ca770c8f1e2447cf480a6b273b5265b9620f585e3"}, + {"shadowbit_EU", "02668f5f723584f97f5e6f9196fc31018f36a6cf824c60328ad0c097a785df4745"}, + {"komodopioneers_EU", "0351f7f2a6ecce863e4e774bfafe2e59e151c08bf8f350286763a6b8ed97274b82"}, + {"madmax_EU", "028d04f7ccae0d9d57bfa801c4f1e32c707c17589b3c08a0ce08d44eab637eb66b"}, + {"marmarachain_EU", "023a858bbc3f0c6df5b74243315028e968c2f299d84ea8ecc0b28b5f0e2ad24c3c"}, + {"node-9_EU", "03c375924aac39d0c49de6690199e4d08d10fed6725988dcf5d2486661b5e3a656"}, + {"slyris_EU", "021cb6365c13cb35aad4b70aa18b63a75d1d4b9797a0754d3d0142d6fedc83b24e"}, + {"smdmitry_EU", "02eb3aad81778f8d6f7e5295c44ca224e5c812f5e43fc1e9ce4ebafc23324183c9"}, + {"van_EU", "03af7f8c82f20671ca1978116353839d3e501523e379bfb52b1e05d7816bb5812f"}, // 30 + {"shadowbit_DEV", "02ca882f153e715091a2dbc5409096f8c109d9fe6506ca7a918056dd37162b6f6e"}, + {"gcharang_DEV", "02cb445948bf0d89f8d61102e12a5ee6e98be61ac7c2cb9ba435219ea9db967117"}, + {"alien_NA", "03bea1ac333b95c8669ec091907ea8713cae26f74b9e886e13593400e21c4d30a8"}, + {"alienx_NA", "02f0b3ef87629509441b1ae95f28108f258a81910e483b90e0496205e24e7069b8"}, + {"cipi_NA", "036cc1d7476e4260601927be0fc8b748ae68d8fec8f5c498f71569a01bd92046c5"}, + {"computergenie_NA", "03a78ae070a5e9e935112cf7ea8293f18950f1011694ea0260799e8762c8a6f0a4"}, + {"dragonhound_NA", "02e650819f4d1cabeaad6bc5ec8c0722a89e63059a10f8b5e97c983c321608329b"}, + {"hyper_NA", "030994a303b26df6e7c6ed456f069c5de9e200e1380bebc5ed8ebe0f834f477f3d"}, + {"madmax_NA", "03898aec46014e8619e2369cc85073048dad05d3c5bf696d8b524db78a39ae5beb"}, + {"node-9_NA", "02f697eed99fd21f2f0eaad81d13543a75c576f669bfddbcbeef0f7625fea2e9d5"}, // 40 + {"nodeone_NA", "03f9dd0484e81174fd50775cb9099691c7d140ff00c0f088847e38dc87da67eb9b"}, + {"pbca26_NA", "0332543ff1287604afd67f63af0aa0b263aef14fe1850b85db16b81462eed834fd"}, + {"ptyx_NA", "02cbda9c43a794f2134a11815fe86dca017990269accb139e962d764c011c9a4d7"}, + {"strob_NA", "02a1c0bd40b294f06d3e44a52d1b2746c260c475c725e9351f1312e49e01c9a405"}, + {"karasugoi_NA", "0262cf2559703464151153c12e00c4b67a969e39b330301fdcaa6667d7eb02c57d"}, + {"webworker01_NA", "0376558d13c31cf9c664a1b5e58f4fff7153777069bef7a66ed8c8526b99787a9e"}, + {"yurii_DEV", "03e57c7341d2c8a3be62e1caaa28978d76a8277dea7bb484fdd8c55dc05e4e4e93"}, + {"ca333_DEV", "03d885e292842912bd990299ebce33451a5a01cb14e4874d90770efb22e82ef40f"}, + {"chmex_SH", "02698305eb3c27a2c724efd2152f9250739355116f201656c34b83aac2d3aebd19"}, + {"collider_SH", "03bd0022a55a2ead52fd65b317186743374ad320f3704d459f41797e264d1ec854"}, // 50 + {"dappvader_SH", "02bffea7911e09ad9a7df54af0c225516478d3ba138e65061aa8d4b9756bb4c8f4"}, + {"drkush_SH", "030b31cc9528566422e25f3e9b96541ab3626c0dea0e7aa3c0b0bd96039eae2f5a"}, + {"majora31_SH", "033bf21f039a1c832effad208d564e02e968f11e3a3aa41c42e3b748a232fb33f3"}, + {"mcrypt_SH", "025faab3cc2e83bf7dad6a9463cbff86c08800e937942126f258cf219bc2320043"}, + {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309"}, + {"mylo_SH", "03458dca36e800d5bc121d8c0d35f9fc6282880a79fee2d7e050f887b797bc7d6e"}, + {"nutellaLicka_SH", "03a495962a9e9eca06ee3b8ab4cd94e6ea0d87dd39d334ad85a524c4fece1a3db7"}, + {"pbca26_SH", "02c62877e96fc414f2444edf0601abff9d5d2f9078e49fa867ba5305f3c5b3beb0"}, + {"phit_SH", "02a9cef2141fb2af24349c1eea20f5fa8f5dba2835723778d19b23353ddcd877b1"}, + {"sheeba_SH", "03e6578015b7f0ab78a486070435031fff7bae11256ca6a9f3d358ab03029737cb"}, // 60 + {"strob_SH", "025ceac4256cef83ca4b110f837a71d70a5a977ecfdf807335e00bc78b560d451a"}, + {"strobnidan_SH", "02b967fde3686d45056343e488997d4c53f25cd7ad38548cd12b136010a09295ae"}, + {"dragonhound_DEV", "038e010c33c56b61389409eea5597fe17967398731e23185c84c472a16fc5d34ab"} + }, + { + // Season 6 + {"blackice_DEV", "02ca882f153e715091a2dbc5409096f8c109d9fe6506ca7a918056dd37162b6f6e"}, // 0 + {"blackice_AR", "02909c79a198179c193fb85bbd4ba09b875a5a9bd481fec284658188b96ed43519"}, + {"alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd"}, + {"alien_NA", "03bea1ac333b95c8669ec091907ea8713cae26f74b9e886e13593400e21c4d30a8"}, + {"alien_SH", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f"}, + {"alienx_EU", "026afe5b112d1b39e0edafd5e051e261a676104460581f3673f26ceff7f1e6c56c"}, + {"alienx_NA", "02f0b3ef87629509441b1ae95f28108f258a81910e483b90e0496205e24e7069b8"}, + {"artem.pikulin_AR", "026a8ed1e4eeeb023cfb8e003e1c1de6a2b771f37e112745ffb8b6e375a9cbfdec"}, + {"artem.pikulin_DEV", "036b9848396ddcdb9bb58ddab2c24b710b8e4e9b0ee084a00518505ecd9e9fe174"}, + {"blackice_EU", "02668f5f723584f97f5e6f9196fc31018f36a6cf824c60328ad0c097a785df4745"}, + {"chmex_AR", "036c856ea778ea105b93c0be187004d4e51161eda32888aa307b8f72d490884005"}, // 10 + {"chmex_EU", "025b7209ba37df8d9695a23ea706ea2594863ab09055ca6bf485855937f3321d1d"}, + {"chmex_NA", "030c2528c29d5328243c910277e3d74aa77c9b4e145308007d2b11550731591dbe"}, + {"chmex_SH", "02698305eb3c27a2c724efd2152f9250739355116f201656c34b83aac2d3aebd19"}, + {"chmex1_SH", "02d27ed1cddfbaff9e47865e7df0165457e8f075f70bbea8c0498598ccf494555d"}, + {"cipi_1_EU", "03d6e1f3a693b5d69049791005d7cb64c259a1ad85833f5a9c545d4fee29905009"}, + {"cipi_2_EU", "0202e430157486503f4bde3d3ca770c8f1e2447cf480a6b273b5265b9620f585e3"}, + {"cipi_AR", "033ae024cdb748e083406a2e20037017a1292079ad6a8161ae5b43f398724fea74"}, + {"cipi_NA", "036cc1d7476e4260601927be0fc8b748ae68d8fec8f5c498f71569a01bd92046c5"}, + {"computergenie_EU", "03a8c071036228e0900e0171f616ce1a58f0a761193551d68c4c20e70534f2e183"}, + {"computergenie_NA", "03a78ae070a5e9e935112cf7ea8293f18950f1011694ea0260799e8762c8a6f0a4"}, // 20 + {"dimxy_AR", "02689d0b77b1e8e8c93a102d8b689fd08179164d70e2dd585543c3896a0916e6a1"}, + {"dimxy_DEV", "039a01cd626d5efbe7fd05a59d8e5fced53bacac589192278f9b00ad31654b6956"}, + {"dragonhound_NA", "02e650819f4d1cabeaad6bc5ec8c0722a89e63059a10f8b5e97c983c321608329b"}, + {"fediakash_AR", "027dfe5403f8870fb0e1b94a2b4204373b31ea73179ba500a88dd56d22855cd03b"}, + {"gcharang_DEV", "033b82b5791c65477dd11095cf33332013df6d2bcb7aa06a6dae5f7b22b6959b0b"}, + {"gcharang_SH", "02cb445948bf0d89f8d61102e12a5ee6e98be61ac7c2cb9ba435219ea9db967117"}, + {"goldenman_AR", "02c11f651df6a03f1a17b9ea0b1a73c0acca7aeacd4081e09bd7dd939690af8ae1"}, + {"kolo_AR", "028431645f923a9e383a4e37cbb7168fa34988da23d43097124fe882bdac6d175f"}, + {"kolo_EU", "03e1287d4c14ad73ce9ddd31361a7de8df4eeeefe9460a1ff9a6b2a1242ad3b7c2"}, + {"kolox_AR", "0289f5f64f4bb18d014c4e9f4c888f4da2b6518e88fd5b7768728c38177b66d305"}, // 30 + {"komodopioneers_EU", "0351f7f2a6ecce863e4e774bfafe2e59e151c08bf8f350286763a6b8ed97274b82"}, + {"madmax_DEV", "027100e6b3db2028034db651946ecde90e45be3799ebc310d39af4496772a850ad"}, + {"marmarachain_EU", "0234e40800500370d43979586ee2cec2e777a0368d10c682e78bca30fd1630c18d"}, + {"mcrypt_AR", "029bdb33b08f96524082490f4373bc6026b92bcaef9bc521a840a799c73b75ed80"}, + {"mcrypt_SH", "025faab3cc2e83bf7dad6a9463cbff86c08800e937942126f258cf219bc2320043"}, + {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309"}, + {"mylo_NA", "0365a778014c216401b6ba9c28eec88f116a9a9912e145ba2dbbd065d98b493af5"}, + {"mylo_SH", "03458dca36e800d5bc121d8c0d35f9fc6282880a79fee2d7e050f887b797bc7d6e"}, + {"nodeone_NA", "03f9dd0484e81174fd50775cb9099691c7d140ff00c0f088847e38dc87da67eb9b"}, + {"nutellalicka_AR", "0285be2518bf8d65fceaa5f4d8485002f90d3b7ff274b23bb925fd167128e19589"}, // 40 + {"nutellalicka_SH", "03a8b10c1f74af429fc43ab4eb722f6c2a88087f2d71703e7f0e8001207a966fb5"}, + {"ocean_AR", "03c2bc8c57a001a788851fedc33ce72797ee8fe26eaa3abb1b807727e4867a3105"}, + {"pbca26_NA", "03d8b25536da157d931b159a72c0eeaedb1bf7bb3eb2d02647fa41b2422a2b064e"}, + {"pbca26_SH", "039a55787b742c3725323f0bd81c90a484fbdbf276a16317883bb03eedd9d6aa7c"}, + {"phit_SH", "02a9cef2141fb2af24349c1eea20f5fa8f5dba2835723778d19b23353ddcd877b1"}, + {"ptyx_NA", "0395640e81359526ecbc140716ddd5c9a1ce2a697fb547ca896e17cad3c65e78db"}, + {"ptyx2_NA", "0225ff37e49e443065018736fbcad175ab5993b51b99b846e8de0b8b9abbed2ef2"}, + {"sheeba_SH", "03e6578015b7f0ab78a486070435031fff7bae11256ca6a9f3d358ab03029737cb"}, + {"smdmitry_AR", "022a2a45979a6631a25e4c96469423de720a2f4c849548957c35a35c91041ee7ac"}, + {"smdmitry_EU", "02eb3aad81778f8d6f7e5295c44ca224e5c812f5e43fc1e9ce4ebafc23324183c9"}, // 50 + {"smdmitry_SH", "02d01cd6b87cbf5a9795c06968f0d169168c1be0d82cfeb79958b11ae2c30316c1"}, + {"strob_SH", "025ceac4256cef83ca4b110f837a71d70a5a977ecfdf807335e00bc78b560d451a"}, + {"strobnidan_SH", "02b967fde3686d45056343e488997d4c53f25cd7ad38548cd12b136010a09295ae"}, + {"tokel_NA", "02b472713e87fb2560569857051ea0811c65d668a6fe73df165afe152417f774a0"}, + {"tonyl_AR", "029ad03929ec295e9164e2bfb9f0e0102c280d5e5212503d079d2d99ab492a9106"}, + {"tonyl_DEV", "02342ec82b31a016b71cd1eb2f482a74f63172e1029ba2fb18f0def3bd4fc0668a"}, + {"van_EU", "03af7f8c82f20671ca1978116353839d3e501523e379bfb52b1e05d7816bb5812f"}, + {"webworker01_EU", "0321d523645caffd8e762764ba56f7874a61b9bf534837a2cb6e7da219fab15eef"}, + {"webworker01_NA", "0287883ddd8da366401893ebcc1ff7e52d2ad3736984120a0ab01603e02c21dc98"}, + {"who-biz_NA", "02f91a6772fe1a376e2bbe4b190008e3f878d40a8eaf92c65f1a7680b6b42ea47b"}, // 60 + {"yurii-khi_DEV", "03e57c7341d2c8a3be62e1caaa28978d76a8277dea7bb484fdd8c55dc05e4e4e93"}, + {"ca333_EU", "021d6fbe67d12f492a01306c70ab096f8b8581eb5f958d3f5fe3588ae8c7797f42"}, + {"dragonhound_DEV", "038e010c33c56b61389409eea5597fe17967398731e23185c84c472a16fc5d34ab"} + } +}; diff --git a/src/komodo_hardfork.h b/src/komodo_hardfork.h index 5cf20ad3..199bf43a 100644 --- a/src/komodo_hardfork.h +++ b/src/komodo_hardfork.h @@ -19,476 +19,7 @@ extern const int32_t nS6HardforkHeight; // dPoW Season 6, Fri Jun 24 2022 static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, nStakedDecemberHardforkTimestamp, nS4Timestamp, nS5Timestamp, nS6Timestamp, 1751328000}; static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {814000, 1444000, nDecemberHardforkHeight, nS4HardforkHeight, nS5HardforkHeight, nS6HardforkHeight, 7113400}; -// Era array of pubkeys. Add extra seasons to bottom as requried, after adding appropriate info above. -static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = -{ - { - { "0_jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, - { "0_jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, - { "0_kolo_testA", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" }, - { "artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, - { "artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, - { "artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, - { "artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, - { "badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, - { "badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, - { "badass_SH", "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" }, - { "crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, // 10 - { "crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, - { "crackers_SH", "02be28310e6312d1dd44651fd96f6a44ccc269a321f907502aae81d246fabdb03e" }, - { "durerus_EU", "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" }, - { "etszombi_AR", "031c79168d15edabf17d9ec99531ea9baa20039d0cdc14d9525863b83341b210e9" }, - { "etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, // 15 - { "etszombi_SH", "025d7a193c0757f7437fad3431f027e7b5ed6c925b77daba52a8755d24bf682dde" }, - { "farl4web_EU", "0300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3f" }, - { "farl4web_SH", "0396bb5ed3c57aa1221d7775ae0ff751e4c7dc9be220d0917fa8bbdf670586c030" }, - { "fullmoon_AR", "0254b1d64840ce9ff6bec9dd10e33beb92af5f7cee628f999cb6bc0fea833347cc" }, - { "fullmoon_NA", "031fb362323b06e165231c887836a8faadb96eda88a79ca434e28b3520b47d235b" }, // 20 - { "fullmoon_SH", "030e12b42ec33a80e12e570b6c8274ce664565b5c3da106859e96a7208b93afd0d" }, - { "grewal_NA", "03adc0834c203d172bce814df7c7a5e13dc603105e6b0adabc942d0421aefd2132" }, - { "grewal_SH", "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" }, - { "indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, - { "indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, - { "indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, - { "indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, - { "jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, - { "jsgalt_NA", "027b3fb6fede798cd17c30dbfb7baf9332b3f8b1c7c513f443070874c410232446" }, - { "karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, // 30 - { "kashifali_EU", "033777c52a0190f261c6f66bd0e2bb299d30f012dcb8bfff384103211edb8bb207" }, - { "kolo_AR", "03016d19344c45341e023b72f9fb6e6152fdcfe105f3b4f50b82a4790ff54e9dc6" }, - { "kolo_SH", "02aa24064500756d9b0959b44d5325f2391d8e95c6127e109184937152c384e185" }, - { "metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, - { "movecrypto_AR", "022783d94518e4dc77cbdf1a97915b29f427d7bc15ea867900a76665d3112be6f3" }, - { "movecrypto_EU", "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" }, - { "movecrypto_NA", "02efb12f4d78f44b0542d1c60146738e4d5506d27ec98a469142c5c84b29de0a80" }, - { "movecrypto_SH", "031f9739a3ebd6037a967ce1582cde66e79ea9a0551c54731c59c6b80f635bc859" }, - { "muros_AR", "022d77402fd7179335da39479c829be73428b0ef33fb360a4de6890f37c2aa005e" }, - { "noashh_AR", "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" }, // 40 - { "noashh_EU", "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" }, - { "noashh_NA", "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" }, - { "nxtswe_EU", "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" }, - { "polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, - { "pondsea_AR", "032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735" }, - { "pondsea_EU", "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" }, - { "pondsea_NA", "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" }, - { "pondsea_SH", "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" }, - { "popcornbag_AR", "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, - { "popcornbag_NA", "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, // 50 - { "ptytrader_NA", "0328c61467148b207400b23875234f8a825cce65b9c4c9b664f47410b8b8e3c222" }, - { "ptytrader_SH", "0250c93c492d8d5a6b565b90c22bee07c2d8701d6118c6267e99a4efd3c7748fa4" }, - { "rnr_AR", "029bdb08f931c0e98c2c4ba4ef45c8e33a34168cb2e6bf953cef335c359d77bfcd" }, - { "rnr_EU", "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" }, - { "rnr_NA", "02e17c5f8c3c80f584ed343b8dcfa6d710dfef0889ec1e7728ce45ce559347c58c" }, - { "rnr_SH", "037536fb9bdfed10251f71543fb42679e7c52308bcd12146b2568b9a818d8b8377" }, - { "titomane_AR", "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" }, - { "titomane_EU", "02e41feded94f0cc59f55f82f3c2c005d41da024e9a805b41105207ef89aa4bfbd" }, - { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, - { "vanbreuk_EU", "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" }, // 60 - { "xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, - { "xxspot1_XX", "02ef445a392fcaf3ad4176a5da7f43580e8056594e003eba6559a713711a27f955" }, - { "xxspot2_XX", "03d85b221ea72ebcd25373e7961f4983d12add66a92f899deaf07bab1d8b6f5573" } - }, - { - {"0dev1_jl777", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, - {"0dev2_kolo", "030f34af4b908fb8eb2099accb56b8d157d49f6cfb691baa80fdd34f385efed961" }, - {"0dev3_kolo", "025af9d2b2a05338478159e9ac84543968fd18c45fd9307866b56f33898653b014" }, - {"0dev4_decker", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" }, - {"a-team_SH", "03b59ad322b17cb94080dc8e6dc10a0a865de6d47c16fb5b1a0b5f77f9507f3cce" }, - {"artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, - {"artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, - {"artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, - {"artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, - {"badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, - {"badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, // 10 - {"batman_AR", "033ecb640ec5852f42be24c3bf33ca123fb32ced134bed6aa2ba249cf31b0f2563" }, - {"batman_SH", "02ca5898931181d0b8aafc75ef56fce9c43656c0b6c9f64306e7c8542f6207018c" }, - {"ca333_EU", "03fc87b8c804f12a6bd18efd43b0ba2828e4e38834f6b44c0bfee19f966a12ba99" }, - {"chainmakers_EU", "02f3b08938a7f8d2609d567aebc4989eeded6e2e880c058fdf092c5da82c3bc5ee" }, - {"chainmakers_NA", "0276c6d1c65abc64c8559710b8aff4b9e33787072d3dda4ec9a47b30da0725f57a" }, - {"chainstrike_SH", "0370bcf10575d8fb0291afad7bf3a76929734f888228bc49e35c5c49b336002153" }, - {"cipi_AR", "02c4f89a5b382750836cb787880d30e23502265054e1c327a5bfce67116d757ce8" }, - {"cipi_NA", "02858904a2a1a0b44df4c937b65ee1f5b66186ab87a751858cf270dee1d5031f18" }, - {"crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, - {"crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, // 20 - {"dwy_EU", "0259c646288580221fdf0e92dbeecaee214504fdc8bbdf4a3019d6ec18b7540424" }, - {"emmanux_SH", "033f316114d950497fc1d9348f03770cd420f14f662ab2db6172df44c389a2667a" }, - {"etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, - {"fullmoon_AR", "03380314c4f42fa854df8c471618751879f9e8f0ff5dbabda2bd77d0f96cb35676" }, - {"fullmoon_NA", "030216211d8e2a48bae9e5d7eb3a42ca2b7aae8770979a791f883869aea2fa6eef" }, - {"fullmoon_SH", "03f34282fa57ecc7aba8afaf66c30099b5601e98dcbfd0d8a58c86c20d8b692c64" }, - {"goldenman_EU", "02d6f13a8f745921cdb811e32237bb98950af1a5952be7b3d429abd9152f8e388d" }, - {"indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, - {"indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, - {"indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, // 30 - {"indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, - {"jackson_AR", "038ff7cfe34cb13b524e0941d5cf710beca2ffb7e05ddf15ced7d4f14fbb0a6f69" }, - {"jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, - {"karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, - {"komodoninja_EU", "038e567b99806b200b267b27bbca2abf6a3e8576406df5f872e3b38d30843cd5ba" }, - {"komodoninja_SH", "033178586896915e8456ebf407b1915351a617f46984001790f0cce3d6f3ada5c2" }, - {"komodopioneers_SH", "033ace50aedf8df70035b962a805431363a61cc4e69d99d90726a2d48fb195f68c" }, - {"libscott_SH", "03301a8248d41bc5dc926088a8cf31b65e2daf49eed7eb26af4fb03aae19682b95" }, - {"lukechilds_AR", "031aa66313ee024bbee8c17915cf7d105656d0ace5b4a43a3ab5eae1e14ec02696" }, - {"madmax_AR", "03891555b4a4393d655bf76f0ad0fb74e5159a615b6925907678edc2aac5e06a75" }, // 40 - {"meshbits_AR", "02957fd48ae6cb361b8a28cdb1b8ccf5067ff68eb1f90cba7df5f7934ed8eb4b2c" }, - {"meshbits_SH", "025c6e94877515dfd7b05682b9cc2fe4a49e076efe291e54fcec3add78183c1edb" }, - {"metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, - {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, - {"patchkez_SH", "0296270f394140640f8fa15684fc11255371abb6b9f253416ea2734e34607799c4" }, - {"pbca26_NA", "0276aca53a058556c485bbb60bdc54b600efe402a8b97f0341a7c04803ce204cb5" }, - {"peer2cloud_AR", "034e5563cb885999ae1530bd66fab728e580016629e8377579493b386bf6cebb15" }, - {"peer2cloud_SH", "03396ac453b3f23e20f30d4793c5b8ab6ded6993242df4f09fd91eb9a4f8aede84" }, - {"polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, - {"hyper_AR", "020f2f984d522051bd5247b61b080b4374a7ab389d959408313e8062acad3266b4" }, // 50 - {"hyper_EU", "03d00cf9ceace209c59fb013e112a786ad583d7de5ca45b1e0df3b4023bb14bf51" }, - {"hyper_SH", "0383d0b37f59f4ee5e3e98a47e461c861d49d0d90c80e9e16f7e63686a2dc071f3" }, - {"hyper_NA", "03d91c43230336c0d4b769c9c940145a8c53168bf62e34d1bccd7f6cfc7e5592de" }, - {"popcornbag_AR", "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, - {"popcornbag_NA", "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, - {"alien_AR", "0348d9b1fc6acf81290405580f525ee49b4749ed4637b51a28b18caa26543b20f0" }, - {"alien_EU", "020aab8308d4df375a846a9e3b1c7e99597b90497efa021d50bcf1bbba23246527" }, - {"thegaltmines_NA", "031bea28bec98b6380958a493a703ddc3353d7b05eb452109a773eefd15a32e421" }, - {"titomane_AR", "029d19215440d8cb9cc6c6b7a4744ae7fb9fb18d986e371b06aeb34b64845f9325" }, - {"titomane_EU", "0360b4805d885ff596f94312eed3e4e17cb56aa8077c6dd78d905f8de89da9499f" }, // 60 - {"titomane_SH", "03573713c5b20c1e682a2e8c0f8437625b3530f278e705af9b6614de29277a435b" }, - {"webworker01_NA", "03bb7d005e052779b1586f071834c5facbb83470094cff5112f0072b64989f97d7" }, - {"xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, - }, - { - {"madmax_NA", "0237e0d3268cebfa235958808db1efc20cc43b31100813b1f3e15cc5aa647ad2c3" }, // 0 - {"alright_AR", "020566fe2fb3874258b2d3cf1809a5d650e0edc7ba746fa5eec72750c5188c9cc9" }, - {"strob_NA", "0206f7a2e972d9dfef1c424c731503a0a27de1ba7a15a91a362dc7ec0d0fb47685" }, - {"dwy_EU", "021c7cf1f10c4dc39d13451123707ab780a741feedab6ac449766affe37515a29e" }, - {"phm87_SH", "021773a38db1bc3ede7f28142f901a161c7b7737875edbb40082a201c55dcf0add" }, - {"chainmakers_NA", "02285d813c30c0bf7eefdab1ff0a8ad08a07a0d26d8b95b3943ce814ac8e24d885" }, - {"indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, - {"blackjok3r_SH", "021eac26dbad256cbb6f74d41b10763183ee07fb609dbd03480dd50634170547cc" }, - {"chainmakers_EU", "03fdf5a3fce8db7dee89724e706059c32e5aa3f233a6b6cc256fea337f05e3dbf7" }, - {"titomane_AR", "023e3aa9834c46971ff3e7cb86a200ec9c8074a9566a3ea85d400d5739662ee989" }, - {"fullmoon_SH", "023b7252968ea8a955cd63b9e57dee45a74f2d7ba23b4e0595572138ad1fb42d21" }, // 10 - {"indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, - {"chmex_EU", "0281304ebbcc39e4f09fda85f4232dd8dacd668e20e5fc11fba6b985186c90086e" }, - {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, - {"ca333_DEV", "02856843af2d9457b5b1c907068bef6077ea0904cc8bd4df1ced013f64bf267958" }, - {"cipi_NA", "02858904a2a1a0b44df4c937b65ee1f5b66186ab87a751858cf270dee1d5031f18" }, - {"pungocloud_SH", "024dfc76fa1f19b892be9d06e985d0c411e60dbbeb36bd100af9892a39555018f6" }, - {"voskcoin_EU", "034190b1c062a04124ad15b0fa56dfdf34aa06c164c7163b6aec0d654e5f118afb" }, - {"decker_DEV", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" }, - {"cryptoeconomy_EU", "0290ab4937e85246e048552df3e9a66cba2c1602db76e03763e16c671e750145d1" }, - {"etszombi_EU", "0293ea48d8841af7a419a24d9da11c34b39127ef041f847651bae6ab14dcd1f6b4" }, // 20 - {"karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, - {"pirate_AR", "03e29c90354815a750db8ea9cb3c1b9550911bb205f83d0355a061ac47c4cf2fde" }, - {"metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, - {"zatjum_SH", "02d6b0c89cacd58a0af038139a9a90c9e02cd1e33803a1f15fceabea1f7e9c263a" }, - {"madmax_AR", "03c5941fe49d673c094bc8e9bb1a95766b4670c88be76d576e915daf2c30a454d3" }, - {"lukechilds_NA", "03f1051e62c2d280212481c62fe52aab0a5b23c95de5b8e9ad5f80d8af4277a64b" }, - {"cipi_AR", "02c4f89a5b382750836cb787880d30e23502265054e1c327a5bfce67116d757ce8" }, - {"tonyl_AR", "02cc8bc862f2b65ad4f99d5f68d3011c138bf517acdc8d4261166b0be8f64189e1" }, - {"infotech_DEV", "0345ad4ab5254782479f6322c369cec77a7535d2f2162d103d666917d5e4f30c4c" }, - {"fullmoon_NA", "032c716701fe3a6a3f90a97b9d874a9d6eedb066419209eed7060b0cc6b710c60b" }, // 30 - {"etszombi_AR", "02e55e104aa94f70cde68165d7df3e162d4410c76afd4643b161dea044aa6d06ce" }, - {"node-9_EU", "0372e5b51e86e2392bb15039bac0c8f975b852b45028a5e43b324c294e9f12e411" }, - {"phba2061_EU", "03f6bd15dba7e986f0c976ea19d8a9093cb7c989d499f1708a0386c5c5659e6c4e" }, - {"indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, - {"and1-89_EU", "02736cbf8d7b50835afd50a319f162dd4beffe65f2b1dc6b90e64b32c8e7849ddd" }, - {"komodopioneers_SH", "032a238a5747777da7e819cfa3c859f3677a2daf14e4dce50916fc65d00ad9c52a" }, - {"komodopioneers_EU", "036d02425916444fff8cc7203fcbfc155c956dda5ceb647505836bef59885b6866" }, - {"d0ct0r_NA", "0303725d8525b6f969122faf04152653eb4bf34e10de92182263321769c334bf58" }, - {"kolo_DEV", "02849e12199dcc27ba09c3902686d2ad0adcbfcee9d67520e9abbdda045ba83227" }, - {"peer2cloud_AR", "02acc001fe1fe8fd68685ba26c0bc245924cb592e10cec71e9917df98b0e9d7c37" }, // 40 - {"webworker01_SH", "031e50ba6de3c16f99d414bb89866e578d963a54bde7916c810608966fb5700776" }, - {"webworker01_NA", "032735e9cad1bb00eaababfa6d27864fa4c1db0300c85e01e52176be2ca6a243ce" }, - {"pbca26_NA", "03a97606153d52338bcffd1bf19bb69ef8ce5a7cbdc2dbc3ff4f89d91ea6bbb4dc" }, - {"indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, - {"pirate_NA", "0255e32d8a56671dee8aa7f717debb00efa7f0086ee802de0692f2d67ee3ee06ee" }, - {"lukechilds_AR", "025c6a73ff6d750b9ddf6755b390948cffdd00f344a639472d398dd5c6b4735d23" }, - {"dragonhound_NA", "0224a9d951d3a06d8e941cc7362b788bb1237bb0d56cc313e797eb027f37c2d375" }, - {"fullmoon_AR", "03da64dd7cd0db4c123c2f79d548a96095a5a103e5b9d956e9832865818ffa7872" }, - {"chainzilla_SH", "0360804b8817fd25ded6e9c0b50e3b0782ac666545b5416644198e18bc3903d9f9" }, - {"titomane_EU", "03772ac0aad6b0e9feec5e591bff5de6775d6132e888633e73d3ba896bdd8e0afb" }, // 50 - {"jeezy_EU", "037f182facbad35684a6e960699f5da4ba89e99f0d0d62a87e8400dd086c8e5dd7" }, - {"titomane_SH", "03850fdddf2413b51790daf51dd30823addb37313c8854b508ea6228205047ef9b" }, - {"alien_AR", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f" }, - {"pirate_EU", "03fff24efd5648870a23badf46e26510e96d9e79ce281b27cfe963993039dd1351" }, - {"thegaltmines_NA", "02db1a16c7043f45d6033ccfbd0a51c2d789b32db428902f98b9e155cf0d7910ed" }, - {"computergenie_NA", "03a78ae070a5e9e935112cf7ea8293f18950f1011694ea0260799e8762c8a6f0a4" }, - {"nutellalicka_SH", "02f7d90d0510c598ce45915e6372a9cd0ba72664cb65ce231f25d526fc3c5479fc" }, - {"chainstrike_SH", "03b806be3bf7a1f2f6290ec5c1ea7d3ea57774dcfcf2129a82b2569e585100e1cb" }, - {"dwy_SH", "036536d2d52d85f630b68b050f29ea1d7f90f3b42c10f8c5cdf3dbe1359af80aff" }, - {"alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd" }, // 60 - {"gt_AR", "0348430538a4944d3162bb4749d8c5ed51299c2434f3ee69c11a1f7815b3f46135" }, - {"patchkez_SH", "03f45e9beb5c4cd46525db8195eb05c1db84ae7ef3603566b3d775770eba3b96ee" }, - {"decker_AR", "03ffdf1a116300a78729608d9930742cd349f11a9d64fcc336b8f18592dd9c91bc" }, // 63 - }, - { - // Season 3.5 - {"madmax_NA", "0237e0d3268cebfa235958808db1efc20cc43b31100813b1f3e15cc5aa647ad2c3" }, // 0 - {"alright_AR", "020566fe2fb3874258b2d3cf1809a5d650e0edc7ba746fa5eec72750c5188c9cc9" }, - {"strob_NA", "0206f7a2e972d9dfef1c424c731503a0a27de1ba7a15a91a362dc7ec0d0fb47685" }, - {"hunter_EU", "0378224b4e9d8a0083ce36f2963ec0a4e231ec06b0c780de108e37f41181a89f6a" }, // FIXME verify this, kolo. Change name if you want - {"phm87_SH", "021773a38db1bc3ede7f28142f901a161c7b7737875edbb40082a201c55dcf0add" }, - {"chainmakers_NA", "02285d813c30c0bf7eefdab1ff0a8ad08a07a0d26d8b95b3943ce814ac8e24d885" }, - {"indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, - {"blackjok3r_SH", "021eac26dbad256cbb6f74d41b10763183ee07fb609dbd03480dd50634170547cc" }, - {"chainmakers_EU", "03fdf5a3fce8db7dee89724e706059c32e5aa3f233a6b6cc256fea337f05e3dbf7" }, - {"titomane_AR", "023e3aa9834c46971ff3e7cb86a200ec9c8074a9566a3ea85d400d5739662ee989" }, - {"fullmoon_SH", "023b7252968ea8a955cd63b9e57dee45a74f2d7ba23b4e0595572138ad1fb42d21" }, // 10 - {"indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, - {"chmex_EU", "0281304ebbcc39e4f09fda85f4232dd8dacd668e20e5fc11fba6b985186c90086e" }, - {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, - {"ca333_DEV", "02856843af2d9457b5b1c907068bef6077ea0904cc8bd4df1ced013f64bf267958" }, - {"cipi_NA", "02858904a2a1a0b44df4c937b65ee1f5b66186ab87a751858cf270dee1d5031f18" }, - {"pungocloud_SH", "024dfc76fa1f19b892be9d06e985d0c411e60dbbeb36bd100af9892a39555018f6" }, - {"voskcoin_EU", "034190b1c062a04124ad15b0fa56dfdf34aa06c164c7163b6aec0d654e5f118afb" }, - {"decker_DEV", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" }, - {"cryptoeconomy_EU", "0290ab4937e85246e048552df3e9a66cba2c1602db76e03763e16c671e750145d1" }, - {"etszombi_EU", "0293ea48d8841af7a419a24d9da11c34b39127ef041f847651bae6ab14dcd1f6b4" }, // 20 - {"karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, - {"pirate_AR", "03e29c90354815a750db8ea9cb3c1b9550911bb205f83d0355a061ac47c4cf2fde" }, - {"metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, - {"zatjum_SH", "02d6b0c89cacd58a0af038139a9a90c9e02cd1e33803a1f15fceabea1f7e9c263a" }, - {"madmax_AR", "03c5941fe49d673c094bc8e9bb1a95766b4670c88be76d576e915daf2c30a454d3" }, - {"lukechilds_NA", "03f1051e62c2d280212481c62fe52aab0a5b23c95de5b8e9ad5f80d8af4277a64b" }, - {"cipi_AR", "02c4f89a5b382750836cb787880d30e23502265054e1c327a5bfce67116d757ce8" }, - {"tonyl_AR", "02cc8bc862f2b65ad4f99d5f68d3011c138bf517acdc8d4261166b0be8f64189e1" }, - {"infotech_DEV", "0345ad4ab5254782479f6322c369cec77a7535d2f2162d103d666917d5e4f30c4c" }, - {"fullmoon_NA", "032c716701fe3a6a3f90a97b9d874a9d6eedb066419209eed7060b0cc6b710c60b" }, // 30 - {"etszombi_AR", "02e55e104aa94f70cde68165d7df3e162d4410c76afd4643b161dea044aa6d06ce" }, - {"node-9_EU", "0372e5b51e86e2392bb15039bac0c8f975b852b45028a5e43b324c294e9f12e411" }, - {"phba2061_EU", "03f6bd15dba7e986f0c976ea19d8a9093cb7c989d499f1708a0386c5c5659e6c4e" }, - {"indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, - {"and1-89_EU", "02736cbf8d7b50835afd50a319f162dd4beffe65f2b1dc6b90e64b32c8e7849ddd" }, - {"komodopioneers_SH", "032a238a5747777da7e819cfa3c859f3677a2daf14e4dce50916fc65d00ad9c52a" }, - {"komodopioneers_EU", "036d02425916444fff8cc7203fcbfc155c956dda5ceb647505836bef59885b6866" }, - {"d0ct0r_NA", "0303725d8525b6f969122faf04152653eb4bf34e10de92182263321769c334bf58" }, - {"kolo_DEV", "02849e12199dcc27ba09c3902686d2ad0adcbfcee9d67520e9abbdda045ba83227" }, - {"peer2cloud_AR", "02acc001fe1fe8fd68685ba26c0bc245924cb592e10cec71e9917df98b0e9d7c37" }, // 40 - {"webworker01_SH", "031e50ba6de3c16f99d414bb89866e578d963a54bde7916c810608966fb5700776" }, - {"webworker01_NA", "032735e9cad1bb00eaababfa6d27864fa4c1db0300c85e01e52176be2ca6a243ce" }, - {"pbca26_NA", "03a97606153d52338bcffd1bf19bb69ef8ce5a7cbdc2dbc3ff4f89d91ea6bbb4dc" }, - {"indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, - {"pirate_NA", "0255e32d8a56671dee8aa7f717debb00efa7f0086ee802de0692f2d67ee3ee06ee" }, - {"lukechilds_AR", "025c6a73ff6d750b9ddf6755b390948cffdd00f344a639472d398dd5c6b4735d23" }, - {"dragonhound_NA", "0224a9d951d3a06d8e941cc7362b788bb1237bb0d56cc313e797eb027f37c2d375" }, - {"fullmoon_AR", "03da64dd7cd0db4c123c2f79d548a96095a5a103e5b9d956e9832865818ffa7872" }, - {"chainzilla_SH", "0360804b8817fd25ded6e9c0b50e3b0782ac666545b5416644198e18bc3903d9f9" }, - {"titomane_EU", "03772ac0aad6b0e9feec5e591bff5de6775d6132e888633e73d3ba896bdd8e0afb" }, // 50 - {"jeezy_EU", "037f182facbad35684a6e960699f5da4ba89e99f0d0d62a87e8400dd086c8e5dd7" }, - {"titomane_SH", "03850fdddf2413b51790daf51dd30823addb37313c8854b508ea6228205047ef9b" }, - {"alien_AR", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f" }, - {"pirate_EU", "03fff24efd5648870a23badf46e26510e96d9e79ce281b27cfe963993039dd1351" }, - {"thegaltmines_NA", "02db1a16c7043f45d6033ccfbd0a51c2d789b32db428902f98b9e155cf0d7910ed" }, - {"computergenie_NA", "03a78ae070a5e9e935112cf7ea8293f18950f1011694ea0260799e8762c8a6f0a4" }, - {"nutellalicka_SH", "02f7d90d0510c598ce45915e6372a9cd0ba72664cb65ce231f25d526fc3c5479fc" }, - {"chainstrike_SH", "03b806be3bf7a1f2f6290ec5c1ea7d3ea57774dcfcf2129a82b2569e585100e1cb" }, - {"hunter_SH", "02407db70ad30ce4dfaee8b4ae35fae88390cad2b0ba0373fdd6231967537ccfdf" }, - {"alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd" }, // 60 - {"gt_AR", "0348430538a4944d3162bb4749d8c5ed51299c2434f3ee69c11a1f7815b3f46135" }, - {"patchkez_SH", "03f45e9beb5c4cd46525db8195eb05c1db84ae7ef3603566b3d775770eba3b96ee" }, - {"decker_AR", "03ffdf1a116300a78729608d9930742cd349f11a9d64fcc336b8f18592dd9c91bc" }, // 63 - }, - { - // Season 4 - { "alien_AR", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f" }, - { "alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd" }, - { "strob_NA", "02a1c0bd40b294f06d3e44a52d1b2746c260c475c725e9351f1312e49e01c9a405" }, - { "titomane_SH", "020014ad4eedf6b1aeb0ad3b101a58d0a2fc570719e46530fd98d4e585f63eb4ae" }, - { "fullmoon_AR", "03b251095e747f759505ec745a4bbff9a768b8dce1f65137300b7c21efec01a07a" }, - { "phba2061_EU", "03a9492d2a1601d0d98cfe94d8adf9689d1bb0e600088127a4f6ca937761fb1c66" }, - { "fullmoon_NA", "03931c1d654a99658998ce0ddae108d825943a821d1cddd85e948ac1d483f68fb6" }, - { "fullmoon_SH", "03c2a1ed9ddb7bb8344328946017b9d8d1357b898957dd6aaa8c190ae26740b9ff" }, - { "madmax_AR", "022be5a2829fa0291f9a51ff7aeceef702eef581f2611887c195e29da49092e6de" }, - { "titomane_EU", "0285cf1fdba761daf6f1f611c32d319cd58214972ef822793008b69dde239443dd" }, - { "cipi_NA", "022c6825a24792cc3b010b1531521eba9b5e2662d640ed700fd96167df37e75239" }, - { "indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, - { "decker_AR", "03ffdf1a116300a78729608d9930742cd349f11a9d64fcc336b8f18592dd9c91bc" }, - { "indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, - { "madmax_NA", "02997b7ab21b86bbea558ae79acc35d62c9cedf441578f78112f986d72e8eece08" }, - { "chainzilla_SH", "02288ba6dc57936b59d60345e397d62f5d7e7d975f34ed5c2f2e23288325661563" }, - { "peer2cloud_AR", "0250e7e43a3535731b051d1bcc7dc88fbb5163c3fe41c5dee72bd973bcc4dca9f2" }, - { "pirate_EU", "0231c0f50a06655c3d2edf8d7e722d290195d49c78d50de7786b9d196e8820c848" }, - { "webworker01_NA", "02dfd5f3cef1142879a7250752feb91ddd722c497fb98c7377c0fcc5ccc201bd55" }, - { "zatjum_SH", "036066fd638b10e555597623e97e032b28b4d1fa5a13c2b0c80c420dbddad236c2" }, - { "titomane_AR", "0268203a4c80047edcd66385c22e764ea5fb8bc42edae389a438156e7dca9a8251" }, - { "chmex_EU", "025b7209ba37df8d9695a23ea706ea2594863ab09055ca6bf485855937f3321d1d" }, - { "indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, - { "patchkez_SH", "02cabd6c5fc0b5476c7a01e9d7b907e9f0a051d7f4f731959955d3f6b18ee9a242" }, - { "metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, - { "etszombi_EU", "0341adbf238f33a33cc895633db996c3ad01275313ac6641e046a3db0b27f1c880" }, - { "pirate_NA", "02207f27a13625a0b8caef6a7bb9de613ff16e4a5f232da8d7c235c7c5bad72ffe" }, - { "metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, - { "indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, - { "chainmakers_NA", "029415a1609c33dfe4a1016877ba35f9265d25d737649f307048efe96e76512877" }, - { "mihailo_EU", "037f9563f30c609b19fd435a19b8bde7d6db703012ba1aba72e9f42a87366d1941" }, - { "tonyl_AR", "0299684d7291abf90975fa493bf53212cf1456c374aa36f83cc94daece89350ae9" }, - { "alien_NA", "03bea1ac333b95c8669ec091907ea8713cae26f74b9e886e13593400e21c4d30a8" }, - { "pungocloud_SH", "025b97d8c23effaca6fa7efacce20bf54df73081b63004a0fe22f3f98fece5669f" }, - { "node9_EU", "029ffa793b5c3248f8ea3da47fa3cf1810dada5af032ecd0e37bab5b92dd63b34e" }, - { "smdmitry_AR", "022a2a45979a6631a25e4c96469423de720a2f4c849548957c35a35c91041ee7ac" }, - { "nodeone_NA", "03f9dd0484e81174fd50775cb9099691c7d140ff00c0f088847e38dc87da67eb9b" }, - { "gcharang_SH", "02ec4172eab854a0d8cd32bc691c83e93975a3df5a4a453a866736c56e025dc359" }, - { "cipi_EU", "02f2b6defff1c544202f66e47cfd6909c54d67c7c39b9c2a99f137dbaf6d0bd8fa" }, - { "etszombi_AR", "0329944b0ac65b6760787ede042a2fde0be9fca1d80dd756bc0ee0b98d389b7682" }, - { "pbca26_NA", "0387e0fb6f2ca951154c87e16c6cbf93a69862bb165c1a96bcd8722b3af24fe533" }, - { "mylo_SH", "03b58f57822e90fe105e6efb63fd8666033ea503d6cc165b1e479bbd8c2ba033e8" }, - { "swisscertifiers_EU", "03ebcc71b42d88994b8b2134bcde6cb269bd7e71a9dd7616371d9294ec1c1902c5" }, - { "marmarachain_AR", "035bbd81a098172592fe97f50a0ce13cbbf80e55cc7862eccdbd7310fab8a90c4c" }, - { "karasugoi_NA", "0262cf2559703464151153c12e00c4b67a969e39b330301fdcaa6667d7eb02c57d" }, - { "phm87_SH", "021773a38db1bc3ede7f28142f901a161c7b7737875edbb40082a201c55dcf0add" }, - { "oszy_EU", "03d1ffd680491b98a3ec5541715681d1a45293c8efb1722c32392a1d792622596a" }, - { "chmex_AR", "036c856ea778ea105b93c0be187004d4e51161eda32888aa307b8f72d490884005" }, - { "dragonhound_NA", "0227e5cad3731e381df157de189527aac8eb50d82a13ce2bd81153984ebc749515" }, - { "strob_SH", "025ceac4256cef83ca4b110f837a71d70a5a977ecfdf807335e00bc78b560d451a" }, - { "madmax_EU", "02ea0cf4d6d151d0528b07efa79cc7403d77cb9195e2e6c8374f5074b9a787e287" }, - { "dudezmobi_AR", "027ecd974ff2a27a37ee69956cd2e6bb31a608116206f3e31ef186823420182450" }, - { "daemonfox_NA", "022d6f4885f53cbd668ad7d03d4f8e830c233f74e3a918da1ed247edfc71820b3d" }, - { "nutellalicka_SH", "02f4b1e71bc865a79c05fe333952b97cb040d8925d13e83925e170188b3011269b" }, - { "starfleet_EU", "025c7275bd750936862b47793f1f0bb3cbed60fb75a48e7da016e557925fe375eb" }, - { "mrlynch_AR", "031987dc82b087cd53e23df5480e265a5928e9243e0e11849fa12359739d8b18a4" }, - { "greer_NA", "03e0995615d7d3cf1107effa6bdb1133e0876cf1768e923aa533a4e2ee675ec383" }, - { "mcrypt_SH", "025faab3cc2e83bf7dad6a9463cbff86c08800e937942126f258cf219bc2320043" }, - { "decker_EU", "03777777caebce56e17ca3aae4e16374335b156f1dd62ee3c7f8799c6b885f5560" }, - { "dappvader_SH", "02962e2e5af746632016bc7b24d444f7c90141a5f42ce54e361b302cf455d90e6a" }, - { "alright_DEV", "02b73a589d61691efa2ada15c006d27bc18493fea867ce6c14db3d3d28751f8ce3" }, - { "artemii235_DEV", "03bb616b12430bdd0483653de18733597a4fd416623c7065c0e21fe9d96460add1" }, - { "tonyl_DEV", "02d5f7fd6e25d34ab2f3318d60cdb89ff3a812ec5d0212c4c113bb12d12616cfdc" }, - { "decker_DEV", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" } - }, - { - // Season 5 - {"alrighttt_DEV", "03483166d8663beeb48a493eec161bf506df1906153b6259f7ca617e4cb8110260"}, // 0 - {"alien_AR", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f"}, - {"artempikulin_AR", "026a8ed1e4eeeb023cfb8e003e1c1de6a2b771f37e112745ffb8b6e375a9cbfdec"}, - {"chmex_AR", "036c856ea778ea105b93c0be187004d4e51161eda32888aa307b8f72d490884005"}, - {"cipi_AR", "033ae024cdb748e083406a2e20037017a1292079ad6a8161ae5b43f398724fea74"}, - {"shadowbit_AR", "02909c79a198179c193fb85bbd4ba09b875a5a9bd481fec284658188b96ed43519"}, - {"goldenman_AR", "0345b888e5de9c11871c080212ccaebf8a3d77b05fe3d535336efc5c7df334bbc7"}, - {"kolo_AR", "0281d3c7bf067088b9572b4d906afca2083a71a38b1011878ecd347651d00af433"}, - {"madmax_AR", "02f729b8df4dacdc8d811416eb32e98a5cc37023b42c81b77d1c00881de879a99a"}, - {"mcrypt_AR", "029bdb33b08f96524082490f4373bc6026b92bcaef9bc521a840a799c73b75ed80"}, - {"mrlynch_AR", "031987dc82b087cd53e23df5480e265a5928e9243e0e11849fa12359739d8b18a4"}, // 10 - {"ocean_AR", "03c2bc8c57a001a788851fedc33ce72797ee8fe26eaa3abb1b807727e4867a3105"}, - {"smdmitry_AR", "022a2a45979a6631a25e4c96469423de720a2f4c849548957c35a35c91041ee7ac"}, - {"tokel_AR", "03f3bf697173e47de7bae2ae02b3d3bcf28133a47db72f2a0266061597aaa7779d"}, - {"tonyl_AR", "029ad03929ec295e9164e2bfb9f0e0102c280d5e5212503d079d2d99ab492a9106"}, - {"tonyl_DEV", "02342ec82b31a016b71cd1eb2f482a74f63172e1029ba2fb18f0def3bd4fc0668a"}, - {"artem_DEV", "036b9848396ddcdb9bb58ddab2c24b710b8e4e9b0ee084a00518505ecd9e9fe174"}, - {"alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd"}, - {"alienx_EU", "026afe5b112d1b39e0edafd5e051e261a676104460581f3673f26ceff7f1e6c56c"}, - {"ca333_EU", "03ffb8072f78304c42ae9b60435f6c3296cbc72de129ae49bba175a65c31c9a7e2"}, - {"chmex_EU", "025b7209ba37df8d9695a23ea706ea2594863ab09055ca6bf485855937f3321d1d"}, // 20 - {"cipi_EU", "03d6e1f3a693b5d69049791005d7cb64c259a1ad85833f5a9c545d4fee29905009"}, - {"cipi2_EU", "0202e430157486503f4bde3d3ca770c8f1e2447cf480a6b273b5265b9620f585e3"}, - {"shadowbit_EU", "02668f5f723584f97f5e6f9196fc31018f36a6cf824c60328ad0c097a785df4745"}, - {"komodopioneers_EU", "0351f7f2a6ecce863e4e774bfafe2e59e151c08bf8f350286763a6b8ed97274b82"}, - {"madmax_EU", "028d04f7ccae0d9d57bfa801c4f1e32c707c17589b3c08a0ce08d44eab637eb66b"}, - {"marmarachain_EU", "023a858bbc3f0c6df5b74243315028e968c2f299d84ea8ecc0b28b5f0e2ad24c3c"}, - {"node-9_EU", "03c375924aac39d0c49de6690199e4d08d10fed6725988dcf5d2486661b5e3a656"}, - {"slyris_EU", "021cb6365c13cb35aad4b70aa18b63a75d1d4b9797a0754d3d0142d6fedc83b24e"}, - {"smdmitry_EU", "02eb3aad81778f8d6f7e5295c44ca224e5c812f5e43fc1e9ce4ebafc23324183c9"}, - {"van_EU", "03af7f8c82f20671ca1978116353839d3e501523e379bfb52b1e05d7816bb5812f"}, // 30 - {"shadowbit_DEV", "02ca882f153e715091a2dbc5409096f8c109d9fe6506ca7a918056dd37162b6f6e"}, - {"gcharang_DEV", "02cb445948bf0d89f8d61102e12a5ee6e98be61ac7c2cb9ba435219ea9db967117"}, - {"alien_NA", "03bea1ac333b95c8669ec091907ea8713cae26f74b9e886e13593400e21c4d30a8"}, - {"alienx_NA", "02f0b3ef87629509441b1ae95f28108f258a81910e483b90e0496205e24e7069b8"}, - {"cipi_NA", "036cc1d7476e4260601927be0fc8b748ae68d8fec8f5c498f71569a01bd92046c5"}, - {"computergenie_NA", "03a78ae070a5e9e935112cf7ea8293f18950f1011694ea0260799e8762c8a6f0a4"}, - {"dragonhound_NA", "02e650819f4d1cabeaad6bc5ec8c0722a89e63059a10f8b5e97c983c321608329b"}, - {"hyper_NA", "030994a303b26df6e7c6ed456f069c5de9e200e1380bebc5ed8ebe0f834f477f3d"}, - {"madmax_NA", "03898aec46014e8619e2369cc85073048dad05d3c5bf696d8b524db78a39ae5beb"}, - {"node-9_NA", "02f697eed99fd21f2f0eaad81d13543a75c576f669bfddbcbeef0f7625fea2e9d5"}, // 40 - {"nodeone_NA", "03f9dd0484e81174fd50775cb9099691c7d140ff00c0f088847e38dc87da67eb9b"}, - {"pbca26_NA", "0332543ff1287604afd67f63af0aa0b263aef14fe1850b85db16b81462eed834fd"}, - {"ptyx_NA", "02cbda9c43a794f2134a11815fe86dca017990269accb139e962d764c011c9a4d7"}, - {"strob_NA", "02a1c0bd40b294f06d3e44a52d1b2746c260c475c725e9351f1312e49e01c9a405"}, - {"karasugoi_NA", "0262cf2559703464151153c12e00c4b67a969e39b330301fdcaa6667d7eb02c57d"}, - {"webworker01_NA", "0376558d13c31cf9c664a1b5e58f4fff7153777069bef7a66ed8c8526b99787a9e"}, - {"yurii_DEV", "03e57c7341d2c8a3be62e1caaa28978d76a8277dea7bb484fdd8c55dc05e4e4e93"}, - {"ca333_DEV", "03d885e292842912bd990299ebce33451a5a01cb14e4874d90770efb22e82ef40f"}, - {"chmex_SH", "02698305eb3c27a2c724efd2152f9250739355116f201656c34b83aac2d3aebd19"}, - {"collider_SH", "03bd0022a55a2ead52fd65b317186743374ad320f3704d459f41797e264d1ec854"}, // 50 - {"dappvader_SH", "02bffea7911e09ad9a7df54af0c225516478d3ba138e65061aa8d4b9756bb4c8f4"}, - {"drkush_SH", "030b31cc9528566422e25f3e9b96541ab3626c0dea0e7aa3c0b0bd96039eae2f5a"}, - {"majora31_SH", "033bf21f039a1c832effad208d564e02e968f11e3a3aa41c42e3b748a232fb33f3"}, - {"mcrypt_SH", "025faab3cc2e83bf7dad6a9463cbff86c08800e937942126f258cf219bc2320043"}, - {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309"}, - {"mylo_SH", "03458dca36e800d5bc121d8c0d35f9fc6282880a79fee2d7e050f887b797bc7d6e"}, - {"nutellaLicka_SH", "03a495962a9e9eca06ee3b8ab4cd94e6ea0d87dd39d334ad85a524c4fece1a3db7"}, - {"pbca26_SH", "02c62877e96fc414f2444edf0601abff9d5d2f9078e49fa867ba5305f3c5b3beb0"}, - {"phit_SH", "02a9cef2141fb2af24349c1eea20f5fa8f5dba2835723778d19b23353ddcd877b1"}, - {"sheeba_SH", "03e6578015b7f0ab78a486070435031fff7bae11256ca6a9f3d358ab03029737cb"}, // 60 - {"strob_SH", "025ceac4256cef83ca4b110f837a71d70a5a977ecfdf807335e00bc78b560d451a"}, - {"strobnidan_SH", "02b967fde3686d45056343e488997d4c53f25cd7ad38548cd12b136010a09295ae"}, - {"dragonhound_DEV", "038e010c33c56b61389409eea5597fe17967398731e23185c84c472a16fc5d34ab"} - }, - { - // Season 6 - {"blackice_DEV", "02ca882f153e715091a2dbc5409096f8c109d9fe6506ca7a918056dd37162b6f6e"}, // 0 - {"blackice_AR", "02909c79a198179c193fb85bbd4ba09b875a5a9bd481fec284658188b96ed43519"}, - {"alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd"}, - {"alien_NA", "03bea1ac333b95c8669ec091907ea8713cae26f74b9e886e13593400e21c4d30a8"}, - {"alien_SH", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f"}, - {"alienx_EU", "026afe5b112d1b39e0edafd5e051e261a676104460581f3673f26ceff7f1e6c56c"}, - {"alienx_NA", "02f0b3ef87629509441b1ae95f28108f258a81910e483b90e0496205e24e7069b8"}, - {"artem.pikulin_AR", "026a8ed1e4eeeb023cfb8e003e1c1de6a2b771f37e112745ffb8b6e375a9cbfdec"}, - {"artem.pikulin_DEV", "036b9848396ddcdb9bb58ddab2c24b710b8e4e9b0ee084a00518505ecd9e9fe174"}, - {"blackice_EU", "02668f5f723584f97f5e6f9196fc31018f36a6cf824c60328ad0c097a785df4745"}, - {"chmex_AR", "036c856ea778ea105b93c0be187004d4e51161eda32888aa307b8f72d490884005"}, // 10 - {"chmex_EU", "025b7209ba37df8d9695a23ea706ea2594863ab09055ca6bf485855937f3321d1d"}, - {"chmex_NA", "030c2528c29d5328243c910277e3d74aa77c9b4e145308007d2b11550731591dbe"}, - {"chmex_SH", "02698305eb3c27a2c724efd2152f9250739355116f201656c34b83aac2d3aebd19"}, - {"chmex1_SH", "02d27ed1cddfbaff9e47865e7df0165457e8f075f70bbea8c0498598ccf494555d"}, - {"cipi_1_EU", "03d6e1f3a693b5d69049791005d7cb64c259a1ad85833f5a9c545d4fee29905009"}, - {"cipi_2_EU", "0202e430157486503f4bde3d3ca770c8f1e2447cf480a6b273b5265b9620f585e3"}, - {"cipi_AR", "033ae024cdb748e083406a2e20037017a1292079ad6a8161ae5b43f398724fea74"}, - {"cipi_NA", "036cc1d7476e4260601927be0fc8b748ae68d8fec8f5c498f71569a01bd92046c5"}, - {"computergenie_EU", "03a8c071036228e0900e0171f616ce1a58f0a761193551d68c4c20e70534f2e183"}, - {"computergenie_NA", "03a78ae070a5e9e935112cf7ea8293f18950f1011694ea0260799e8762c8a6f0a4"}, // 20 - {"dimxy_AR", "02689d0b77b1e8e8c93a102d8b689fd08179164d70e2dd585543c3896a0916e6a1"}, - {"dimxy_DEV", "039a01cd626d5efbe7fd05a59d8e5fced53bacac589192278f9b00ad31654b6956"}, - {"dragonhound_NA", "02e650819f4d1cabeaad6bc5ec8c0722a89e63059a10f8b5e97c983c321608329b"}, - {"fediakash_AR", "027dfe5403f8870fb0e1b94a2b4204373b31ea73179ba500a88dd56d22855cd03b"}, - {"gcharang_DEV", "033b82b5791c65477dd11095cf33332013df6d2bcb7aa06a6dae5f7b22b6959b0b"}, - {"gcharang_SH", "02cb445948bf0d89f8d61102e12a5ee6e98be61ac7c2cb9ba435219ea9db967117"}, - {"goldenman_AR", "02c11f651df6a03f1a17b9ea0b1a73c0acca7aeacd4081e09bd7dd939690af8ae1"}, - {"kolo_AR", "028431645f923a9e383a4e37cbb7168fa34988da23d43097124fe882bdac6d175f"}, - {"kolo_EU", "03e1287d4c14ad73ce9ddd31361a7de8df4eeeefe9460a1ff9a6b2a1242ad3b7c2"}, - {"kolox_AR", "0289f5f64f4bb18d014c4e9f4c888f4da2b6518e88fd5b7768728c38177b66d305"}, // 30 - {"komodopioneers_EU", "0351f7f2a6ecce863e4e774bfafe2e59e151c08bf8f350286763a6b8ed97274b82"}, - {"madmax_DEV", "027100e6b3db2028034db651946ecde90e45be3799ebc310d39af4496772a850ad"}, - {"marmarachain_EU", "0234e40800500370d43979586ee2cec2e777a0368d10c682e78bca30fd1630c18d"}, - {"mcrypt_AR", "029bdb33b08f96524082490f4373bc6026b92bcaef9bc521a840a799c73b75ed80"}, - {"mcrypt_SH", "025faab3cc2e83bf7dad6a9463cbff86c08800e937942126f258cf219bc2320043"}, - {"metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309"}, - {"mylo_NA", "0365a778014c216401b6ba9c28eec88f116a9a9912e145ba2dbbd065d98b493af5"}, - {"mylo_SH", "03458dca36e800d5bc121d8c0d35f9fc6282880a79fee2d7e050f887b797bc7d6e"}, - {"nodeone_NA", "03f9dd0484e81174fd50775cb9099691c7d140ff00c0f088847e38dc87da67eb9b"}, - {"nutellalicka_AR", "0285be2518bf8d65fceaa5f4d8485002f90d3b7ff274b23bb925fd167128e19589"}, // 40 - {"nutellalicka_SH", "03a8b10c1f74af429fc43ab4eb722f6c2a88087f2d71703e7f0e8001207a966fb5"}, - {"ocean_AR", "03c2bc8c57a001a788851fedc33ce72797ee8fe26eaa3abb1b807727e4867a3105"}, - {"pbca26_NA", "03d8b25536da157d931b159a72c0eeaedb1bf7bb3eb2d02647fa41b2422a2b064e"}, - {"pbca26_SH", "039a55787b742c3725323f0bd81c90a484fbdbf276a16317883bb03eedd9d6aa7c"}, - {"phit_SH", "02a9cef2141fb2af24349c1eea20f5fa8f5dba2835723778d19b23353ddcd877b1"}, - {"ptyx_NA", "0395640e81359526ecbc140716ddd5c9a1ce2a697fb547ca896e17cad3c65e78db"}, - {"ptyx2_NA", "0225ff37e49e443065018736fbcad175ab5993b51b99b846e8de0b8b9abbed2ef2"}, - {"sheeba_SH", "03e6578015b7f0ab78a486070435031fff7bae11256ca6a9f3d358ab03029737cb"}, - {"smdmitry_AR", "022a2a45979a6631a25e4c96469423de720a2f4c849548957c35a35c91041ee7ac"}, - {"smdmitry_EU", "02eb3aad81778f8d6f7e5295c44ca224e5c812f5e43fc1e9ce4ebafc23324183c9"}, // 50 - {"smdmitry_SH", "02d01cd6b87cbf5a9795c06968f0d169168c1be0d82cfeb79958b11ae2c30316c1"}, - {"strob_SH", "025ceac4256cef83ca4b110f837a71d70a5a977ecfdf807335e00bc78b560d451a"}, - {"strobnidan_SH", "02b967fde3686d45056343e488997d4c53f25cd7ad38548cd12b136010a09295ae"}, - {"tokel_NA", "02b472713e87fb2560569857051ea0811c65d668a6fe73df165afe152417f774a0"}, - {"tonyl_AR", "029ad03929ec295e9164e2bfb9f0e0102c280d5e5212503d079d2d99ab492a9106"}, - {"tonyl_DEV", "02342ec82b31a016b71cd1eb2f482a74f63172e1029ba2fb18f0def3bd4fc0668a"}, - {"van_EU", "03af7f8c82f20671ca1978116353839d3e501523e379bfb52b1e05d7816bb5812f"}, - {"webworker01_EU", "0321d523645caffd8e762764ba56f7874a61b9bf534837a2cb6e7da219fab15eef"}, - {"webworker01_NA", "0287883ddd8da366401893ebcc1ff7e52d2ad3736984120a0ab01603e02c21dc98"}, - {"who-biz_NA", "02f91a6772fe1a376e2bbe4b190008e3f878d40a8eaf92c65f1a7680b6b42ea47b"}, // 60 - {"yurii-khi_DEV", "03e57c7341d2c8a3be62e1caaa28978d76a8277dea7bb484fdd8c55dc05e4e4e93"}, - {"ca333_EU", "021d6fbe67d12f492a01306c70ab096f8b8581eb5f958d3f5fe3588ae8c7797f42"}, - {"dragonhound_DEV", "038e010c33c56b61389409eea5597fe17967398731e23185c84c472a16fc5d34ab"} - } -}; - extern char NOTARYADDRS[64][64]; -extern char NOTARY_ADDRESSES[NUM_KMD_SEASONS][64][64]; \ No newline at end of file +extern char NOTARY_ADDRESSES[NUM_KMD_SEASONS][64][64]; + +extern const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2]; diff --git a/src/komodo_interest.cpp b/src/komodo_interest.cpp index 12b2570e..361a7cc4 100644 --- a/src/komodo_interest.cpp +++ b/src/komodo_interest.cpp @@ -13,182 +13,222 @@ * * ******************************************************************************/ #include "komodo_interest.h" +#include "komodo_bitcoind.h" +#include "komodo_utils.h" // dstr() -#ifdef notanymore -uint64_t komodo_earned_interest(int32_t height,int64_t paidinterest) -{ - static uint64_t *interests; static int32_t maxheight; - uint64_t total; int32_t ind,incr = 10000; - // need to make interests persistent before 2030, or just hardfork interest/mining rewards disable after MAX_MONEY is exceeded - return(0); - if ( height >= maxheight ) - { - if ( interests == 0 ) - { - maxheight = height + incr; - interests = (uint64_t *)calloc(maxheight,sizeof(*interests) * 2); - } - else - { - interests = (uint64_t *)realloc(interests,(maxheight + incr) * sizeof(*interests) * 2); - memset(&interests[maxheight << 1],0,incr * sizeof(*interests) * 2); - maxheight += incr; - } - } - ind = (height << 1); - if ( paidinterest < 0 ) // request - { - return(interests[ind]); - } - else - { - if ( interests[ind + 1] != paidinterest ) // need to handle skips like at 80000 - { - //LogPrintf("interests.%d %.8f %.8f vs paidinterest %.8f\n",height,dstr(interests[ind]),dstr(interests[ind+1]),dstr(paidinterest)); - interests[ind + 1] = paidinterest; - if ( height <= 1 ) - interests[ind] = 0; - else interests[ind] = interests[ind - 2] + interests[ind - 1]; - total = interests[ind] + paidinterest; - //LogPrintf("reset interests[height.%d to maxheight.%d] <- %.8f\n",height,maxheight,dstr(total)); - for (++height; height= LOCKTIME_THRESHOLD && tiptime > nLockTime && (minutes= (tiptime - nLockTime) / 60) >= (KOMODO_MAXMEMPOOLTIME/60) ) + int32_t minutes; + if ( nLockTime >= LOCKTIME_THRESHOLD + && tiptime > nLockTime + && (minutes= (tiptime - nLockTime) / 60) >= (KOMODO_MAXMEMPOOLTIME/60) ) { if ( minutes > 365 * 24 * 60 ) minutes = 365 * 24 * 60; if ( txheight >= 1000000 && minutes > 31 * 24 * 60 ) minutes = 31 * 24 * 60; minutes -= ((KOMODO_MAXMEMPOOLTIME/60) - 1); - interest = ((nValue / 10512000) * minutes); + return (nValue / 10512000) * minutes; } - return(interest); + return 0; } +/**** + * @brief evidently a new way to calculate interest + * @param txheight + * @param nValue + * @param nLockTime + * @param tiptime + * @return interest calculated + */ uint64_t komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime) { - uint64_t interest = 0; - if ( txheight < KOMODO_ENDOFERA && nLockTime >= LOCKTIME_THRESHOLD && tiptime != 0 && nLockTime < tiptime && nValue >= 10*COIN ) //komodo_moneysupply(txheight) < MAX_MONEY && - interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); - return(interest); + if ( txheight < KOMODO_ENDOFERA + && nLockTime >= LOCKTIME_THRESHOLD + && tiptime != 0 + && nLockTime < tiptime + && nValue >= 10*COIN ) + return _komodo_interestnew(txheight,nValue,nLockTime,tiptime); + return 0; } +/**** + * @brief calculate interest + * @param txheight + * @param nValue + * @param nLockTime + * @param tiptime + * @returns the interest + */ uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime) { int32_t minutes,exception; uint64_t interestnew,numerator,denominator,interest = 0; uint32_t activation; activation = 1491350400; // 1491350400 5th April - if ( ASSETCHAINS_SYMBOL[0] != 0 ) + if ( !chainName.isKMD() ) return(0); if ( txheight >= KOMODO_ENDOFERA ) - return(0); - if ( nLockTime >= LOCKTIME_THRESHOLD && tiptime != 0 && nLockTime < tiptime && nValue >= 10*COIN ) //komodo_moneysupply(txheight) < MAX_MONEY && + return 0; + + if ( nLockTime >= LOCKTIME_THRESHOLD && tiptime != 0 && nLockTime < tiptime && nValue >= 10*COIN ) { - if ( (minutes= (tiptime - nLockTime) / 60) >= 60 ) + int32_t minutes = (tiptime - nLockTime) / 60; + if ( minutes >= 60 ) { if ( minutes > 365 * 24 * 60 ) minutes = 365 * 24 * 60; if ( txheight >= 250000 ) minutes -= 59; - denominator = (((uint64_t)365 * 24 * 60) / minutes); + uint64_t denominator = (((uint64_t)365 * 24 * 60) / minutes); if ( denominator == 0 ) denominator = 1; // max KOMODO_INTEREST per transfer, do it at least annually! if ( nValue > 25000LL*COIN ) { - exception = 0; + bool exception = false; if ( txheight <= 155949 ) { if ( (txheight == 116607 && nValue == 2502721100000LL) || - (txheight == 126891 && nValue == 2879650000000LL) || - (txheight == 129510 && nValue == 3000000000000LL) || - (txheight == 141549 && nValue == 3500000000000LL) || - (txheight == 154473 && nValue == 3983399350000LL) || - (txheight == 154736 && nValue == 3983406748175LL) || - (txheight == 155013 && nValue == 3983414006565LL) || - (txheight == 155492 && nValue == 3983427592291LL) || - (txheight == 155613 && nValue == 9997409999999797LL) || - (txheight == 157927 && nValue == 9997410667451072LL) || - (txheight == 155613 && nValue == 2590000000000LL) || - (txheight == 155949 && nValue == 4000000000000LL) ) - exception = 1; - if ( exception == 0 || nValue == 4000000000000LL ) - LogPrintf(">>>>>>>>>>>> exception.%d txheight.%d %.8f locktime %u vs tiptime %u <<<<<<<<<\n",exception,txheight,(double)nValue/COIN,nLockTime,tiptime); + (txheight == 126891 && nValue == 2879650000000LL) || + (txheight == 129510 && nValue == 3000000000000LL) || + (txheight == 141549 && nValue == 3500000000000LL) || + (txheight == 154473 && nValue == 3983399350000LL) || + (txheight == 154736 && nValue == 3983406748175LL) || + (txheight == 155013 && nValue == 3983414006565LL) || + (txheight == 155492 && nValue == 3983427592291LL) || + (txheight == 155613 && nValue == 9997409999999797LL) || + (txheight == 157927 && nValue == 9997410667451072LL) || + (txheight == 155613 && nValue == 2590000000000LL) || + (txheight == 155949 && nValue == 4000000000000LL) ) + { + exception = true; + } + if ( exception || nValue == 4000000000000LL ) + LogPrintf(">>>>>>>>>>>> exception.%d txheight.%d %.8f locktime %u vs tiptime %u <<<<<<<<<\n",(int32_t)exception,txheight,(double)nValue/COIN,nLockTime,tiptime); } - //if ( nValue == 4000000000000LL ) - // LogPrintf(">>>>>>>>>>>> exception.%d txheight.%d %.8f locktime %u vs tiptime %u <<<<<<<<<\n",exception,txheight,(double)nValue/COIN,nLockTime,tiptime); - if ( exception == 0 ) + if ( !exception ) { - numerator = (nValue / 20); // assumes 5%! + uint64_t numerator = (nValue / 20); // assumes 5%! if ( txheight < 250000 ) interest = (numerator / denominator); else if ( txheight < 1000000 ) { interest = (numerator * minutes) / ((uint64_t)365 * 24 * 60); - interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); + uint64_t interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); if ( interest < interestnew ) - LogPrintf("pathA current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime); + LogPrintf("pathA current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n", + dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime); } - else interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); + else + interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); } else if ( txheight < 1000000 ) { - numerator = (nValue * KOMODO_INTEREST); + uint64_t numerator = (nValue * KOMODO_INTEREST); interest = (numerator / denominator) / COIN; - interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); + uint64_t interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); if ( interest < interestnew ) LogPrintf("pathB current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime); } - else interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); + else + interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); } else { - /* 250000 algo - numerator = (nValue * KOMODO_INTEREST); - if ( txheight < 250000 || numerator * minutes < 365 * 24 * 60 ) - interest = (numerator / denominator) / COIN; - else interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60)) / COIN; - */ - numerator = (nValue * KOMODO_INTEREST); + uint64_t numerator = (nValue * KOMODO_INTEREST); if ( txheight < 250000 || tiptime < activation ) { if ( txheight < 250000 || numerator * minutes < 365 * 24 * 60 ) interest = (numerator / denominator) / COIN; - else interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60)) / COIN; + else + interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60)) / COIN; } else if ( txheight < 1000000 ) { - numerator = (nValue / 20); // assumes 5%! + uint64_t numerator = (nValue / 20); // assumes 5%! interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60)); - //LogPrintf("interest %llu %.8f <- numerator.%llu minutes.%d\n",(long long)interest,(double)interest/COIN,(long long)numerator,(int32_t)minutes); - interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); + uint64_t interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); if ( interest < interestnew ) LogPrintf("pathC current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime); } - else interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); + else + interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime); } - if ( 0 && numerator == (nValue * KOMODO_INTEREST) ) - LogPrintf("komodo_interest.%d %lld %.8f nLockTime.%u tiptime.%u minutes.%d interest %lld %.8f (%llu / %llu) prod.%llu\n",txheight,(long long)nValue,(double)nValue/COIN,nLockTime,tiptime,minutes,(long long)interest,(double)interest/COIN,(long long)numerator,(long long)denominator,(long long)(numerator * minutes)); } } - return(interest); -} \ No newline at end of file + return interest; +} + +/**** + * @brief get information needed for interest calculation from a particular tx + * @param txheighttimep time of block + * @param txheightp height of block + * @param tiptimep time of tip + * @param valuep value of out at n + * @param hash the transaction hash + * @param n the vout to look for + * @returns locktime + */ +uint32_t komodo_interest_args(uint32_t *txheighttimep,int32_t *txheightp,uint32_t *tiptimep,uint64_t *valuep, + uint256 hash,int32_t n) +{ + *txheighttimep = *txheightp = *tiptimep = 0; + *valuep = 0; + + LOCK(cs_main); + CTransaction tx; + uint256 hashBlock; + if ( !GetTransaction(hash,tx,hashBlock,true) ) + return(0); + uint32_t locktime = 0; + if ( n < tx.vout.size() ) + { + CBlockIndex *pindex = komodo_getblockindex(hashBlock); + if ( pindex != nullptr ) + { + *valuep = tx.vout[n].nValue; + *txheightp = pindex->nHeight; + *txheighttimep = pindex->nTime; + CBlockIndex *tipindex; + if ( *tiptimep == 0 && (tipindex= chainActive.Tip()) != 0 ) + *tiptimep = (uint32_t)tipindex->nTime; + locktime = tx.nLockTime; + } + } + return(locktime); +} + +/**** + * @brief get accrued interest + * @param[out] txheightp + * @param[out] locktimep + * @param[in] hash + * @param[in] n + * @param[in] checkheight + * @param[in] checkvalue + * @param[in] tipheight + * @return the interest calculated + */ +uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n, + int32_t checkheight,uint64_t checkvalue,int32_t tipheight) +{ + uint32_t tiptime=0; + CBlockIndex *pindex = chainActive[tipheight]; + if ( pindex != nullptr ) + tiptime = (uint32_t)pindex->nTime; + else + LogPrintf("cant find height[%d]\n",tipheight); + + uint32_t txheighttimep; + uint64_t value; + *locktimep = komodo_interest_args(&txheighttimep, txheightp, &tiptime, &value, hash, n); + if ( *locktimep != 0 ) + { + if ( (checkvalue == 0 || value == checkvalue) && (checkheight == 0 || *txheightp == checkheight) ) + return komodo_interest(*txheightp,value,*locktimep,tiptime); + else + LogPrintf("komodo_accrued_interest value mismatch %llu vs %llu or height mismatch %d vs %d\n",(long long)value,(long long)checkvalue,*txheightp,checkheight); + } + return 0; +} + diff --git a/src/komodo_interest.h b/src/komodo_interest.h index 255141ab..24fc8c76 100644 --- a/src/komodo_interest.h +++ b/src/komodo_interest.h @@ -12,24 +12,42 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ +#include "uint256.h" +#include -#include "komodo_defs.h" - -#define SATOSHIDEN ((uint64_t)100000000L) -#define dstr(x) ((double)(x) / SATOSHIDEN) - +// each era of this many blocks reduces block reward from 3 to 2 to 1 #define KOMODO_ENDOFERA 7777777 -#define KOMODO_INTEREST ((uint64_t)5000000) //((uint64_t)(0.05 * COIN)) // 5% -extern int64_t MAX_MONEY; -extern uint8_t NOTARY_PUBKEY33[]; - -#ifdef notanymore -uint64_t komodo_earned_interest(int32_t height,int64_t paidinterest); -uint64_t komodo_moneysupply(int32_t height); -#endif - -uint64_t _komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); +/**** + * @brief evidently a new way to calculate interest + * @param txheight + * @param nValue + * @param nLockTime + * @param tiptime + * @return interest calculated + */ uint64_t komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); +/**** + * @brief calculate interest + * @param txheight + * @param nValue + * @param nLockTime + * @param tiptime + * @returns the interest + */ uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); + +/**** + * @brief get accrued interest + * @param[out] txheightp + * @param[out] locktimep + * @param[in] hash + * @param[in] n + * @param[in] checkheight + * @param[in] checkvalue + * @param[in] tipheight + * @return the interest calculated + */ +uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n, + int32_t checkheight,uint64_t checkvalue,int32_t tipheight); diff --git a/src/komodo_jumblr.cpp b/src/komodo_jumblr.cpp deleted file mode 100644 index 1663edc3..00000000 --- a/src/komodo_jumblr.cpp +++ /dev/null @@ -1,763 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ -#include "komodo_jumblr.h" -#include "komodo_extern_globals.h" -#include "komodo_bitcoind.h" // komodo_issuemethod -#include "komodo_utils.h" // clonestr -#include "komodo_curve25519.h" // OS_randombytes - -char Jumblr_secretaddrs[JUMBLR_MAXSECRETADDRS][64],Jumblr_deposit[64]; -int32_t Jumblr_numsecretaddrs; // if 0 -> run silent mode -struct jumblr_item *Jumblrs; // variable Jumblrs should be visible only in .cpp, not in .h - -char *jumblr_issuemethod(char *userpass,char *method,char *params,uint16_t port) -{ - cJSON *retjson,*resjson = 0; char *retstr; - if ( (retstr= komodo_issuemethod(userpass,method,params,port)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( jobj(retjson,(char *)"result") != 0 ) - resjson = jduplicate(jobj(retjson,(char *)"result")); - else if ( jobj(retjson,(char *)"error") != 0 ) - resjson = jduplicate(jobj(retjson,(char *)"error")); - else - { - resjson = cJSON_CreateObject(); - jaddstr(resjson,(char *)"error",(char *)"cant parse return"); - } - free_json(retjson); - } - free(retstr); - } - if ( resjson != 0 ) - return(jprint(resjson,1)); - else return(clonestr((char *)"{\"error\":\"unknown error\"}")); -} - -char *jumblr_importaddress(char *address) -{ - char params[1024]; - sprintf(params,"[\"%s\", \"%s\", false]",address,address); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"importaddress",params,BITCOIND_RPCPORT)); -} - -char *jumblr_validateaddress(char *addr) -{ - char params[1024]; - sprintf(params,"[\"%s\"]",addr); - LogPrintf("validateaddress.%s\n",params); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"validateaddress",params,BITCOIND_RPCPORT)); -} - -int32_t Jumblr_secretaddrfind(char *searchaddr) -{ - int32_t i; - for (i=0; i 0 ) - { - OS_randombytes((uint8_t *)&r,sizeof(r)); - r %= Jumblr_numsecretaddrs; - safecopy(secretaddr,Jumblr_secretaddrs[r],64); - } - return(r); -} - -int32_t jumblr_addresstype(char *addr) -{ - if ( addr[0] == '"' && addr[strlen(addr)-1] == '"' ) - { - addr[strlen(addr)-1] = 0; - addr++; - } - if ( addr[0] == 'z' && addr[1] == 'c' && strlen(addr) >= 40 ) - return('z'); - else if ( strlen(addr) < 40 ) - return('t'); - LogPrintf("strange.(%s)\n",addr); - return(-1); -} - -struct jumblr_item *jumblr_opidfind(char *opid) -{ - struct jumblr_item *ptr; - HASH_FIND(hh,Jumblrs,opid,(int32_t)strlen(opid),ptr); - return(ptr); -} - -struct jumblr_item *jumblr_opidadd(char *opid) -{ - struct jumblr_item *ptr = 0; - if ( opid != 0 && (ptr= jumblr_opidfind(opid)) == 0 ) - { - ptr = (struct jumblr_item *)calloc(1,sizeof(*ptr)); - safecopy(ptr->opid,opid,sizeof(ptr->opid)); - HASH_ADD_KEYPTR(hh,Jumblrs,ptr->opid,(int32_t)strlen(ptr->opid),ptr); - if ( ptr != jumblr_opidfind(opid) ) - LogPrintf("jumblr_opidadd.(%s) ERROR, couldnt find after add\n",opid); - } - return(ptr); -} - -char *jumblr_zgetnewaddress() -{ - char params[1024]; - sprintf(params,"[]"); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getnewaddress",params,BITCOIND_RPCPORT)); -} - -char *jumblr_zlistoperationids() -{ - char params[1024]; - sprintf(params,"[]"); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listoperationids",params,BITCOIND_RPCPORT)); -} - -char *jumblr_zgetoperationresult(char *opid) -{ - char params[1024]; - sprintf(params,"[[\"%s\"]]",opid); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationresult",params,BITCOIND_RPCPORT)); -} - -char *jumblr_zgetoperationstatus(char *opid) -{ - char params[1024]; - sprintf(params,"[[\"%s\"]]",opid); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationstatus",params,BITCOIND_RPCPORT)); -} - -char *jumblr_sendt_to_z(char *taddr,char *zaddr,double amount) -{ - char params[1024]; double fee = ((amount-3*JUMBLR_TXFEE) * JUMBLR_FEE) * 1.5; - if ( jumblr_addresstype(zaddr) != 'z' || jumblr_addresstype(taddr) != 't' ) - return(clonestr((char *)"{\"error\":\"illegal address in t to z\"}")); - sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",taddr,zaddr,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); - LogPrintf("t -> z: %s\n",params); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_RPCPORT)); -} - -char *jumblr_sendz_to_z(char *zaddrS,char *zaddrD,double amount) -{ - char params[1024]; double fee = (amount-2*JUMBLR_TXFEE) * JUMBLR_FEE; - if ( jumblr_addresstype(zaddrS) != 'z' || jumblr_addresstype(zaddrD) != 'z' ) - return(clonestr((char *)"{\"error\":\"illegal address in z to z\"}")); - //sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddrS,zaddrD,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); - sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddrS,zaddrD,amount-fee-JUMBLR_TXFEE,JUMBLR_TXFEE); - LogPrintf("z -> z: %s\n",params); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_RPCPORT)); -} - -char *jumblr_sendz_to_t(char *zaddr,char *taddr,double amount) -{ - char params[1024]; double fee = ((amount-JUMBLR_TXFEE) * JUMBLR_FEE) * 1.5; - if ( jumblr_addresstype(zaddr) != 'z' || jumblr_addresstype(taddr) != 't' ) - return(clonestr((char *)"{\"error\":\"illegal address in z to t\"}")); - sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddr,taddr,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); - LogPrintf("z -> t: %s\n",params); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_RPCPORT)); -} - -char *jumblr_zlistaddresses() -{ - char params[1024]; - sprintf(params,"[]"); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listaddresses",params,BITCOIND_RPCPORT)); -} - -char *jumblr_zlistreceivedbyaddress(char *addr) -{ - char params[1024]; - sprintf(params,"[\"%s\", 1]",addr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listreceivedbyaddress",params,BITCOIND_RPCPORT)); -} - -char *jumblr_getreceivedbyaddress(char *addr) -{ - char params[1024]; - sprintf(params,"[\"%s\", 1]",addr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"getreceivedbyaddress",params,BITCOIND_RPCPORT)); -} - -char *jumblr_importprivkey(char *wifstr) -{ - char params[1024]; - sprintf(params,"[\"%s\", \"\", false]",wifstr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"importprivkey",params,BITCOIND_RPCPORT)); -} - -char *jumblr_zgetbalance(char *addr) -{ - char params[1024]; - sprintf(params,"[\"%s\", 1]",addr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getbalance",params,BITCOIND_RPCPORT)); -} - -char *jumblr_listunspent(char *coinaddr) -{ - char params[1024]; - sprintf(params,"[1, 99999999, [\"%s\"]]",coinaddr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"listunspent",params,BITCOIND_RPCPORT)); -} - -char *jumblr_gettransaction(char *txidstr) -{ - char params[1024]; - sprintf(params,"[\"%s\", 1]",txidstr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"getrawtransaction",params,BITCOIND_RPCPORT)); -} - -int32_t jumblr_numvins(bits256 txid) -{ - char txidstr[65],params[1024],*retstr; cJSON *retjson,*vins; int32_t n,numvins = -1; - bits256_str(txidstr,txid); - if ( (retstr= jumblr_gettransaction(txidstr)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( jobj(retjson,(char *)"vin") != 0 && ((vins= jarray(&n,retjson,(char *)"vin")) == 0 || n == 0) ) - { - numvins = n; - //LogPrintf("numvins.%d\n",n); - } //else LogPrintf("no vin.(%s)\n",retstr); - free_json(retjson); - } - free(retstr); - } - return(numvins); -} - -int64_t jumblr_receivedby(char *addr) -{ - char *retstr; int64_t total = 0; - if ( (retstr= jumblr_getreceivedbyaddress(addr)) != 0 ) - { - total = atof(retstr) * SATOSHIDEN; - free(retstr); - } - return(total); -} - -int64_t jumblr_balance(char *addr) -{ - char *retstr; double val; int64_t balance = 0; //cJSON *retjson; int32_t i,n; - /*if ( jumblr_addresstype(addr) == 't' ) - { - if ( (retstr= jumblr_listunspent(addr)) != 0 ) - { - //LogPrintf("jumblr.[%s].(%s)\n","KMD",retstr); - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (n= cJSON_GetArraySize(retjson)) > 0 && cJSON_IsArray(retjson) != 0 ) - for (i=0; i SMALLVAL ) - balance = val * SATOSHIDEN; - free(retstr); - } - return(balance); -} - -int32_t jumblr_itemset(struct jumblr_item *ptr,cJSON *item,char *status) -{ - cJSON *params,*amounts,*dest; char *from,*addr; int32_t i,n; int64_t amount; - /*"params" : { - "fromaddress" : "RDhEGYScNQYetCyG75Kf8Fg61UWPdwc1C5", - "amounts" : [ - { - "address" : "zc9s3UdkDFTnnwHrMCr1vYy2WmkjhmTxXNiqC42s7BjeKBVUwk766TTSsrRPKfnX31Bbu8wbrTqnjDqskYGwx48FZMPHvft", - "amount" : 3.00000000 - } - ], - "minconf" : 1, - "fee" : 0.00010000 - }*/ - if ( (params= jobj(item,(char *)"params")) != 0 ) - { - //LogPrintf("params.(%s)\n",jprint(params,0)); - if ( (from= jstr(params,(char *)"fromaddress")) != 0 ) - { - safecopy(ptr->src,from,sizeof(ptr->src)); - } - if ( (amounts= jarray(&n,params,(char *)"amounts")) != 0 ) - { - for (i=0; i 0 ) - { - if ( strcmp(addr,JUMBLR_ADDR) == 0 ) - ptr->fee = amount; - else - { - ptr->amount = amount; - safecopy(ptr->dest,addr,sizeof(ptr->dest)); - } - } - } - } - ptr->txfee = jdouble(params,(char *)"fee") * SATOSHIDEN; - } - return(1); -} - -void jumblr_opidupdate(struct jumblr_item *ptr) -{ - char *retstr,*status; cJSON *retjson,*item; - if ( ptr->status == 0 ) - { - if ( (retstr= jumblr_zgetoperationstatus(ptr->opid)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( cJSON_GetArraySize(retjson) == 1 && cJSON_IsArray(retjson) != 0 ) - { - item = jitem(retjson,0); - //LogPrintf("%s\n",jprint(item,0)); - if ( (status= jstr(item,(char *)"status")) != 0 ) - { - if ( strcmp(status,(char *)"success") == 0 ) - { - ptr->status = jumblr_itemset(ptr,item,status); - if ( (jumblr_addresstype(ptr->src) == 't' && jumblr_addresstype(ptr->src) == 'z' && strcmp(ptr->src,Jumblr_deposit) != 0) || (jumblr_addresstype(ptr->src) == 'z' && jumblr_addresstype(ptr->src) == 't' && Jumblr_secretaddrfind(ptr->dest) < 0) ) - { - LogPrintf("a non-jumblr t->z pruned\n"); - free(jumblr_zgetoperationresult(ptr->opid)); - ptr->status = -1; - } - - } - else if ( strcmp(status,(char *)"failed") == 0 ) - { - LogPrintf("jumblr_opidupdate %s failed\n",ptr->opid); - free(jumblr_zgetoperationresult(ptr->opid)); - ptr->status = -1; - } - } - } - free_json(retjson); - } - free(retstr); - } - } -} - -void jumblr_prune(struct jumblr_item *ptr) -{ - struct jumblr_item *tmp; char oldsrc[128]; int32_t flag = 1; - if ( is_hexstr(ptr->opid,0) == 64 ) - return; - LogPrintf("jumblr_prune %s\n",ptr->opid); - strcpy(oldsrc,ptr->src); - free(jumblr_zgetoperationresult(ptr->opid)); - while ( flag != 0 ) - { - flag = 0; - HASH_ITER(hh,Jumblrs,ptr,tmp) - { - if ( strcmp(oldsrc,ptr->dest) == 0 ) - { - if ( is_hexstr(ptr->opid,0) != 64 ) - { - LogPrintf("jumblr_prune %s (%s -> %s) matched oldsrc\n",ptr->opid,ptr->src,ptr->dest); - free(jumblr_zgetoperationresult(ptr->opid)); - strcpy(oldsrc,ptr->src); - flag = 1; - break; - } - } - } - } -} - - -bits256 jbits256(cJSON *json,char *field); - - -void jumblr_zaddrinit(char *zaddr) -{ - struct jumblr_item *ptr; char *retstr,*totalstr; cJSON *item,*array; double total; bits256 txid; char txidstr[65],t_z,z_z; - if ( (totalstr= jumblr_zgetbalance(zaddr)) != 0 ) - { - if ( (total= atof(totalstr)) > SMALLVAL ) - { - if ( (retstr= jumblr_zlistreceivedbyaddress(zaddr)) != 0 ) - { - if ( (array= cJSON_Parse(retstr)) != 0 ) - { - t_z = z_z = 0; - if ( cJSON_GetArraySize(array) == 1 && cJSON_IsArray(array) != 0 ) - { - item = jitem(array,0); - if ( (uint64_t)((total+0.0000000049) * SATOSHIDEN) == (uint64_t)((jdouble(item,(char *)"amount")+0.0000000049) * SATOSHIDEN) ) - { - txid = jbits256(item,(char *)"txid"); - bits256_str(txidstr,txid); - if ( (ptr= jumblr_opidadd(txidstr)) != 0 ) - { - ptr->amount = (total * SATOSHIDEN); - ptr->status = 1; - strcpy(ptr->dest,zaddr); - if ( jumblr_addresstype(ptr->dest) != 'z' ) - LogPrintf("error setting dest type to Z: %s\n",jprint(item,0)); - if ( jumblr_numvins(txid) == 0 ) - { - z_z = 1; - strcpy(ptr->src,zaddr); - ptr->src[3] = '0'; - ptr->src[4] = '0'; - ptr->src[5] = '0'; - if ( jumblr_addresstype(ptr->src) != 'z' ) - LogPrintf("error setting address type to Z: %s\n",jprint(item,0)); - } - else - { - t_z = 1; - strcpy(ptr->src,"taddr"); - if ( jumblr_addresstype(ptr->src) != 't' ) - LogPrintf("error setting address type to T: %s\n",jprint(item,0)); - } - LogPrintf("%s %s %.8f t_z.%d z_z.%d\n",zaddr,txidstr,total,t_z,z_z); // cant be z->t from spend - } - } else LogPrintf("mismatched %s %s total %.8f vs %.8f -> %lld\n",zaddr,totalstr,dstr(SATOSHIDEN * total),dstr(SATOSHIDEN * jdouble(item,(char *)"amount")),(long long)((uint64_t)(total * SATOSHIDEN) - (uint64_t)(jdouble(item,(char *)"amount") * SATOSHIDEN))); - } - free_json(array); - } - free(retstr); - } - } - free(totalstr); - } -} - -void jumblr_opidsupdate() -{ - char *retstr; cJSON *array; int32_t i,n; struct jumblr_item *ptr; - if ( (retstr= jumblr_zlistoperationids()) != 0 ) - { - if ( (array= cJSON_Parse(retstr)) != 0 ) - { - if ( (n= cJSON_GetArraySize(array)) > 0 && cJSON_IsArray(array) != 0 ) - { - //LogPrintf("%s -> n%d\n",retstr,n); - for (i=0; istatus == 0 ) - jumblr_opidupdate(ptr); - //LogPrintf("%d: %s -> %s %.8f\n",ptr->status,ptr->src,ptr->dest,dstr(ptr->amount)); - if ( jumblr_addresstype(ptr->src) == 'z' && jumblr_addresstype(ptr->dest) == 't' ) - jumblr_prune(ptr); - } - } - } - free_json(array); - } - free(retstr); - } -} - -uint64_t jumblr_increment(uint8_t r,int32_t height,uint64_t total,uint64_t biggest,uint64_t medium, uint64_t smallest) -{ - int32_t i,n; uint64_t incrs[1000],remains = total; - height /= JUMBLR_SYNCHRONIZED_BLOCKS; - if ( (height % JUMBLR_SYNCHRONIZED_BLOCKS) == 0 || total >= 100*biggest ) - { - if ( total >= biggest ) - return(biggest); - else if ( total >= medium ) - return(medium); - else if ( total >= smallest ) - return(smallest); - else return(0); - } - else - { - n = 0; - while ( remains > smallest && n < sizeof(incrs)/sizeof(*incrs) ) - { - if ( remains >= biggest ) - incrs[n] = biggest; - else if ( remains >= medium ) - incrs[n] = medium; - else if ( remains >= smallest ) - incrs[n] = smallest; - else break; - remains -= incrs[n]; - n++; - } - if ( n > 0 ) - { - r %= n; - for (i=0; i %.8f\n",n,r,dstr(incrs[r])); - return(incrs[r]); - } - } - return(0); -} - -void jumblr_iteration() -{ - static int32_t lastheight; static uint32_t lasttime; - char *zaddr,*addr,*retstr=0,secretaddr[64]; cJSON *array; int32_t i,iter,height,acpublic,counter,chosen_one,n; uint64_t smallest,medium,biggest,amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint16_t r,s; - acpublic = ASSETCHAINS_PUBLIC; - if ( ASSETCHAINS_SYMBOL[0] == 0 && GetTime() >= KOMODO_SAPLING_DEADLINE ) - acpublic = 1; - if ( JUMBLR_PAUSE != 0 || acpublic != 0 ) - return; - if ( lasttime == 0 ) - { - if ( (retstr= jumblr_zlistaddresses()) != 0 ) - { - if ( (array= cJSON_Parse(retstr)) != 0 ) - { - if ( (n= cJSON_GetArraySize(array)) > 0 && cJSON_IsArray(array) != 0 ) - { - for (i=0; inHeight; - if ( time(NULL) < lasttime+40 ) - return; - lasttime = (uint32_t)time(NULL); - if ( lastheight == height ) - return; - lastheight = height; - if ( (height % JUMBLR_SYNCHRONIZED_BLOCKS) != JUMBLR_SYNCHRONIZED_BLOCKS-3 ) - return; - fee = JUMBLR_INCR * JUMBLR_FEE; - smallest = SATOSHIDEN * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE); - medium = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE); - biggest = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*777 + 3*JUMBLR_TXFEE); - OS_randombytes((uint8_t *)&r,sizeof(r)); - s = (r % 3); - //LogPrintf("jumblr_iteration r.%u s.%u\n",r,s); - switch ( s ) - { - case 0: // t -> z - default: - if ( Jumblr_deposit[0] != 0 && (total= jumblr_balance(Jumblr_deposit)) >= smallest ) - { - if ( (zaddr= jumblr_zgetnewaddress()) != 0 ) - { - if ( zaddr[0] == '"' && zaddr[strlen(zaddr)-1] == '"' ) - { - zaddr[strlen(zaddr)-1] = 0; - addr = zaddr+1; - } else addr = zaddr; - amount = jumblr_increment(r/3,height,total,biggest,medium,smallest); - /* - amount = 0; - if ( (height % (JUMBLR_SYNCHRONIZED_BLOCKS*JUMBLR_SYNCHRONIZED_BLOCKS)) == 0 && total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE) ) - amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE); - else if ( (r & 3) == 0 && total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE) ) - amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE); - else amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE);*/ - if ( amount > 0 && (retstr= jumblr_sendt_to_z(Jumblr_deposit,addr,dstr(amount))) != 0 ) - { - LogPrintf("sendt_to_z.(%s)\n",retstr); - free(retstr), retstr = 0; - } - free(zaddr); - } else LogPrintf("no zaddr from jumblr_zgetnewaddress\n"); - } - else if ( Jumblr_deposit[0] != 0 ) - LogPrintf("%s total %.8f vs %.8f\n",Jumblr_deposit,dstr(total),(JUMBLR_INCR + 3*(fee+JUMBLR_TXFEE))); - break; - case 1: // z -> z - jumblr_opidsupdate(); - chosen_one = -1; - for (iter=counter=0; iter<2; iter++) - { - counter = n = 0; - HASH_ITER(hh,Jumblrs,ptr,tmp) - { - if ( ptr->spent == 0 && ptr->status > 0 && jumblr_addresstype(ptr->src) == 't' && jumblr_addresstype(ptr->dest) == 'z' ) - { - if ( (total= jumblr_balance(ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) - { - if ( iter == 1 && counter == chosen_one ) - { - if ( (zaddr= jumblr_zgetnewaddress()) != 0 ) - { - if ( zaddr[0] == '"' && zaddr[strlen(zaddr)-1] == '"' ) - { - zaddr[strlen(zaddr)-1] = 0; - addr = zaddr+1; - } else addr = zaddr; - if ( (retstr= jumblr_sendz_to_z(ptr->dest,addr,dstr(total))) != 0 ) - { - LogPrintf("n.%d counter.%d chosen_one.%d send z_to_z.(%s)\n",n,counter,chosen_one,retstr); - free(retstr), retstr = 0; - } - ptr->spent = (uint32_t)time(NULL); - free(zaddr); - break; - } - } - counter++; - } - } - n++; - } - if ( counter == 0 ) - break; - if ( iter == 0 ) - { - OS_randombytes((uint8_t *)&chosen_one,sizeof(chosen_one)); - if ( chosen_one < 0 ) - chosen_one = -chosen_one; - chosen_one %= counter; - LogPrintf("jumblr z->z chosen_one.%d of %d, from %d\n",chosen_one,counter,n); - } - } - break; - case 2: // z -> t - if ( Jumblr_numsecretaddrs > 0 ) - { - jumblr_opidsupdate(); - chosen_one = -1; - for (iter=0; iter<2; iter++) - { - counter = n = 0; - HASH_ITER(hh,Jumblrs,ptr,tmp) - { - //LogPrintf("status.%d %c %c %.8f\n",ptr->status,jumblr_addresstype(ptr->src),jumblr_addresstype(ptr->dest),dstr(ptr->amount)); - if ( ptr->spent == 0 && ptr->status > 0 && jumblr_addresstype(ptr->src) == 'z' && jumblr_addresstype(ptr->dest) == 'z' ) - { - if ( (total= jumblr_balance(ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) - { - if ( iter == 1 && counter == chosen_one ) - { - Jumblr_secretaddr(secretaddr); - if ( (retstr= jumblr_sendz_to_t(ptr->dest,secretaddr,dstr(total))) != 0 ) - { - LogPrintf("%s send z_to_t.(%s)\n",secretaddr,retstr); - free(retstr), retstr = 0; - } else LogPrintf("null return from jumblr_sendz_to_t\n"); - ptr->spent = (uint32_t)time(NULL); - break; - } - counter++; - } //else LogPrintf("z->t spent.%u total %.8f error\n",ptr->spent,dstr(total)); - } - n++; - } - if ( counter == 0 ) - break; - if ( iter == 0 ) - { - OS_randombytes((uint8_t *)&chosen_one,sizeof(chosen_one)); - if ( chosen_one < 0 ) - chosen_one = -chosen_one; - chosen_one %= counter; - LogPrintf("jumblr z->t chosen_one.%d of %d, from %d\n",chosen_one,counter,n); - } //else LogPrintf("n.%d counter.%d chosen.%d\n",n,counter,chosen_one); - } - } - break; - } -} diff --git a/src/komodo_jumblr.h b/src/komodo_jumblr.h deleted file mode 100644 index 0ddd99b3..00000000 --- a/src/komodo_jumblr.h +++ /dev/null @@ -1,112 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ -#pragma once -#include "uthash.h" // UT_hash_handle -#include "komodo_cJSON.h" -#include "komodo_defs.h" - -#ifdef _WIN32 -#include -#endif - -#define JUMBLR_ADDR "RGhxXpXSSBTBm9EvNsXnTQczthMCxHX91t" -#define JUMBLR_BTCADDR "18RmTJe9qMech8siuhYfMtHo8RtcN1obC6" -#define JUMBLR_MAXSECRETADDRS 777 -#define JUMBLR_SYNCHRONIZED_BLOCKS 10 -#define JUMBLR_INCR 9.965 -#define JUMBLR_FEE 0.001 -#define JUMBLR_TXFEE 0.01 -#define SMALLVAL 0.000000000000001 - -#define JUMBLR_ERROR_DUPLICATEDEPOSIT -1 -#define JUMBLR_ERROR_SECRETCANTBEDEPOSIT -2 -#define JUMBLR_ERROR_TOOMANYSECRETS -3 -#define JUMBLR_ERROR_NOTINWALLET -4 - -struct jumblr_item -{ - UT_hash_handle hh; - int64_t amount,fee,txfee; // fee and txfee not really used (yet) - uint32_t spent,pad; - char opid[66],src[128],dest[128],status; -}; - -char *jumblr_issuemethod(char *userpass,char *method,char *params,uint16_t port); - -char *jumblr_importaddress(char *address); - -char *jumblr_validateaddress(char *addr); - -int32_t Jumblr_secretaddrfind(char *searchaddr); - -int32_t Jumblr_secretaddradd(char *secretaddr); // external - -int32_t Jumblr_depositaddradd(char *depositaddr); // external - -int32_t Jumblr_secretaddr(char *secretaddr); - -int32_t jumblr_addresstype(char *addr); - -struct jumblr_item *jumblr_opidfind(char *opid); - -struct jumblr_item *jumblr_opidadd(char *opid); - -char *jumblr_zgetnewaddress(); - -char *jumblr_zlistoperationids(); - -char *jumblr_zgetoperationresult(char *opid); - -char *jumblr_zgetoperationstatus(char *opid); - -char *jumblr_sendt_to_z(char *taddr,char *zaddr,double amount); - -char *jumblr_sendz_to_z(char *zaddrS,char *zaddrD,double amount); - -char *jumblr_sendz_to_t(char *zaddr,char *taddr,double amount); - -char *jumblr_zlistaddresses(); - -char *jumblr_zlistreceivedbyaddress(char *addr); - -char *jumblr_getreceivedbyaddress(char *addr); - -char *jumblr_importprivkey(char *wifstr); - -char *jumblr_zgetbalance(char *addr); - -char *jumblr_listunspent(char *coinaddr); - -char *jumblr_gettransaction(char *txidstr); - -int32_t jumblr_numvins(bits256 txid); - -int64_t jumblr_receivedby(char *addr); - -int64_t jumblr_balance(char *addr); - -int32_t jumblr_itemset(struct jumblr_item *ptr,cJSON *item,char *status); - -void jumblr_opidupdate(struct jumblr_item *ptr); - -void jumblr_prune(struct jumblr_item *ptr); - -void jumblr_zaddrinit(char *zaddr); - -void jumblr_opidsupdate(); - -uint64_t jumblr_increment(uint8_t r,int32_t height,uint64_t total,uint64_t biggest,uint64_t medium, uint64_t smallest); - -void jumblr_iteration(); diff --git a/src/komodo_kv.cpp b/src/komodo_kv.cpp index f8a6c4df..d0dafb5f 100644 --- a/src/komodo_kv.cpp +++ b/src/komodo_kv.cpp @@ -13,21 +13,98 @@ * * ******************************************************************************/ #include "komodo_kv.h" -#include "komodo_extern_globals.h" +#include "komodo_globals.h" #include "komodo_utils.h" // portable_mutex_lock -#include "komodo_curve25519.h" // komodo_kvsigverify +#include "komodo_curve25519.h" // for komodo_kvsigverify +#include -int32_t komodo_kvcmp(uint8_t *refvalue,uint16_t refvaluesize,uint8_t *value,uint16_t valuesize) +std::mutex kv_mutex; + +struct komodo_kv +{ + UT_hash_handle hh; + bits256 pubkey; + uint8_t *key; + uint8_t *value; + int32_t height; + uint32_t flags; + uint16_t keylen; + uint16_t valuesize; +}; + +komodo_kv *KOMODO_KV; + +/**** + * @brief build a private key from the public key and passphrase + * @param pubkeyp the public key + * @param passphrase the passphrase + * @return a private key + */ +uint256 komodo_kvprivkey(uint256 *pubkeyp,char *passphrase) +{ + uint256 privkey; + conv_NXTpassword((uint8_t *)&privkey,(uint8_t *)pubkeyp,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + return privkey; +} + +/**** + * @brief sign + * @param buf what to sign + * @param len the length of buf + * @param _privkey the key to sign with + */ +uint256 komodo_kvsig(uint8_t *buf,int32_t len,uint256 _privkey) { - if ( refvalue == 0 && value == 0 ) - return(0); - else if ( refvalue == 0 || value == 0 ) - return(-1); - else if ( refvaluesize != valuesize ) - return(-1); - else return(memcmp(refvalue,value,valuesize)); + // get the private key in the format we need + bits256 privkey; + memcpy(&privkey,&_privkey,sizeof(privkey)); + // hash the contents of buf + bits256 hash; + vcalc_sha256(0,hash.bytes,buf,len); + bits256 otherpub = curve25519(hash,curve25519_basepoint9()); + bits256 pubkey = curve25519(privkey,curve25519_basepoint9()); + bits256 sig = curve25519_shared(privkey,otherpub); + bits256 checksig = curve25519_shared(hash,pubkey); // is this needed? + uint256 usig; + memcpy(&usig,&sig,sizeof(usig)); + return usig; +} + +/**** + * @brief verify the signature + * @param buf the message + * @param len the length of the message + * @param _pubkey who signed + * @param sig the signature + * @return -1 on error, otherwise 0 + */ +int32_t komodo_kvsigverify(uint8_t *buf,int32_t len,uint256 _pubkey,uint256 sig) +{ + bits256 hash; + bits256 checksig; + + static uint256 zeroes; + if (_pubkey == zeroes) + return -1; + + // get the public key in the right format + bits256 pubkey; + memcpy(&pubkey,&_pubkey,sizeof(pubkey)); + + // validate the signature + vcalc_sha256(0,hash.bytes,buf,len); + checksig = curve25519_shared(hash,pubkey); + if ( memcmp(&checksig,&sig,sizeof(sig)) != 0 ) + return -1; + + return 0; } +/*** + * @brief get duration from flags + * @param flags + * @returns duration in days + */ int32_t komodo_kvnumdays(uint32_t flags) { int32_t numdays; @@ -36,11 +113,23 @@ int32_t komodo_kvnumdays(uint32_t flags) return(numdays); } +/*** + * @brief calculate the duration in minutes + * @param flags + * @return the duration + */ int32_t komodo_kvduration(uint32_t flags) { return(komodo_kvnumdays(flags) * KOMODO_KVDURATION); } +/*** + * @brief calculate the required fee + * @param flags + * @param opretlen + * @param keylen + * @return the fee + */ uint64_t komodo_kvfee(uint32_t flags,int32_t opretlen,int32_t keylen) { int32_t numdays,k; uint64_t fee; @@ -52,20 +141,35 @@ uint64_t komodo_kvfee(uint32_t flags,int32_t opretlen,int32_t keylen) return(fee); } -int32_t komodo_kvsearch(uint256 *pubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen) +/*** + * @brief find a value + * @param[out] pubkeyp the found pubkey + * @param current_height current chain height + * @param[out] flagsp flags found within the value + * @param[out] heightp height + * @param[out] value the value + * @param key the key + * @param keylen the length of the key + * @return -1 on error, otherwise size of value + */ +int32_t komodo_kvsearch(uint256 *pubkeyp, int32_t current_height, uint32_t *flagsp, + int32_t *heightp, uint8_t value[IGUANA_MAXSCRIPTSIZE], uint8_t *key, int32_t keylen) { - struct komodo_kv *ptr; int32_t duration,retval = -1; *heightp = -1; *flagsp = 0; + + komodo_kv *ptr; + int32_t retval = -1; memset(pubkeyp,0,sizeof(*pubkeyp)); - portable_mutex_lock(&KOMODO_KV_mutex); + std::lock_guard lock(kv_mutex); + // look in hashtable for key HASH_FIND(hh,KOMODO_KV,key,keylen,ptr); - if ( ptr != 0 ) + if ( ptr != nullptr ) { - duration = komodo_kvduration(ptr->flags); - //LogPrintf("duration.%d flags.%d current.%d ht.%d keylen.%d valuesize.%d\n",duration,ptr->flags,current_height,ptr->height,ptr->keylen,ptr->valuesize); + int32_t duration = komodo_kvduration(ptr->flags); if ( current_height > (ptr->height + duration) ) { + // entry has expired, remove it HASH_DELETE(hh,KOMODO_KV,ptr); if ( ptr->value != 0 ) free(ptr->value); @@ -75,38 +179,48 @@ int32_t komodo_kvsearch(uint256 *pubkeyp,int32_t current_height,uint32_t *flagsp } else { + // place values into parameters *heightp = ptr->height; *flagsp = ptr->flags; - int32_t i; for (i=0; i<32; i++) + for (int32_t i=0; i<32; i++) { - //printf("%02x",((uint8_t *)&ptr->pubkey)[31-i]); ((uint8_t *)pubkeyp)[i] = ((uint8_t *)&ptr->pubkey)[31-i]; } - //printf(" ptr->pubkey\n"); memcpy(pubkeyp,&ptr->pubkey,sizeof(*pubkeyp)); if ( (retval= ptr->valuesize) > 0 ) memcpy(value,ptr->value,retval); } - } //else LogPrintf("couldnt find (%s)\n",(char *)key); - portable_mutex_unlock(&KOMODO_KV_mutex); + } if ( retval < 0 ) { // search rawmempool } - return(retval); + return retval; } +/**** + * @brief update value + * @param opretbuf what to write + * @param opretlen length of opretbuf + * @param value the value to be related to the key + */ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value) { static uint256 zeroes; - uint32_t flags; uint256 pubkey,refpubkey,sig; int32_t i,refvaluesize,hassig,coresize,haspubkey,height,kvheight; uint16_t keylen,valuesize,newflag = 0; uint8_t *key,*valueptr,keyvalue[IGUANA_MAXSCRIPTSIZE*8]; struct komodo_kv *ptr; char *transferpubstr,*tstr; uint64_t fee; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) // disable KV for KMD + + if (chainName.isKMD()) // disable KV for KMD return; + + // parse opretbuf + uint16_t keylen; + uint16_t valuesize; + int32_t height; + uint32_t flags; iguana_rwnum(0,&opretbuf[1],sizeof(keylen),&keylen); iguana_rwnum(0,&opretbuf[3],sizeof(valuesize),&valuesize); iguana_rwnum(0,&opretbuf[5],sizeof(height),&height); iguana_rwnum(0,&opretbuf[9],sizeof(flags),&flags); - key = &opretbuf[13]; + uint8_t *key = &opretbuf[13]; if ( keylen+13 > opretlen ) { static uint32_t counter; @@ -114,85 +228,104 @@ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value) LogPrintf("komodo_kvupdate: keylen.%d + 13 > opretlen.%d, this can be ignored\n",keylen,opretlen); return; } - valueptr = &key[keylen]; - fee = komodo_kvfee(flags,opretlen,keylen); - //LogPrintf("fee %.8f vs %.8f flags.%d keylen.%d valuesize.%d height.%d (%02x %02x %02x) (%02x %02x %02x)\n",(double)fee/COIN,(double)value/COIN,flags,keylen,valuesize,height,key[0],key[1],key[2],valueptr[0],valueptr[1],valueptr[2]); + uint8_t *valueptr = &key[keylen]; + uint64_t fee = komodo_kvfee(flags,opretlen,keylen); if ( value >= fee ) { - coresize = (int32_t)(sizeof(flags)+sizeof(height)+sizeof(keylen)+sizeof(valuesize)+keylen+valuesize+1); - if ( opretlen == coresize || opretlen == coresize+sizeof(uint256) || opretlen == coresize+2*sizeof(uint256) ) + // we have enough for the fee + int32_t coresize = (int32_t)(sizeof(flags) + +sizeof(height) + +sizeof(keylen) + +sizeof(valuesize) + +keylen+valuesize+1); + uint256 pubkey; + if ( opretlen == coresize + || opretlen == coresize+sizeof(uint256) + || opretlen == coresize+2*sizeof(uint256) ) { - memset(&pubkey,0,sizeof(pubkey)); - memset(&sig,0,sizeof(sig)); - if ( (haspubkey= (opretlen >= coresize+sizeof(uint256))) != 0 ) + // end could be pubkey or pubkey+signature + if ( opretlen >= coresize+sizeof(uint256) ) { - for (i=0; i<32; i++) + for (uint8_t i=0; i<32; i++) ((uint8_t *)&pubkey)[i] = opretbuf[coresize+i]; } - if ( (hassig= (opretlen == coresize+sizeof(uint256)*2)) != 0 ) + uint256 sig; + if ( opretlen == coresize+sizeof(uint256)*2 ) { - for (i=0; i<32; i++) + for (uint8_t i=0; i<32; i++) ((uint8_t *)&sig)[i] = opretbuf[coresize+sizeof(uint256)+i]; } + + uint8_t keyvalue[IGUANA_MAXSCRIPTSIZE*8]; memcpy(keyvalue,key,keylen); - if ( (refvaluesize= komodo_kvsearch((uint256 *)&refpubkey,height,&flags,&kvheight,&keyvalue[keylen],key,keylen)) >= 0 ) + uint256 refpubkey; + int32_t kvheight; + int32_t refvaluesize = komodo_kvsearch(&refpubkey,height, + &flags,&kvheight,&keyvalue[keylen],key,keylen); + if ( refvaluesize >= 0 ) { - if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 ) + if ( zeroes != refpubkey ) { + // validate signature if ( komodo_kvsigverify(keyvalue,keylen+refvaluesize,refpubkey,sig) < 0 ) { - //LogPrintf("komodo_kvsigverify error [%d]\n",coresize-13); return; } } } - portable_mutex_lock(&KOMODO_KV_mutex); + // with validation complete, update internal storage + std::lock_guard lock(kv_mutex); + komodo_kv *ptr; + bool newflag = false; HASH_FIND(hh,KOMODO_KV,key,keylen,ptr); if ( ptr != 0 ) { - //LogPrintf("(%s) already there\n",(char *)key); - //if ( (ptr->flags & KOMODO_KVPROTECTED) != 0 ) + // We are updating an existing entry + // if we are doing a transfer, log it and insert the pubkey + char *tstr = (char *)"transfer:"; + char *transferpubstr = (char *)&valueptr[strlen(tstr)]; + if ( strncmp(tstr,(char *)valueptr,strlen(tstr)) == 0 && is_hexstr(transferpubstr,0) == 64 ) { - tstr = (char *)"transfer:"; - transferpubstr = (char *)&valueptr[strlen(tstr)]; - if ( strncmp(tstr,(char *)valueptr,strlen(tstr)) == 0 && is_hexstr(transferpubstr,0) == 64 ) - { - LogPrintf("transfer.(%s) to [%s]? ishex.%d\n",key,transferpubstr,is_hexstr(transferpubstr,0)); - for (i=0; i<32; i++) - ((uint8_t *)&pubkey)[31-i] = _decode_hex(&transferpubstr[i*2]); - } + LogPrintf("transfer.(%s) to [%s]? ishex.%d\n",key,transferpubstr,is_hexstr(transferpubstr,0)); + for (uint8_t i=0; i<32; i++) + ((uint8_t *)&pubkey)[31-i] = _decode_hex(&transferpubstr[i*2]); } } else if ( ptr == 0 ) { - ptr = (struct komodo_kv *)calloc(1,sizeof(*ptr)); + // add a new entry to the hashtable + ptr = (komodo_kv *)calloc(1,sizeof(*ptr)); ptr->key = (uint8_t *)calloc(1,keylen); ptr->keylen = keylen; memcpy(ptr->key,key,keylen); - newflag = 1; + newflag = true; HASH_ADD_KEYPTR(hh,KOMODO_KV,ptr->key,ptr->keylen,ptr); - //LogPrintf("KV add.(%s) (%s)\n",ptr->key,valueptr); } - if ( newflag != 0 || (ptr->flags & KOMODO_KVPROTECTED) == 0 ) + if ( newflag || (ptr->flags & KOMODO_KVPROTECTED) == 0 ) // can we edit the value? { - if ( ptr->value != 0 ) - free(ptr->value), ptr->value = 0; + if ( ptr->value != nullptr ) + { + // clear out old value + free(ptr->value); + ptr->value = nullptr; + } if ( (ptr->valuesize= valuesize) != 0 ) { + // add value ptr->value = (uint8_t *)calloc(1,valuesize); memcpy(ptr->value,valueptr,valuesize); } - } else LogPrintf("newflag.%d zero or protected %d\n",newflag,(ptr->flags & KOMODO_KVPROTECTED)); - /*for (i=0; i<32; i++) - LogPrintf("%02x",((uint8_t *)&ptr->pubkey)[i]); - LogPrintf(" <- "); - for (i=0; i<32; i++) - LogPrintf("%02x",((uint8_t *)&pubkey)[i]); - LogPrintf(" new pubkey\n");*/ + } + else + LogPrintf("newflag.%d zero or protected %d\n",(uint16_t)newflag, + (ptr->flags & KOMODO_KVPROTECTED)); memcpy(&ptr->pubkey,&pubkey,sizeof(ptr->pubkey)); ptr->height = height; ptr->flags = flags; // jl777 used to or in KVPROTECTED - portable_mutex_unlock(&KOMODO_KV_mutex); - } else LogPrintf("KV update size mismatch %d vs %d\n",opretlen,coresize); - } else LogPrintf("not enough fee\n"); + } + else + LogPrintf("KV update size mismatch %d vs %d\n",opretlen,coresize); + } + else + LogPrintf("not enough fee\n"); } diff --git a/src/komodo_kv.h b/src/komodo_kv.h index 0a320994..c6cdf491 100644 --- a/src/komodo_kv.h +++ b/src/komodo_kv.h @@ -12,25 +12,71 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ - #pragma once -// #ifndef H_KOMODOKV_H -// #define H_KOMODOKV_H - +#include "uint256.h" #include "komodo_defs.h" -#include "hex.h" - -int32_t komodo_kvcmp(uint8_t *refvalue,uint16_t refvaluesize,uint8_t *value,uint16_t valuesize); - -int32_t komodo_kvnumdays(uint32_t flags); +#include +/*** + * @brief calculate the duration in minutes + * @param flags + * @return the duration + */ int32_t komodo_kvduration(uint32_t flags); +/*** + * @brief calculate the required fee + * @param flags + * @param opretlen + * @param keylen + * @return the fee + */ uint64_t komodo_kvfee(uint32_t flags,int32_t opretlen,int32_t keylen); -int32_t komodo_kvsearch(uint256 *pubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); +/*** + * @brief find a value + * @param[out] pubkeyp the found pubkey + * @param current_height current chain height + * @param[out] flagsp flags found within the value + * @param[out] heightp height + * @param[out] value the value + * @param key the key + * @param keylen the length of the key + * @return -1 on error, otherwise size of value + */ +int32_t komodo_kvsearch(uint256 *pubkeyp,int32_t current_height,uint32_t *flagsp, + int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); +/**** + * @brief update value + * @param opretbuf what to write + * @param opretlen length of opretbuf + * @param value the value to be related to the key + */ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value); +/**** + * @brief build a private key from the public key and passphrase + * @param pubkeyp the public key + * @param passphrase the passphrase + * @return a private key + */ +uint256 komodo_kvprivkey(uint256 *pubkeyp,char *passphrase); + +/**** + * @brief sign + * @param buf what to sign + * @param len the length of buf + * @param _privkey the key to sign with + */ +uint256 komodo_kvsig(uint8_t *buf,int32_t len,uint256 _privkey); -// #endif +/**** + * @brief verify the signature + * @param buf the message + * @param len the length of the message + * @param _pubkey who signed + * @param sig the signature + * @return -1 on error, otherwise 0 + */ +int32_t komodo_kvsigverify(uint8_t *buf,int32_t len,uint256 _pubkey,uint256 sig); diff --git a/src/komodo_nSPV.h b/src/komodo_nSPV.h index 9aaa18ce..42ae4fe7 100644 --- a/src/komodo_nSPV.h +++ b/src/komodo_nSPV.h @@ -441,8 +441,10 @@ int32_t NSPV_rwremoterpcresp(int32_t rwflag,uint8_t *serialized,struct NSPV_remo void NSPV_remoterpc_purge(struct NSPV_remoterpcresp *ptr) { - if ( ptr != 0 ) + if ( ptr != 0 ) { + if (ptr->json) free (ptr->json); memset(ptr,0,sizeof(*ptr)); + } } // useful utility functions @@ -559,7 +561,7 @@ int32_t NSPV_notariescount(CTransaction tx,uint8_t elected[64][33]) return(numsigs); } -uint256 NSPV_opretextract(int32_t *heightp,uint256 *blockhashp,char *symbol,std::vector opret,uint256 txid) +uint256 NSPV_opretextract(int32_t *heightp,uint256 *blockhashp,const char *symbol,std::vector opret,uint256 txid) { uint256 desttxid; int32_t i; iguana_rwnum(0,&opret[32],sizeof(*heightp),heightp); @@ -574,15 +576,14 @@ uint256 NSPV_opretextract(int32_t *heightp,uint256 *blockhashp,char *symbol,std: int32_t NSPV_notarizationextract(int32_t verifyntz,int32_t *ntzheightp,uint256 *blockhashp,uint256 *desttxidp,CTransaction tx) { - int32_t numsigs=0; uint8_t elected[64][33]; char *symbol; std::vector opret; uint32_t nTime; + int32_t numsigs=0; uint8_t elected[64][33]; std::vector opret; uint32_t nTime; if ( tx.vout.size() >= 2 ) { - symbol = (ASSETCHAINS_SYMBOL[0] == 0) ? (char *)"KMD" : ASSETCHAINS_SYMBOL; GetOpReturnData(tx.vout[1].scriptPubKey,opret); if ( opret.size() >= 32*2+4 ) { //sleep(1); // needed to avoid no pnodes error - *desttxidp = NSPV_opretextract(ntzheightp,blockhashp,symbol,opret,tx.GetHash()); + *desttxidp = NSPV_opretextract(ntzheightp,blockhashp,chainName.ToString().c_str(),opret,tx.GetHash()); nTime = NSPV_blocktime(*ntzheightp); komodo_notaries(elected,*ntzheightp,nTime); if ( verifyntz != 0 && (numsigs= NSPV_fastnotariescount(tx,elected,nTime)) < 12 ) diff --git a/src/komodo_nSPV_defs.h b/src/komodo_nSPV_defs.h index 40d9dc02..307a29ea 100644 --- a/src/komodo_nSPV_defs.h +++ b/src/komodo_nSPV_defs.h @@ -22,7 +22,6 @@ #define NSPV_POLLMICROS 50000 #define NSPV_MAXVINS 64 #define NSPV_AUTOLOGOUT 777 -#define NSPV_BRANCHID 0x76b809bb // nSPV defines and struct definitions with serialization and purge functions @@ -55,6 +54,16 @@ #define NSPV_REMOTERPC 0x14 #define NSPV_REMOTERPCRESP 0x15 +extern int32_t KOMODO_NSPV; + +#ifndef KOMODO_NSPV_FULLNODE +#define KOMODO_NSPV_FULLNODE (KOMODO_NSPV <= 0) +#endif + +#ifndef KOMODO_NSPV_SUPERLITE +#define KOMODO_NSPV_SUPERLITE (KOMODO_NSPV > 0) +#endif + int32_t NSPV_gettransaction(int32_t skipvalidation,int32_t vout,uint256 txid,int32_t height,CTransaction &tx,uint256 &hashblock,int32_t &txheight,int32_t ¤theight,int64_t extradata,uint32_t tiptime,int64_t &rewardsum); UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis); extern uint256 SIG_TXHASH; @@ -185,8 +194,9 @@ struct NSPV_CCmtxinfo struct NSPV_remoterpcresp { + NSPV_remoterpcresp() { method[0] = '\0'; json = nullptr; } char method[64]; - char json[11000]; + char *json; }; #endif // KOMODO_NSPV_DEFSH diff --git a/src/komodo_nSPV_fullnode.h b/src/komodo_nSPV_fullnode.h index e778d31d..e134c4e4 100644 --- a/src/komodo_nSPV_fullnode.h +++ b/src/komodo_nSPV_fullnode.h @@ -21,6 +21,7 @@ #include "notarisationdb.h" #include "rpc/server.h" +#include "komodo_bitcoind.h" static std::map nspv_remote_commands = {{"channelsopen", true},{"channelspayment", true},{"channelsclose", true},{"channelsrefund", true}, {"channelslist", true},{"channelsinfo", true},{"oraclescreate", true},{"oraclesfund", true},{"oraclesregister", true},{"oraclessubscribe", true}, @@ -36,19 +37,19 @@ struct NSPV_ntzargs int32_t NSPV_notarization_find(struct NSPV_ntzargs *args,int32_t height,int32_t dir) { - int32_t ntzheight = 0; uint256 hashBlock; CTransaction tx; Notarisation nota; char *symbol; std::vector opret; - symbol = (ASSETCHAINS_SYMBOL[0] == 0) ? (char *)"KMD" : ASSETCHAINS_SYMBOL; + int32_t ntzheight = 0; uint256 hashBlock; CTransaction tx; Notarisation nota; + std::vector opret; memset(args,0,sizeof(*args)); if ( dir > 0 ) height += 10; - if ( (args->txidht= ScanNotarisationsDB(height,symbol,1440,nota)) == 0 ) + if ( (args->txidht= ScanNotarisationsDB(height,chainName.ToString(),1440,nota)) == 0 ) return(-1); args->txid = nota.first; if ( !GetTransaction(args->txid,tx,hashBlock,false) || tx.vout.size() < 2 ) return(-2); GetOpReturnData(tx.vout[1].scriptPubKey,opret); if ( opret.size() >= 32*2+4 ) - args->desttxid = NSPV_opretextract(&args->ntzheight,&args->blockhash,symbol,opret,args->txid); + args->desttxid = NSPV_opretextract(&args->ntzheight,&args->blockhash,chainName.ToString().c_str(),opret,args->txid); return(args->ntzheight); } @@ -185,7 +186,7 @@ int32_t NSPV_getaddressutxos(struct NSPV_utxosresp *ptr,char *coinaddr,bool isCC ptr->utxos[ind].vout = (int32_t)it->first.index; ptr->utxos[ind].satoshis = it->second.satoshis; ptr->utxos[ind].height = it->second.blockHeight; - if ( ASSETCHAINS_SYMBOL[0] == 0 && it->second.satoshis >= 10*COIN ) + if ( chainName.isKMD() && it->second.satoshis >= 10*COIN ) { ptr->utxos[n].extradata = komodo_accrued_interest(&txheight,&locktime,ptr->utxos[ind].txid,ptr->utxos[ind].vout,ptr->utxos[ind].height,ptr->utxos[ind].satoshis,tipheight); interest += ptr->utxos[ind].extradata; @@ -517,7 +518,7 @@ int32_t NSPV_mempoolfuncs(bits256 *satoshisp,int32_t *vindexp,std::vector> e; ss >> f; ss >> tmp_txid;); if (e!=eval || (txid!=zeroid && txid!=tmp_txid) || (func!=0 && f!=func)) continue; break; @@ -687,6 +688,9 @@ int32_t NSPV_remoterpc(struct NSPV_remoterpcresp *ptr,char *json,int n) { rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); response=rpc_result.write(); + ptr->json = (char*)malloc(response.size()); + if (ptr->json == nullptr) + throw JSONRPCError(RPC_OUT_OF_MEMORY, "Cannot allocate memory for response"); memcpy(ptr->json,response.c_str(),response.size()); len+=response.size(); return (len); @@ -708,6 +712,7 @@ int32_t NSPV_remoterpc(struct NSPV_remoterpcresp *ptr,char *json,int n) rpc_result = JSONRPCReplyObj(NullUniValue,JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); response=rpc_result.write(); } + ptr->json = (char*)malloc(response.size()); // only not a big size error responses are here memcpy(ptr->json,response.c_str(),response.size()); len+=response.size(); return (len); diff --git a/src/komodo_nSPV_superlite.h b/src/komodo_nSPV_superlite.h index 731dc4e9..72b0b957 100644 --- a/src/komodo_nSPV_superlite.h +++ b/src/komodo_nSPV_superlite.h @@ -23,7 +23,7 @@ CAmount AmountFromValue(const UniValue& value); -int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr); +int32_t bitcoin_base58decode(uint8_t *data,const char *coinaddr); uint32_t NSPV_lastinfo,NSPV_logintime,NSPV_tiptime; CKey NSPV_key; @@ -391,7 +391,7 @@ UniValue NSPV_utxoresp_json(struct NSPV_utxoresp *utxos,int32_t numutxos) item.push_back(Pair("txid",utxos[i].txid.GetHex())); item.push_back(Pair("vout",(int64_t)utxos[i].vout)); item.push_back(Pair("value",(double)utxos[i].satoshis/COIN)); - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) item.push_back(Pair("interest",(double)utxos[i].extradata/COIN)); array.push_back(item); } @@ -408,7 +408,7 @@ UniValue NSPV_utxosresp_json(struct NSPV_utxosresp *ptr) result.push_back(Pair("height",(int64_t)ptr->nodeheight)); result.push_back(Pair("numutxos",(int64_t)ptr->numutxos)); result.push_back(Pair("balance",(double)ptr->total/COIN)); - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) result.push_back(Pair("interest",(double)ptr->interest/COIN)); result.push_back(Pair("filter",(int64_t)ptr->filter)); result.push_back(Pair("lastpeer",NSPV_lastpeer)); diff --git a/src/komodo_nSPV_wallet.h b/src/komodo_nSPV_wallet.h index f38903bc..c23078df 100644 --- a/src/komodo_nSPV_wallet.h +++ b/src/komodo_nSPV_wallet.h @@ -17,8 +17,11 @@ #ifndef KOMODO_NSPVWALLET_H #define KOMODO_NSPVWALLET_H +#include "komodo_interest.h" + // nSPV wallet uses superlite functions (and some komodod built in functions) to implement nSPV_spend -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +#include "komodo_bitcoind.h" +#include "rpc/rawtransaction.h" int32_t NSPV_validatehdrs(struct NSPV_ntzsproofresp *ptr) { @@ -83,7 +86,7 @@ int32_t NSPV_gettransaction(int32_t skipvalidation,int32_t vout,uint256 txid,int retval = -2001; else if ( skipvalidation == 0 && ptr->unspentvalue <= 0 ) retval = -2002; - else if ( ASSETCHAINS_SYMBOL[0] == 0 && tiptime != 0 ) + else if ( chainName.isKMD() && tiptime != 0 ) { rewards = komodo_interestnew(height,tx.vout[vout].nValue,tx.nLockTime,tiptime); if ( rewards != extradata ) @@ -236,6 +239,8 @@ int64_t NSPV_addinputs(struct NSPV_utxoresp *used,CMutableTransaction &mtx,int64 return(0); } +#define NSPV_BRANCHID 0x76b809bb + bool NSPV_SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScript scriptPubKey,uint32_t nTime) { CTransaction txNewConst(mtx); SignatureData sigdata; CBasicKeyStore keystore; int64_t branchid = NSPV_BRANCHID; @@ -388,7 +393,7 @@ UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis) // what its a mtx.nExpiryHeight = 0; mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID; mtx.nVersion = SAPLING_TX_VERSION; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) { + if ( chainName.isKMD() ) { if ( !komodo_hardfork_active((uint32_t)chainActive.Tip()->nTime) ) mtx.nLockTime = (uint32_t)time(NULL) - 777; else @@ -407,7 +412,7 @@ UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis) // what its a return(result); } hex = NSPV_signtx(rewardsum,interestsum,retcodes,mtx,txfee,opret,used); - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) { char numstr[64]; sprintf(numstr,"%.8f",(double)interestsum/COIN); diff --git a/src/komodo_notary.cpp b/src/komodo_notary.cpp index 500ca7e1..d41b74b5 100644 --- a/src/komodo_notary.cpp +++ b/src/komodo_notary.cpp @@ -13,92 +13,135 @@ * * ******************************************************************************/ #include "komodo_notary.h" +#include "komodo_globals.h" #include "komodo_extern_globals.h" -//#include "komodo.h" // komodo_stateupdate() -//#include "komodo_structs.h" // KOMODO_NOTARIES_HARDCODED +#include "komodo.h" // komodo_stateupdate() +#include "komodo_structs.h" // KOMODO_NOTARIES_HARDCODED #include "komodo_utils.h" // komodo_stateptr +#include "komodo_bitcoind.h" -#include "hex.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 KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); +//struct knotaries_entry *Pubkeys; // todo remove + +// statics used within this .cpp for caching purposes +static int didinit; // see komodo_init +static uint8_t kmd_pubkeys[NUM_KMD_SEASONS][64][33]; // see komodo_notaries +static int32_t hwmheight; // highest height ever passed to komodo_notariesinit +static int32_t hadnotarization; // used in komodo_dpowconfs +static bool didinit_NOTARIES[NUM_KMD_SEASONS]; // komodo_notaries() -const char *Notaries_genesis[][2] = -{ - { "jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, - { "jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, - { "pondsea_SH", "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" }, - { "crackers_EU", "0340c66cf2c41c41efb420af57867baa765e8468c12aa996bfd816e1e07e410728" }, - { "pondsea_EU", "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" }, - { "locomb_EU", "025c6d26649b9d397e63323d96db42a9d3caad82e1d6076970efe5056c00c0779b" }, - { "fullmoon_AE", "0204a908350b8142698fdb6fabefc97fe0e04f537adc7522ba7a1e8f3bec003d4a" }, - { "movecrypto_EU", "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" }, - { "badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, - { "crackers_NA", "029e1c01131974f4cd3f564cc0c00eb87a0f9721043fbc1ca60f9bd0a1f73f64a1" }, - { "proto_EU", "03681ffdf17c8f4f0008cefb7fa0779c5e888339cdf932f0974483787a4d6747c1" }, // 10 - { "jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, - { "farl4web_EU", "035caa40684ace968677dca3f09098aa02b70e533da32390a7654c626e0cf908e1" }, - { "nxtswe_EU", "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" }, - { "traderbill_EU", "03196e8de3e2e5d872f31d79d6a859c8704a2198baf0af9c7b21e29656a7eb455f" }, - { "vanbreuk_EU", "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" }, // 15 - { "titomane_EU", "03517fcac101fed480ae4f2caf775560065957930d8c1facc83e30077e45bdd199" }, - { "supernet_AE", "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" }, - { "supernet_EU", "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" }, - { "supernet_NA", "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" }, - { "yassin_EU", "033fb7231bb66484081952890d9a03f91164fb27d392d9152ec41336b71b15fbd0" }, // 20 - { "durerus_EU", "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" }, - { "badass_SH", "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" }, - { "badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, - { "pondsea_NA", "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" }, - { "rnr_EU", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" }, - { "crackers_SH", "02313d72f9a16055737e14cfc528dcd5d0ef094cfce23d0348fe974b6b1a32e5f0" }, - { "grewal_SH", "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" }, - { "polycryptoblock_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, - { "titomane_NA", "0387046d9745414fb58a0fa3599078af5073e10347e4657ef7259a99cb4f10ad47" }, - { "titomane_AE", "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" }, - { "kolo_EU", "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" }, - { "artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, - { "eclips_EU", "0339369c1f5a2028d44be7be6f8ec3b907fdec814f87d2dead97cab4edb71a42e9" }, - { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, -}; +/**** + * @brief get the kmd season based on height (used on the KMD chain) + * @param height the chain height + * @returns the KMD season (returns 0 if the height is above the range) + */ int32_t getkmdseason(int32_t height) { if ( height <= KMD_SEASON_HEIGHTS[0] ) - return(1); + return 1; for (int32_t i = 1; i < NUM_KMD_SEASONS; i++) { if ( height <= KMD_SEASON_HEIGHTS[i] && height > KMD_SEASON_HEIGHTS[i-1] ) - return(i+1); + return i+1; } - return(0); + return 0; } +/**** + * @brief get the season based on timestamp (used for alternate chains) + * @param timestamp the time + * @returns the KMD season (returns 0 if timestamp is above the range) + */ int32_t getacseason(uint32_t timestamp) { if ( timestamp <= KMD_SEASON_TIMESTAMPS[0] ) - return(1); + return 1; for (int32_t i = 1; i < NUM_KMD_SEASONS; i++) { if ( timestamp <= KMD_SEASON_TIMESTAMPS[i] && timestamp > KMD_SEASON_TIMESTAMPS[i-1] ) - return(i+1); + return i+1; + } + return 0; +} + +/***** + * 2 Helpers for unit tests that reset statics (among other things) + * DO NOT USE for anything other than unit tests + */ +//void undo_init_STAKED(); // see notaries_staked.cpp +/*void undo_init_notaries() +{ + undo_init_STAKED(); + memset(didinit_notaries, 0, NUM_KMD_SEASONS * sizeof(bool) ); + if (Pubkeys != nullptr) + { + free(Pubkeys); + Pubkeys = nullptr; + } + hwmheight = 0; + didinit = false; +}*/ + +/**** + * Calculate the height index (how notaries are stored) based on the height + * @param height the height + * @returns the height index + */ +int32_t ht_index_from_height(int32_t height) +{ + int32_t htind = height / KOMODO_ELECTION_GAP; + if ( htind >= KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP ) + htind = (KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; + return htind; +} + + +//char NOTARY_ADDRESSES[NUM_KMD_SEASONS][64][64]; //todo remove + +// ARRR notary exception +int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime) // from ac_private chains only +{ + int32_t season = getacseason(tiptime); + if ( NOTARY_ADDRESSES[season-1][0][0] == 0 ) + { + uint8_t pubkeys[64][33]; + komodo_notaries(pubkeys,0,tiptime); + } + if ( strcmp(coinaddr,CRYPTO777_KMDADDR) == 0 ) + return(1); + for (int32_t i = 0; i < NUM_KMD_NOTARIES; i++) + { + if ( strcmp(coinaddr,NOTARY_ADDRESSES[season-1][i]) == 0 ) + { + //LogPrintf("coinaddr.%s notaryaddress[%i].%s\n",coinaddr,i,NOTARY_ADDRESSES[season-1][i]); + return(1); + } } return(0); } +/*** + * @brief Given a height or timestamp, get the appropriate notary keys + * @param[out] pubkeys the results + * @param[in] height the height + * @param[in] timestamp the timestamp + * @returns the number of notaries + */ int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp) { - int32_t i,htind,n; uint64_t mask = 0; struct knotary_entry *kp,*tmp; - static uint8_t kmd_pubkeys[NUM_KMD_SEASONS][64][33],didinit[NUM_KMD_SEASONS]; - - if ( timestamp == 0 && ASSETCHAINS_SYMBOL[0] != 0 ) - timestamp = komodo_heightstamp(height); - else if ( ASSETCHAINS_SYMBOL[0] == 0 ) - timestamp = 0; + // calculate timestamp if necessary (only height passed in and non-KMD chain) + // TODO: check if this logic changed okay + if ( chainName.isKMD() ) + timestamp = 0; // For KMD, we always use height + else if ( timestamp == 0 ) + timestamp = komodo_heightstamp(height); // derive the timestamp from the passed-in height - // If this chain is not a staked chain, use the normal Komodo logic to determine notaries. This allows KMD to still sync and use its proper pubkeys for dPoW. - if ( is_STAKED(ASSETCHAINS_SYMBOL) == 0 ) + // If this chain is not a staked chain, use the normal Komodo logic to determine notaries. + // This allows KMD to still sync and use its proper pubkeys for dPoW. + if ( is_STAKED(chainName.symbol()) == 0 ) { int32_t kmd_season = 0; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) { // This is KMD, use block heights to determine the KMD notary season.. if ( height >= KOMODO_NOTARIES_HARDCODED ) @@ -111,17 +154,17 @@ int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestam } if ( kmd_season != 0 ) { - if ( didinit[kmd_season-1] == 0 ) + if ( !didinit_NOTARIES[kmd_season-1] ) { - for (i=0; i= KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP ) - htind = (KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; - if ( Pubkeys == 0 ) + if ( Pubkeys == nullptr ) { komodo_init(height); - //LogPrintf("Pubkeys.%p htind.%d vs max.%d\n",Pubkeys,htind,KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP); } - pthread_mutex_lock(&komodo_mutex); - n = Pubkeys[htind].numnotaries; - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) - LogPrintf("%s height.%d t.%u genesis.%d\n",ASSETCHAINS_SYMBOL,height,timestamp,n); + int32_t htind = ht_index_from_height(height); + std::lock_guard lock(komodo_mutex); + int32_t n = Pubkeys[htind].numnotaries; + uint64_t mask = 0; + knotary_entry *kp; + knotary_entry *tmp; HASH_ITER(hh,Pubkeys[htind].Notaries,kp,tmp) { if ( kp->notaryid < n ) { mask |= (1LL << kp->notaryid); memcpy(pubkeys[kp->notaryid],kp->pubkey,33); - } else LogPrintf("illegal notaryid.%d vs n.%d\n",kp->notaryid,n); + } + else + LogPrintf("illegal notaryid.%d vs n.%d\n",kp->notaryid,n); } - pthread_mutex_unlock(&komodo_mutex); if ( (n < 64 && mask == ((1LL << n)-1)) || (n == 64 && mask == 0xffffffffffffffffLL) ) - return(n); + return n; LogPrintf("error retrieving notaries ht.%d got mask.%llx for n.%d\n",height,(long long)mask,n); - return(-1); + return -1; } int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp) @@ -180,62 +222,59 @@ int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t hei int32_t komodo_ratify_threshold(int32_t height,uint64_t signedmask) { - int32_t htind,numnotaries,i,wt = 0; - htind = height / KOMODO_ELECTION_GAP; - if ( htind >= KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP ) - htind = (KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; + int32_t numnotaries, i, wt = 0; + int32_t htind = ht_index_from_height(height); numnotaries = Pubkeys[htind].numnotaries; for (i=0; i (numnotaries >> 1) || (wt > 7 && (signedmask & 1) != 0) ) - return(1); - else return(0); + return 1; + return 0; } +/***** + * Push keys into the notary collection + * @param origheight the height where these notaries begin + * @param pubkeys the notaries' public keys + * @param num the number of keys in pubkeys + */ void komodo_notarysinit(int32_t origheight,uint8_t pubkeys[64][33],int32_t num) { - static int32_t hwmheight; - int32_t k,i,htind,height; struct knotary_entry *kp; struct knotaries_entry N; if ( Pubkeys == 0 ) - Pubkeys = (struct knotaries_entry *)calloc(1 + (KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP),sizeof(*Pubkeys)); + Pubkeys = (knotaries_entry *)calloc(1 + (KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP),sizeof(*Pubkeys)); + knotaries_entry N; memset(&N,0,sizeof(N)); + // calculate the height + int32_t htind = 0; // height index (number of elections so far) if ( origheight > 0 ) { - height = (origheight + KOMODO_ELECTION_GAP/2); + int32_t height = (origheight + KOMODO_ELECTION_GAP/2); height /= KOMODO_ELECTION_GAP; height = ((height + 1) * KOMODO_ELECTION_GAP); - htind = (height / KOMODO_ELECTION_GAP); - if ( htind >= KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP ) - htind = (KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; - //LogPrintf("htind.%d activation %d from %d vs %d | hwmheight.%d %s\n",htind,height,origheight,(((origheight+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,hwmheight,ASSETCHAINS_SYMBOL); - } else htind = 0; - pthread_mutex_lock(&komodo_mutex); - for (k=0; kpubkey,pubkeys[k],33); - kp->notaryid = k; - HASH_ADD_KEYPTR(hh,N.Notaries,kp->pubkey,33,kp); - if ( 0 && height > 10000 ) + std::lock_guard lock(komodo_mutex); + for (int32_t k=0; kpubkey,pubkeys[k],33); + kp->notaryid = k; + HASH_ADD_KEYPTR(hh,N.Notaries,kp->pubkey,33,kp); } - } - N.numnotaries = num; - for (i=htind; i hwmheight ) hwmheight = origheight; } @@ -243,14 +282,17 @@ void komodo_notarysinit(int32_t origheight,uint8_t pubkeys[64][33],int32_t num) int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp) { // -1 if not notary, 0 if notary, 1 if special notary - struct knotary_entry *kp; int32_t numnotaries=0,htind,modval = -1; + knotary_entry *kp; + int32_t numnotaries=0; + int32_t modval = -1; + *notaryidp = -1; if ( height < 0 )//|| height >= KOMODO_MAXBLOCKS ) { LogPrintf("komodo_chosennotary ht.%d illegal\n",height); return(-1); } - if ( height >= KOMODO_NOTARIES_HARDCODED || ASSETCHAINS_SYMBOL[0] != 0 ) + if ( height >= KOMODO_NOTARIES_HARDCODED || !chainName.isKMD() ) { if ( (*notaryidp= komodo_electednotary(&numnotaries,pubkey33,height,timestamp)) >= 0 && numnotaries != 0 ) { @@ -260,27 +302,25 @@ int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33, } if ( height >= 250000 ) return(-1); - if ( Pubkeys == 0 ) + if ( Pubkeys == nullptr ) komodo_init(0); - htind = height / KOMODO_ELECTION_GAP; - if ( htind >= KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP ) - htind = (KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; - pthread_mutex_lock(&komodo_mutex); - HASH_FIND(hh,Pubkeys[htind].Notaries,pubkey33,33,kp); - pthread_mutex_unlock(&komodo_mutex); - if ( kp != 0 ) + int32_t htind = ht_index_from_height(height); + { + std::lock_guard lock(komodo_mutex); + HASH_FIND(hh,Pubkeys[htind].Notaries,pubkey33,33,kp); + } + if ( kp != nullptr ) { if ( (numnotaries= Pubkeys[htind].numnotaries) > 0 ) { *notaryidp = kp->notaryid; modval = ((height % numnotaries) == kp->notaryid); - //LogPrintf("found notary.%d ht.%d modval.%d\n",kp->notaryid,height,modval); - } else LogPrintf("unexpected zero notaries at height.%d\n",height); - } //else LogPrintf("cant find kp at htind.%d ht.%d\n",htind,height); - //int32_t i; for (i=0; i<33; i++) - // LogPrintf("%02x",pubkey33[i]); - //LogPrintf(" ht.%d notary.%d special.%d htind.%d num.%d\n",height,*notaryidp,modval,htind,numnotaries); - return(modval); + } + else + LogPrintf("unexpected zero notaries at height.%d\n",height); + } + + return modval; } /****** @@ -437,35 +477,63 @@ void komodo_notarized_update(struct komodo_state *sp,int32_t nHeight,int32_t not new_cp.notarized_desttxid = notarized_desttxid; new_cp.MoM = MoM; new_cp.MoMdepth = MoMdepth; - portable_mutex_lock(&komodo_mutex); + std::lock_guard lock(komodo_mutex); sp->AddCheckpoint(new_cp); - portable_mutex_unlock(&komodo_mutex); } +/**** + * @brief Initialize genesis notaries into memory + * @note After a successful run, subsequent calls do nothing + * @param height the current height (not used other than to stop initialization if less than zero) + */ void komodo_init(int32_t height) { - static int didinit; uint256 zero; int32_t k,n; uint8_t pubkeys[64][33]; - if ( 0 && height != 0 ) - LogPrintf("komodo_init ht.%d didinit.%d\n",height,didinit); + uint256 zero; + uint8_t pubkeys[64][33]; memset(&zero,0,sizeof(zero)); - if ( didinit == 0 ) + if ( !didinit ) { - pthread_mutex_init(&komodo_mutex,NULL); decode_hex(NOTARY_PUBKEY33,33,NOTARY_PUBKEY.c_str()); if ( height >= 0 ) { - n = (int32_t)(sizeof(Notaries_genesis)/sizeof(*Notaries_genesis)); - for (k=0; k 0xffffffff ) - LogPrintf("Pval overflow error %lld\n",(long long)price.Pval); - else val32 = (uint32_t)price.Pval; - } - return(val32); - }*/ - int32_t PAX_pubkey(int32_t rwflag,uint8_t *pubkey33,uint8_t *addrtypep,uint8_t rmd160[20],char fiat[4],uint8_t *shortflagp,int64_t *fiatoshisp) { if ( rwflag != 0 ) @@ -312,14 +327,11 @@ void komodo_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals) KMDBTC = ((double)kmdbtc / (1000000000. * 1000.)); BTCUSD = PAX_BTCUSD(height,btcusd); CNYUSD = ((double)cnyusd / 1000000000.); - portable_mutex_lock(&komodo_mutex); + std::lock_guard lock(komodo_mutex); PVALS = (uint32_t *)realloc(PVALS,(NUM_PRICES+1) * sizeof(*PVALS) * 36); PVALS[36 * NUM_PRICES] = height; memcpy(&PVALS[36 * NUM_PRICES + 1],pvals,sizeof(*pvals) * 35); NUM_PRICES++; - portable_mutex_unlock(&komodo_mutex); - if ( 0 ) - LogPrintf("OP_RETURN.%d KMD %.8f BTC %.6f CNY %.6f NUM_PRICES.%d (%llu %llu %llu)\n",height,KMDBTC,BTCUSD,CNYUSD,NUM_PRICES,(long long)kmdbtc,(long long)btcusd,(long long)cnyusd); } } } @@ -467,7 +479,6 @@ uint64_t _komodo_paxprice(uint64_t *kmdbtcp,uint64_t *btcusdp,int32_t height,cha height -= 10; if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 ) { - //portable_mutex_lock(&komodo_mutex); for (i=NUM_PRICES-1; i>=0; i--) { ptr = &PVALS[36 * i]; @@ -479,13 +490,11 @@ uint64_t _komodo_paxprice(uint64_t *kmdbtcp,uint64_t *btcusdp,int32_t height,cha *kmdbtcp = pvals[MAX_CURRENCIES] / 539; *btcusdp = pvals[MAX_CURRENCIES + 1] / 539; } - //portable_mutex_unlock(&komodo_mutex); if ( kmdbtc != 0 && btcusd != 0 ) return(komodo_paxcalc(height,pvals,baseid,relid,basevolume,kmdbtc,btcusd)); else return(0); } } - //portable_mutex_unlock(&komodo_mutex); } //else LogPrintf("paxprice invalid base.%s %d, rel.%s %d\n",base,baseid,rel,relid); return(0); } @@ -584,26 +593,10 @@ uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint } else return(_komodo_paxpriceB(seed,height,base,rel,basevolume)); } -/*uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint64_t basevolume) -{ - uint64_t baseusd,basekmd,usdkmd; int32_t baseid = komodo_baseid(base); - //if ( strcmp(rel,"KMD") != 0 || baseid < 0 || MINDENOMS[baseid] == MINDENOMS[USD] ) - // return(_komodo_paxpriceB(seed,height,base,rel,basevolume)); - //else - { - baseusd = _komodo_paxpriceB(seed,height,base,(char *)"USD",SATOSHIDEN); - usdkmd = _komodo_paxpriceB(seed,height,(char *)"USD",(char *)"KMD",SATOSHIDEN); - basekmd = (komodo_paxvol(basevolume,baseusd) * usdkmd) / 10000000; - if ( strcmp("KMD",base) == 0 ) - LogPrintf("baseusd.%llu usdkmd.%llu %llu\n",(long long)baseusd,(long long)usdkmd,(long long)basekmd); - return(basekmd); - } -}*/ - uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume) { int32_t i,nonz=0; int64_t diff; uint64_t price,seed,sum = 0; - if ( ASSETCHAINS_SYMBOL[0] == 0 && chainActive.Tip() != 0 && height > chainActive.Tip()->nHeight ) + if ( chainName.isKMD() && chainActive.Tip() != 0 && height > chainActive.Tip()->nHeight ) { if ( height < 100000000 ) { @@ -614,69 +607,51 @@ uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uin return(0); } *seedp = komodo_seed(height); - portable_mutex_lock(&komodo_mutex); - for (i=0; i<17; i++) { - if ( (price= komodo_paxpriceB(*seedp,height-i,base,rel,basevolume)) != 0 ) + std::lock_guard lock(komodo_mutex); + for (i=0; i<17; i++) { - sum += price; - nonz++; - if ( 0 && i == 1 && nonz == 2 ) + if ( (price= komodo_paxpriceB(*seedp,height-i,base,rel,basevolume)) != 0 ) { - diff = (((int64_t)price - (sum >> 1)) * 10000); - if ( diff < 0 ) - diff = -diff; - diff /= price; - LogPrintf("(%llu %llu %lld).%lld ",(long long)price,(long long)(sum>>1),(long long)(((int64_t)price - (sum >> 1)) * 10000),(long long)diff); - if ( diff < 33 ) - break; - } - else if ( 0 && i == 3 && nonz == 4 ) - { - diff = (((int64_t)price - (sum >> 2)) * 10000); - if ( diff < 0 ) - diff = -diff; - diff /= price; - LogPrintf("(%llu %llu %lld).%lld ",(long long)price,(long long)(sum>>2),(long long) (((int64_t)price - (sum >> 2)) * 10000),(long long)diff); - if ( diff < 20 ) - break; + sum += price; + nonz++; + if ( 0 && i == 1 && nonz == 2 ) + { + diff = (((int64_t)price - (sum >> 1)) * 10000); + if ( diff < 0 ) + diff = -diff; + diff /= price; + LogPrintf("(%llu %llu %lld).%lld ",(long long)price,(long long)(sum>>1),(long long)(((int64_t)price - (sum >> 1)) * 10000),(long long)diff); + if ( diff < 33 ) + break; + } + else if ( 0 && i == 3 && nonz == 4 ) + { + diff = (((int64_t)price - (sum >> 2)) * 10000); + if ( diff < 0 ) + diff = -diff; + diff /= price; + LogPrintf("(%llu %llu %lld).%lld ",(long long)price,(long long)(sum>>2),(long long) (((int64_t)price - (sum >> 2)) * 10000),(long long)diff); + if ( diff < 20 ) + break; + } } + if ( height < 165000 || height > 236000 ) + break; } - if ( height < 165000 || height > 236000 ) - break; } - portable_mutex_unlock(&komodo_mutex); if ( nonz != 0 ) sum /= nonz; //LogPrintf("-> %lld %s/%s i.%d ht.%d\n",(long long)sum,base,rel,i,height); return(sum); } -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; - if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 ) - { - for (i=NUM_PRICES-1; i>=0; i--) - { - ptr = &PVALS[36 * i]; - heights[num] = *ptr; - prices[num] = komodo_paxcalc(*ptr,&ptr[1],baseid,relid,COIN,0,0); - num++; - if ( num >= max ) - return(num); - } - } - return(num); -} - -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 KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); // komodo.h void komodo_paxpricefeed(int32_t height,uint8_t *pricefeed,int32_t opretlen) { double KMDBTC,BTCUSD,CNYUSD; uint32_t numpvals,timestamp,pvals[128]; uint256 zero; numpvals = dpow_readprices(height,pricefeed,×tamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals); memset(&zero,0,sizeof(zero)); - komodo_stateupdate(height,0,0,0,zero,0,0,pvals,numpvals,0,0,0,0,0,0,zero,0); + komodo_stateupdate(height,0,0,0,zero,pvals,numpvals,0,0,0,0,0,0,zero,0); if ( 0 ) { int32_t i; @@ -686,14 +661,14 @@ void komodo_paxpricefeed(int32_t height,uint8_t *pricefeed,int32_t opretlen) } } -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) +uint64_t PAX_fiatdest(uint64_t *seedp,int32_t tokomodo,char *destaddr,uint8_t pubkey33[33],const char *coinaddr,int32_t height,const 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; *seedp = komodo_seed(height); if ( (baseid= komodo_baseid(origbase)) < 0 || baseid == MAX_CURRENCIES ) { if ( 0 && origbase[0] != 0 ) - LogPrintf("[%s] PAX_fiatdest illegal base.(%s)\n",ASSETCHAINS_SYMBOL,origbase); + LogPrintf("[%s] PAX_fiatdest illegal base.(%s)\n",chainName.symbol().c_str(),origbase); return(0); } for (i=0; i<3; i++) @@ -702,7 +677,6 @@ uint64_t PAX_fiatdest(uint64_t *seedp,int32_t tokomodo,char *destaddr,uint8_t pu if ( fiatoshis < 0 ) shortflag = 1, fiatoshis = -fiatoshis; komodoshis = komodo_paxprice(seedp,height,base,(char *)"KMD",(uint64_t)fiatoshis); - //LogPrintf("PAX_fiatdest ht.%d price %s %.8f -> KMD %.8f seed.%llx\n",height,base,(double)fiatoshis/COIN,(double)komodoshis/COIN,(long long)*seedp); if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == 20 ) { PAX_pubkey(1,pubkey33,&addrtype,rmd160,base,&shortflag,tokomodo != 0 ? &komodoshis : &fiatoshis); diff --git a/src/komodo_pax.h b/src/komodo_pax.h index 537f7001..2329e1b0 100644 --- a/src/komodo_pax.h +++ b/src/komodo_pax.h @@ -1,4 +1,4 @@ -/****************************************************************************** +/****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * @@ -51,9 +51,6 @@ #define IDR 30 #define HRK 31 -#define MAX_CURRENCIES 32 -extern char CURRENCIES[][8]; - uint64_t komodo_maxallowed(int32_t baseid); uint64_t komodo_paxvol(uint64_t volume,uint64_t price); @@ -86,8 +83,6 @@ uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint 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); - void komodo_paxpricefeed(int32_t height,uint8_t *pricefeed,int32_t opretlen); -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); \ No newline at end of file +uint64_t PAX_fiatdest(uint64_t *seedp,int32_t tokomodo,char *destaddr,uint8_t pubkey33[33],const char *coinaddr,int32_t height,const char *origbase,int64_t fiatoshis); diff --git a/src/komodo_port.c b/src/komodo_port.c index 9a226f97..d5065316 100644 --- a/src/komodo_port.c +++ b/src/komodo_port.c @@ -12,12 +12,12 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ - +#include "bits256.h" +#include "komodo_utils.h" // for komodo_port #include #include #include #include -#include "bits256.h" uint64_t ASSETCHAINS_COMMISSION; uint32_t ASSETCHAINS_MAGIC = 2387029918; @@ -761,22 +761,6 @@ int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endian return(len); } -uint32_t komodo_assetmagic(char *symbol,uint64_t supply,uint8_t *extraptr,int32_t extralen) -{ - uint8_t buf[512]; uint32_t crc0=0; int32_t len = 0; bits256 hash; - if ( strcmp(symbol,"KMD") == 0 ) - return(0x8de4eef9); - len = iguana_rwnum(1,&buf[len],sizeof(supply),(void *)&supply); - strcpy((char *)&buf[len],symbol); - len += strlen(symbol); - if ( extraptr != 0 && extralen != 0 ) - { - vcalc_sha256(0,hash.bytes,extraptr,extralen); - crc0 = hash.uints[0]; - } - return(calc_crc32(crc0,buf,len)); -} - uint16_t komodo_assetport(uint32_t magic,int32_t extralen) { if ( magic == 0x8de4eef9 ) @@ -786,17 +770,6 @@ uint16_t komodo_assetport(uint32_t magic,int32_t extralen) else return(16000 + (magic % 49500)); } -uint16_t komodo_port(char *symbol,uint64_t supply,uint32_t *magicp,uint8_t *extraptr,int32_t extralen) -{ - if ( symbol == 0 || symbol[0] == 0 || strcmp("KMD",symbol) == 0 ) - { - *magicp = 0x8de4eef9; - return(7770); - } - *magicp = komodo_assetmagic(symbol,supply,extraptr,extralen); - return(komodo_assetport(*magicp,extralen)); -} - uint16_t komodo_calcport(char *name,uint64_t supply,uint64_t endsubsidy,uint64_t reward,uint64_t halving,uint64_t decay,uint64_t commission,uint8_t staked,int32_t cc) { uint8_t extrabuf[4096],*extraptr=0; int32_t extralen=0; uint64_t val; diff --git a/src/komodo_structs.cpp b/src/komodo_structs.cpp index 5ca4cea4..b8512f3f 100644 --- a/src/komodo_structs.cpp +++ b/src/komodo_structs.cpp @@ -13,25 +13,9 @@ * * ******************************************************************************/ #include "komodo_structs.h" +#include "komodo_globals.h" +#include "komodo_bitcoind.h" #include "mem_read.h" -#include - -extern std::mutex komodo_mutex; - -/*** - * komodo_state - */ - -bool komodo_state::add_event(const std::string& symbol, const uint32_t height, std::shared_ptr in) -{ - if (ASSETCHAINS_SYMBOL[0] != 0) - { - std::lock_guard lock(komodo_mutex); - events.push_back( in ); - return true; - } - return false; -} namespace komodo { @@ -96,11 +80,11 @@ std::ostream& operator<<(std::ostream& os, const event& in) break; case(EVENT_NOTARIZED): { - event_notarized* tmp = dynamic_cast(const_cast(&in)); - if (tmp->MoMdepth == 0) - os << "N"; - else + const event_notarized& tmp = static_cast(in); + if (tmp.MoMdepth != 0 && !tmp.MoM.IsNull()) os << "M"; + else + os << "N"; break; } case(EVENT_U): @@ -108,8 +92,8 @@ std::ostream& operator<<(std::ostream& os, const event& in) break; case(EVENT_KMDHEIGHT): { - event_kmdheight* tmp = dynamic_cast(const_cast(&in)); - if (tmp->timestamp == 0) + const event_kmdheight& tmp = static_cast(in); + if (tmp.timestamp == 0) os << "K"; else os << "T"; @@ -135,7 +119,7 @@ std::ostream& operator<<(std::ostream& os, const event& in) * @param pos the starting position (will advance) * @param data_len full length of data */ -event_pubkeys::event_pubkeys(uint8_t* data, long& pos, long data_len, int32_t height) : event(EVENT_PUBKEYS, height) +event_pubkeys::event_pubkeys(uint8_t* data, long& pos, long data_len, int32_t height) : event_pubkeys(height) { num = data[pos++]; if (num > 64) @@ -143,7 +127,7 @@ event_pubkeys::event_pubkeys(uint8_t* data, long& pos, long data_len, int32_t he mem_nread(pubkeys, num, data, pos, data_len); } -event_pubkeys::event_pubkeys(FILE* fp, int32_t height) : event(EVENT_PUBKEYS, height) +event_pubkeys::event_pubkeys(FILE* fp, int32_t height) : event_pubkeys(height) { num = fgetc(fp); if ( fread(pubkeys,33,num,fp) != num ) @@ -152,30 +136,34 @@ event_pubkeys::event_pubkeys(FILE* fp, int32_t height) : event(EVENT_PUBKEYS, he std::ostream& operator<<(std::ostream& os, const event_pubkeys& in) { - const event& e = dynamic_cast(in); + const event& e = static_cast(in); os << e; os << in.num; - for(uint8_t i = 0; i < in.num-1; ++i) - os << in.pubkeys[i]; + for(uint8_t i = 0; i < in.num; ++i) + for(uint8_t j = 0; j < 33; ++j) + os << in.pubkeys[i][j]; return os; } -event_rewind::event_rewind(uint8_t *data, long &pos, long data_len, int32_t height) : event(EVENT_REWIND, height) +event_rewind::event_rewind(uint8_t *data, long &pos, long data_len, int32_t height) : event_rewind(height) { // nothing to do } std::ostream& operator<<(std::ostream& os, const event_rewind& in) { - const event& e = dynamic_cast(in); + const event& e = static_cast(in); os << e; return os; } -event_notarized::event_notarized(uint8_t *data, long &pos, long data_len, int32_t height, const char* _dest, bool includeMoM) - : event(EVENT_NOTARIZED, height), MoMdepth(0) +event_notarized::event_notarized(uint8_t *data, long &pos, long data_len, int32_t height, + const char* _dest, bool includeMoM) + : event_notarized(height, _dest) { - strncpy(this->dest, _dest, sizeof(this->dest)-1); - this->dest[sizeof(this->dest)-1] = 0; + // init via event_notarized(height, dest) + //if (_dest != nullptr) + // strncpy(this->dest, _dest, sizeof(this->dest)-1); + //this->dest[sizeof(this->dest)-1] = 0; MoM.SetNull(); mem_read(this->notarizedheight, data, pos, data_len); mem_read(this->blockhash, data, pos, data_len); @@ -188,10 +176,12 @@ event_notarized::event_notarized(uint8_t *data, long &pos, long data_len, int32_ } event_notarized::event_notarized(FILE* fp, int32_t height, const char* _dest, bool includeMoM) - : event(EVENT_NOTARIZED, height), MoMdepth(0) + : event_notarized(height, _dest) { - strncpy(this->dest, _dest, sizeof(this->dest)-1); - this->dest[sizeof(this->dest)-1] = 0; + // init via event_notarized(height, dest) + //if (_dest != nullptr) + // strncpy(this->dest, _dest, sizeof(this->dest)-1); + //this->dest[sizeof(this->dest)-1] = 0; MoM.SetNull(); if ( fread(¬arizedheight,1,sizeof(notarizedheight),fp) != sizeof(notarizedheight) ) throw parse_error("Invalid notarization height"); @@ -210,12 +200,12 @@ event_notarized::event_notarized(FILE* fp, int32_t height, const char* _dest, bo std::ostream& operator<<(std::ostream& os, const event_notarized& in) { - const event& e = dynamic_cast(in); + const event& e = static_cast(in); os << e; os << serializable(in.notarizedheight); os << serializable(in.blockhash); os << serializable(in.desttxid); - if (in.MoMdepth > 0) + if (in.MoMdepth != 0 && !in.MoM.IsNull()) { os << serializable(in.MoM); os << serializable(in.MoMdepth); @@ -223,7 +213,7 @@ std::ostream& operator<<(std::ostream& os, const event_notarized& in) return os; } -event_u::event_u(uint8_t *data, long &pos, long data_len, int32_t height) : event(EVENT_U, height) +event_u::event_u(uint8_t *data, long &pos, long data_len, int32_t height) : event_u(height) { mem_read(this->n, data, pos, data_len); mem_read(this->nid, data, pos, data_len); @@ -231,7 +221,7 @@ event_u::event_u(uint8_t *data, long &pos, long data_len, int32_t height) : even mem_read(this->hash, data, pos, data_len); } -event_u::event_u(FILE *fp, int32_t height) : event(EVENT_U, height) +event_u::event_u(FILE *fp, int32_t height) : event_u(height) { if (fread(&n, 1, sizeof(n), fp) != sizeof(n)) throw parse_error("Unable to read n of event U from file"); @@ -245,7 +235,7 @@ event_u::event_u(FILE *fp, int32_t height) : event(EVENT_U, height) std::ostream& operator<<(std::ostream& os, const event_u& in) { - const event& e = dynamic_cast(in); + const event& e = static_cast(in); os << e; os << in.n << in.nid; os.write((const char*)in.mask, 8); @@ -253,14 +243,16 @@ std::ostream& operator<<(std::ostream& os, const event_u& in) return os; } -event_kmdheight::event_kmdheight(uint8_t* data, long &pos, long data_len, int32_t height, bool includeTimestamp) : event(EVENT_KMDHEIGHT, height) +event_kmdheight::event_kmdheight(uint8_t* data, long &pos, long data_len, int32_t height, + bool includeTimestamp) : event_kmdheight(height) { mem_read(this->kheight, data, pos, data_len); if (includeTimestamp) mem_read(this->timestamp, data, pos, data_len); } -event_kmdheight::event_kmdheight(FILE *fp, int32_t height, bool includeTimestamp) : event(EVENT_KMDHEIGHT, height) +event_kmdheight::event_kmdheight(FILE *fp, int32_t height, bool includeTimestamp) + : event_kmdheight(height) { if ( fread(&kheight,1,sizeof(kheight),fp) != sizeof(kheight) ) throw parse_error("Unable to parse KMD height"); @@ -273,14 +265,15 @@ event_kmdheight::event_kmdheight(FILE *fp, int32_t height, bool includeTimestamp std::ostream& operator<<(std::ostream& os, const event_kmdheight& in) { - const event& e = dynamic_cast(in); + const event& e = static_cast(in); os << e << serializable(in.kheight); if (in.timestamp > 0) os << serializable(in.timestamp); return os; } -event_opreturn::event_opreturn(uint8_t *data, long &pos, long data_len, int32_t height) : event(EVENT_OPRETURN, height) +event_opreturn::event_opreturn(uint8_t *data, long &pos, long data_len, int32_t height) + : event_opreturn(height) { mem_read(this->txid, data, pos, data_len); mem_read(this->vout, data, pos, data_len); @@ -294,7 +287,7 @@ event_opreturn::event_opreturn(uint8_t *data, long &pos, long data_len, int32_t } } -event_opreturn::event_opreturn(FILE* fp, int32_t height) : event(EVENT_OPRETURN, height) +event_opreturn::event_opreturn(FILE* fp, int32_t height) : event_opreturn(height) { if ( fread(&txid,1,sizeof(txid),fp) != sizeof(txid) ) throw parse_error("Unable to parse txid of opreturn record"); @@ -312,7 +305,7 @@ event_opreturn::event_opreturn(FILE* fp, int32_t height) : event(EVENT_OPRETURN, std::ostream& operator<<(std::ostream& os, const event_opreturn& in) { - const event& e = dynamic_cast(in); + const event& e = static_cast(in); os << e << serializable(in.txid) << serializable(in.vout) @@ -322,7 +315,8 @@ std::ostream& operator<<(std::ostream& os, const event_opreturn& in) return os; } -event_pricefeed::event_pricefeed(uint8_t *data, long &pos, long data_len, int32_t height) : event(EVENT_PRICEFEED, height) +event_pricefeed::event_pricefeed(uint8_t *data, long &pos, long data_len, int32_t height) + : event_pricefeed(height) { mem_read(this->num, data, pos, data_len); // we're only interested if there are 35 prices. @@ -333,7 +327,8 @@ event_pricefeed::event_pricefeed(uint8_t *data, long &pos, long data_len, int32_ pos += num * sizeof(uint32_t); } -event_pricefeed::event_pricefeed(FILE* fp, int32_t height) : event(EVENT_PRICEFEED, height) +event_pricefeed::event_pricefeed(FILE* fp, int32_t height) + : event_pricefeed(height) { num = fgetc(fp); if ( num * sizeof(uint32_t) <= sizeof(prices) && fread(prices,sizeof(uint32_t),num,fp) != num ) @@ -342,7 +337,7 @@ event_pricefeed::event_pricefeed(FILE* fp, int32_t height) : event(EVENT_PRICEFE std::ostream& operator<<(std::ostream& os, const event_pricefeed& in) { - const event& e = dynamic_cast(in); + const event& e = static_cast(in); os << e << (uint8_t)in.num; os.write((const char*)in.prices, in.num * sizeof(uint32_t)); return os; diff --git a/src/komodo_structs.h b/src/komodo_structs.h index 6f4f0135..152a51de 100644 --- a/src/komodo_structs.h +++ b/src/komodo_structs.h @@ -19,40 +19,22 @@ #include #include "komodo_defs.h" +#include "komodo_extern_globals.h" #include "uthash.h" #include "utlist.h" #define GENESIS_NBITS 0x1f00ffff #define KOMODO_MINRATIFY ((height < 90000) ? 7 : 11) -#define KOMODO_NOTARIES_HARDCODED 180000 // DONT CHANGE +#define KOMODO_NOTARIES_HARDCODED 180000 // DONT CHANGE Below this height notaries were hardcoded #define KOMODO_MAXBLOCKS 250000 // DONT CHANGE -#define KOMODO_EVENT_RATIFY 'P' -#define KOMODO_EVENT_NOTARIZED 'N' -#define KOMODO_EVENT_KMDHEIGHT 'K' -#define KOMODO_EVENT_REWIND 'B' -#define KOMODO_EVENT_PRICEFEED 'V' -#define KOMODO_EVENT_OPRETURN 'R' -#define KOMODO_OPRETURN_DEPOSIT 'D' -#define KOMODO_OPRETURN_ISSUED 'I' // assetchain -#define KOMODO_OPRETURN_WITHDRAW 'W' // assetchain -#define KOMODO_OPRETURN_REDEEMED 'X' - -#define KOMODO_KVPROTECTED 1 -#define KOMODO_KVBINARY 2 -#define KOMODO_KVDURATION 1440 #define KOMODO_ASSETCHAIN_MAXLEN 65 #include "bits256.h" +#include -// structs prior to refactor -struct komodo_kv { UT_hash_handle hh; bits256 pubkey; uint8_t *key,*value; int32_t height; uint32_t flags; uint16_t keylen,valuesize; }; - -struct komodo_event_notarized { uint256 blockhash,desttxid,MoM; int32_t notarizedheight,MoMdepth; char dest[16]; }; -struct komodo_event_pubkeys { uint8_t num; uint8_t pubkeys[64][33]; }; -struct komodo_event_opreturn { uint256 txid; uint64_t value; uint16_t vout,oplen; uint8_t opret[]; }; -struct komodo_event_pricefeed { uint8_t num; uint32_t prices[35]; }; +//extern std::mutex komodo_mutex; //todo remove struct komodo_event { @@ -64,6 +46,21 @@ struct komodo_event uint8_t space[]; }; +/*** + * @brief persist event to file stream + * @param evt the event + * @param fp the file + * @returns the number of bytes written + */ +template +size_t write_event(T& evt, FILE *fp) +{ + std::stringstream ss; + ss << evt; + std::string buf = ss.str(); + return fwrite(buf.c_str(), buf.size(), 1, fp); +} + namespace komodo { enum komodo_event_type @@ -112,7 +109,7 @@ struct event_notarized : public event event_notarized() : event(komodo_event_type::EVENT_NOTARIZED, 0), notarizedheight(0), MoMdepth(0) { memset(this->dest, 0, sizeof(this->dest)); } - event_notarized(int32_t ht, const char* _dest) : event(EVENT_NOTARIZED, ht), notarizedheight(0), MoMdepth(0) { + event_notarized(int32_t ht, const char* _dest) : event(komodo_event_type::EVENT_NOTARIZED, ht), notarizedheight(0), MoMdepth(0) { strncpy(this->dest, _dest, sizeof(this->dest)-1); this->dest[sizeof(this->dest)-1] = 0; } event_notarized(uint8_t* data, long &pos, long data_len, int32_t height, const char* _dest, bool includeMoM = false); @@ -222,19 +219,13 @@ std::ostream& operator<<(std::ostream& os, const event_pricefeed& in); } // namespace komodo -struct pax_transaction -{ - UT_hash_handle hh; - uint256 txid; - uint64_t komodoshis,fiatoshis,validated; - int32_t marked,height,otherheight,approved,didstats,ready; - uint16_t vout; - char symbol[KOMODO_ASSETCHAIN_MAXLEN],source[KOMODO_ASSETCHAIN_MAXLEN],coinaddr[64]; uint8_t rmd160[20],type,buf[35]; -}; - struct knotary_entry { UT_hash_handle hh; uint8_t pubkey[33],notaryid; }; -struct knotaries_entry { int32_t height,numnotaries; struct knotary_entry *Notaries; }; - +struct knotaries_entry +{ + int32_t height; + int32_t numnotaries; // The number of notaries stored in Notaries + knotary_entry *Notaries; // A hashtable of notary ID/public key +}; struct notarized_checkpoint { uint256 notarized_hash; @@ -280,6 +271,7 @@ struct komodo_ccdata class komodo_state { public: + std::string symbol; int32_t SAVEDHEIGHT; int32_t CURRENT_HEIGHT; uint32_t SAVEDTIMESTAMP; @@ -291,7 +283,19 @@ class komodo_state uint64_t shorted; std::list> events; uint32_t RTbufs[64][3]; uint64_t RTmask; - bool add_event(const std::string& symbol, const uint32_t height, std::shared_ptr in); + template + bool add_event(const std::string& symbol, const uint32_t height, T& in) + { + if (!chainName.isKMD()) + { + std::shared_ptr ptr = std::make_shared( in ); + std::lock_guard lock(komodo_mutex); + events.push_back( ptr ); + return true; + } + return false; + } + protected: /*** * @brief clear the checkpoints collection diff --git a/src/komodo_utils.cpp b/src/komodo_utils.cpp index 9aaed9e8..bb28b222 100644 --- a/src/komodo_utils.cpp +++ b/src/komodo_utils.cpp @@ -12,16 +12,254 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ +#include "komodo_defs.h" +#include "komodo.h" #include "komodo_utils.h" -#include "komodo_extern_globals.h" +#include "komodo_globals.h" #include "komodo_notary.h" +#include "komodo_gateway.h" +#include "notaries_staked.h" + +#include "cc/CCinclude.h" + +// todo remove +//struct komodo_state KOMODO_STATES[34]; +//int32_t ASSETCHAINS_CBMATURITY; +//uint64_t ASSETCHAINS_TIMEUNLOCKFROM = 0; +//uint64_t ASSETCHAINS_TIMEUNLOCKTO = 0; + +struct sha256_vstate { uint64_t length; uint32_t state[8],curlen; uint8_t buf[64]; }; + +// following is ported from libtom + +#define STORE32L(x, y) \ +{ (y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \ +(y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); } + +#define LOAD32L(x, y) \ +{ x = (uint32_t)(((uint64_t)((y)[3] & 255)<<24) | \ +((uint32_t)((y)[2] & 255)<<16) | \ +((uint32_t)((y)[1] & 255)<<8) | \ +((uint32_t)((y)[0] & 255))); } + +#define STORE64L(x, y) \ +{ (y)[7] = (uint8_t)(((x)>>56)&255); (y)[6] = (uint8_t)(((x)>>48)&255); \ +(y)[5] = (uint8_t)(((x)>>40)&255); (y)[4] = (uint8_t)(((x)>>32)&255); \ +(y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \ +(y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); } + +#define LOAD64L(x, y) \ +{ x = (((uint64_t)((y)[7] & 255))<<56)|(((uint64_t)((y)[6] & 255))<<48)| \ +(((uint64_t)((y)[5] & 255))<<40)|(((uint64_t)((y)[4] & 255))<<32)| \ +(((uint64_t)((y)[3] & 255))<<24)|(((uint64_t)((y)[2] & 255))<<16)| \ +(((uint64_t)((y)[1] & 255))<<8)|(((uint64_t)((y)[0] & 255))); } + +#define STORE32H(x, y) \ +{ (y)[0] = (uint8_t)(((x)>>24)&255); (y)[1] = (uint8_t)(((x)>>16)&255); \ +(y)[2] = (uint8_t)(((x)>>8)&255); (y)[3] = (uint8_t)((x)&255); } + +#define LOAD32H(x, y) \ +{ x = (uint32_t)(((uint64_t)((y)[0] & 255)<<24) | \ +((uint32_t)((y)[1] & 255)<<16) | \ +((uint32_t)((y)[2] & 255)<<8) | \ +((uint32_t)((y)[3] & 255))); } + +#define STORE64H(x, y) \ +{ (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255); \ +(y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255); \ +(y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255); \ +(y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); } + +#define LOAD64H(x, y) \ +{ x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ +(((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ +(((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ +(((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } + +// Various logical functions +#define RORc(x, y) ( ((((uint32_t)(x)&0xFFFFFFFFUL)>>(uint32_t)((y)&31)) | ((uint32_t)(x)<<(uint32_t)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x),(n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) +#define MIN(x, y) ( ((x)<(y))?(x):(y) ) + +static inline int32_t sha256_vcompress(struct sha256_vstate * md,uint8_t *buf) +{ + uint32_t S[8],W[64],t0,t1,i; + for (i=0; i<8; i++) // copy state into S + S[i] = md->state[i]; + for (i=0; i<16; i++) // copy the state into 512-bits into W[0..15] + LOAD32H(W[i],buf + (4*i)); + for (i=16; i<64; i++) // fill W[16..63] + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + +#define RND(a,b,c,d,e,f,g,h,i,ki) \ +t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ +t1 = Sigma0(a) + Maj(a, b, c); \ +d += t0; \ +h = t0 + t1; + + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); +#undef RND + for (i=0; i<8; i++) // feedback + md->state[i] = md->state[i] + S[i]; + return(0); +} + +#undef RORc +#undef Ch +#undef Maj +#undef S +#undef R +#undef Sigma0 +#undef Sigma1 +#undef Gamma0 +#undef Gamma1 + +static inline int32_t sha256_vdone(struct sha256_vstate *md,uint8_t *out) +{ + int32_t i; + if ( md->curlen >= sizeof(md->buf) ) + return(-1); + md->length += md->curlen * 8; // increase the length of the message + md->buf[md->curlen++] = (uint8_t)0x80; // append the '1' bit + // if len > 56 bytes we append zeros then compress. Then we can fall back to padding zeros and length encoding like normal. + if ( md->curlen > 56 ) + { + while ( md->curlen < 64 ) + md->buf[md->curlen++] = (uint8_t)0; + sha256_vcompress(md,md->buf); + md->curlen = 0; + } + while ( md->curlen < 56 ) // pad upto 56 bytes of zeroes + md->buf[md->curlen++] = (uint8_t)0; + STORE64H(md->length,md->buf+56); // store length + sha256_vcompress(md,md->buf); + for (i=0; i<8; i++) // copy output + STORE32H(md->state[i],out+(4*i)); + return(0); +} + +static inline int32_t sha256_vprocess(struct sha256_vstate *md,const uint8_t *in,uint64_t inlen) +{ + uint64_t n; int32_t err; + if ( md->curlen > sizeof(md->buf) ) + return(-1); + while ( inlen > 0 ) + { + if ( md->curlen == 0 && inlen >= 64 ) + { + if ( (err= sha256_vcompress(md,(uint8_t *)in)) != 0 ) + return(err); + md->length += 64 * 8, in += 64, inlen -= 64; + } + else + { + n = MIN(inlen,64 - md->curlen); + memcpy(md->buf + md->curlen,in,(size_t)n); + md->curlen += n, in += n, inlen -= n; + if ( md->curlen == 64 ) + { + if ( (err= sha256_vcompress(md,md->buf)) != 0 ) + return(err); + md->length += 8*64; + md->curlen = 0; + } + } + } + return(0); +} + +static inline void sha256_vinit(struct sha256_vstate * md) +{ + md->curlen = 0; + md->length = 0; + md->state[0] = 0x6A09E667UL; + md->state[1] = 0xBB67AE85UL; + md->state[2] = 0x3C6EF372UL; + md->state[3] = 0xA54FF53AUL; + md->state[4] = 0x510E527FUL; + md->state[5] = 0x9B05688CUL; + md->state[6] = 0x1F83D9ABUL; + md->state[7] = 0x5BE0CD19UL; +} void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len) { - /* struct sha256_vstate md; + /* + struct sha256_vstate md; sha256_vinit(&md); sha256_vprocess(&md,src,len); - sha256_vdone(&md,hash); */ + sha256_vdone(&md,hash); + */ // we will use CSHA256 class instead of above implementation, // in case if daemon compiled with USE_ASM enabled it will use @@ -323,39 +561,6 @@ int rmd160_vinit(struct rmd160_vstate * md) md->length = 0; return 0; } -#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ -int func_name (struct rmd160_vstate * md, const unsigned char *in, unsigned long inlen) \ -{ \ -unsigned long n; \ -int err; \ -if (md->curlen > sizeof(md->buf)) { \ -return -1; \ -} \ -while (inlen > 0) { \ -if (md->curlen == 0 && inlen >= block_size) { \ -if ((err = compress_name (md, (unsigned char *)in)) != 0) { \ -return err; \ -} \ -md->length += block_size * 8; \ -in += block_size; \ -inlen -= block_size; \ -} else { \ -n = MIN(inlen, (block_size - md->curlen)); \ -memcpy(md->buf + md->curlen, in, (size_t)n); \ -md->curlen += n; \ -in += n; \ -inlen -= n; \ -if (md->curlen == block_size) { \ -if ((err = compress_name (md, md->buf)) != 0) { \ -return err; \ -} \ -md->length += 8*block_size; \ -md->curlen = 0; \ -} \ -} \ -} \ -return 0; \ -} /** Process a block of memory though the hash @@ -364,7 +569,38 @@ return 0; @param inlen The length of the data (octets) @return 0 if successful */ -HASH_PROCESS(rmd160_vprocess, rmd160_vcompress, rmd160, 64) +int rmd160_vprocess (struct rmd160_vstate * md, const unsigned char *in, unsigned long inlen) +{ + unsigned long n; + int err; + if (md->curlen > sizeof(md->buf)) { + return -1; + } + while (inlen > 0) { + if (md->curlen == 0 && inlen >= 64) { + if ((err = rmd160_vcompress (md, (unsigned char *)in)) != 0) { + return err; + } + md->length += 64 * 8; + in += 64; + inlen -= 64; + } else { + n = MIN(inlen, (64 - md->curlen)); + memcpy(md->buf + md->curlen, in, (size_t)n); + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == 64) { + if ((err = rmd160_vcompress (md, md->buf)) != 0) { + return err; + } + md->length += 8*64; + md->curlen = 0; + } + } + } + return 0; +} /** Terminate the hash to get the digest @@ -499,7 +735,7 @@ void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen) calc_rmd160(0,rmd160,hash.bytes,sizeof(hash)); } -int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr) +int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],const char *coinaddr) { bits256 hash; uint8_t *buf,_buf[25]; int32_t len; memset(rmd160,0,20); @@ -533,31 +769,32 @@ int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len) { - int32_t i; uint8_t data[25]; bits256 hash;// char checkaddr[65]; + int32_t i; + uint8_t data[25]; + bits256 hash; if ( len != 20 ) calc_rmd160_sha256(data+1,pubkey_or_rmd160,len); - else memcpy(data+1,pubkey_or_rmd160,20); - //btc_convrmd160(checkaddr,addrtype,data+1); + else + memcpy(data+1,pubkey_or_rmd160,20); data[0] = addrtype; hash = bits256_doublesha256(0,data,21); for (i=0; i<4; i++) data[21+i] = hash.bytes[31-i]; - if ( (coinaddr= bitcoin_base58encode(coinaddr,data,25)) != 0 ) - { - //uint8_t checktype,rmd160[20]; - //bitcoin_addr2rmd160(&checktype,rmd160,coinaddr); - //if ( strcmp(checkaddr,coinaddr) != 0 ) - // LogPrintf("checkaddr.(%s) vs coinaddr.(%s) %02x vs [%02x] memcmp.%d\n",checkaddr,coinaddr,addrtype,checktype,memcmp(rmd160,data+1,20)); - } - return(coinaddr); + return bitcoin_base58encode(coinaddr,data,25); } -int32_t komodo_is_issuer() + +/*int32_t komodo_baseid(const char *origbase) { - if ( ASSETCHAINS_SYMBOL[0] != 0 && komodo_baseid(ASSETCHAINS_SYMBOL) >= 0 ) - return(1); - else return(0); -} + int32_t i; char base[64]; + for (i=0; origbase[i]!=0&&i= 0x4c ) - { - if ( opretlen == 0x4c ) - opretlen = script[len++]; - else if ( opretlen == 0x4d ) - { - opretlen = script[len] + (script[len+1] << 8); - len += 2; - //opretlen = script[len++]; - //opretlen = (opretlen << 8) | script[len++]; - } - } - *opretlenp = opretlen; - return(len); -} - int32_t komodo_opreturnscript(uint8_t *script,uint8_t type,uint8_t *opret,int32_t opretlen) { int32_t offset = 0; @@ -810,171 +1028,67 @@ void OS_randombytes(unsigned char *x,long xlen) } #endif -void lock_queue(queue_t *queue) -{ - if ( queue->initflag == 0 ) - { - portable_mutex_init(&queue->mutex); - queue->initflag = 1; - } - portable_mutex_lock(&queue->mutex); -} - -void queue_enqueue(char *name,queue_t *queue,struct queueitem *item) -{ - if ( queue->name[0] == 0 && name != 0 && name[0] != 0 ) - strcpy(queue->name,name); - if ( item == 0 ) - { - LogPrintf("FATAL type error: queueing empty value\n"); - return; - } - lock_queue(queue); - DL_APPEND(queue->list,item); - portable_mutex_unlock(&queue->mutex); -} - -struct queueitem *queue_dequeue(queue_t *queue) -{ - struct queueitem *item = 0; - lock_queue(queue); - if ( queue->list != 0 ) - { - item = queue->list; - DL_DELETE(queue->list,item); - } - portable_mutex_unlock(&queue->mutex); - return(item); -} - -void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize) -{ - struct queueitem *item = 0; - lock_queue(queue); - if ( queue->list != 0 ) - { - DL_FOREACH(queue->list,item) - { - #ifdef _WIN32 - if ( item == copy || (item->allocsize == copysize && memcmp((void *)((intptr_t)item + sizeof(struct queueitem)),(void *)((intptr_t)copy + sizeof(struct queueitem)),copysize) == 0) ) - #else - if ( item == copy || (item->allocsize == copysize && memcmp((void *)((long)item + sizeof(struct queueitem)),(void *)((long)copy + sizeof(struct queueitem)),copysize) == 0) ) - #endif - { - DL_DELETE(queue->list,item); - portable_mutex_unlock(&queue->mutex); - LogPrintf("name.(%s) deleted item.%p list.%p\n",queue->name,item,queue->list); - return(item); - } - } - } - portable_mutex_unlock(&queue->mutex); - return(0); -} - -void *queue_free(queue_t *queue) -{ - struct queueitem *item = 0; - lock_queue(queue); - if ( queue->list != 0 ) - { - DL_FOREACH(queue->list,item) - { - DL_DELETE(queue->list,item); - free(item); - } - //LogPrintf("name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list); - } - portable_mutex_unlock(&queue->mutex); - return(0); -} - -void *queue_clone(queue_t *clone,queue_t *queue,int32_t size) -{ - struct queueitem *ptr,*item = 0; - lock_queue(queue); - if ( queue->list != 0 ) - { - DL_FOREACH(queue->list,item) - { - ptr = (struct queueitem *)calloc(1,sizeof(*ptr)); - memcpy(ptr,item,size); - queue_enqueue(queue->name,clone,ptr); - } - //LogPrintf("name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list); - } - portable_mutex_unlock(&queue->mutex); - return(0); -} - -int32_t queue_size(queue_t *queue) +/** + * @brief Get the username, password, and port from a file + * @param[out] username the username found in the config file + * @param[out] password the password found in the config file + * @param[in] fp the file to be read + * @return the RPC port + */ +uint16_t _komodo_userpass(char *username,char *password,FILE *fp) { - int32_t count = 0; - struct queueitem *tmp; - lock_queue(queue); - DL_COUNT(queue->list,tmp,count); - portable_mutex_unlock(&queue->mutex); - return count; -} + uint16_t port = 0; + char *rpcuser = nullptr; + char *rpcpassword = nullptr; + char line[8192]; -void iguana_initQ(queue_t *Q,char *name) -{ - struct queueitem *item,*I; - memset(Q,0,sizeof(*Q)); - I = (struct queueitem *)calloc(1,sizeof(*I)); - strcpy(Q->name,name); - queue_enqueue(name,Q,I); - if ( (item= queue_dequeue(Q)) != 0 ) - free(item); -} + username[0] = 0; + password[0] = 0; -uint16_t _komodo_userpass(char *username,char *password,FILE *fp) -{ - char *rpcuser,*rpcpassword,*str,line[8192]; uint16_t port = 0; - rpcuser = rpcpassword = 0; - username[0] = password[0] = 0; while ( fgets(line,sizeof(line),fp) != 0 ) { + char *str = nullptr; if ( line[0] == '#' ) continue; - //LogPrintf("line.(%s) %p %p\n",line,strstr(line,(char *)"rpcuser"),strstr(line,(char *)"rpcpassword")); - if ( (str= strstr(line,(char *)"rpcuser")) != 0 ) + if ( (str= strstr(line,(char *)"rpcuser")) != nullptr ) + { rpcuser = parse_conf_line(str,(char *)"rpcuser"); - else if ( (str= strstr(line,(char *)"rpcpassword")) != 0 ) + } + else if ( (str= strstr(line,(char *)"rpcpassword")) != nullptr ) + { rpcpassword = parse_conf_line(str,(char *)"rpcpassword"); - else if ( (str= strstr(line,(char *)"rpcport")) != 0 ) + } + else if ( (str= strstr(line,(char *)"rpcport")) != nullptr ) { port = atoi(parse_conf_line(str,(char *)"rpcport")); - //LogPrintf("rpcport.%u in file\n",port); } } - if ( rpcuser != 0 && rpcpassword != 0 ) + if ( rpcuser != nullptr && rpcpassword != nullptr ) { strcpy(username,rpcuser); strcpy(password,rpcpassword); } - //LogPrintf("rpcuser.(%s) rpcpassword.(%s) KMDUSERPASS.(%s) %u\n",rpcuser,rpcpassword,KMDUSERPASS,port); - if ( rpcuser != 0 ) + if ( rpcuser != nullptr ) free(rpcuser); - if ( rpcpassword != 0 ) + if ( rpcpassword != nullptr ) free(rpcpassword); - return(port); + return port; } -void komodo_statefname(char *fname,char *symbol,char *str) +void komodo_statefname(char *fname, const char *symbol, const char *str) { int32_t n,len; - sprintf(fname,"%s",GetDataDir(false).string().c_str()); - if ( (n= (int32_t)strlen(ASSETCHAINS_SYMBOL)) != 0 ) + snprintf(fname, MAX_STATEFNAME, "%s",GetDataDir(false).string().c_str()); + if ( (n= (int32_t)chainName.symbol().size()) != 0 ) { len = (int32_t)strlen(fname); - if ( !mapArgs.count("-datadir") && strcmp(ASSETCHAINS_SYMBOL,&fname[len - n]) == 0 ) + if ( !mapArgs.count("-datadir") && strcmp(chainName.symbol().c_str(),&fname[len - n]) == 0 ) fname[len - n] = 0; - else if(mapArgs.count("-datadir")) LogPrintf("DEBUG - %s:%d: custom datadir\n", __FILE__, __LINE__); + else if(mapArgs.count("-datadir")) LogPrintf("DEBUG - komodo_utils:1363: custom datadir\n"); else { if ( strcmp(symbol,"REGTEST") != 0 ) - LogPrintf("unexpected fname.(%s) vs %s [%s] n.%d len.%d (%s)\n",fname,symbol,ASSETCHAINS_SYMBOL,n,len,&fname[len - n]); + LogPrintf("unexpected fname.(%s) vs %s [%s] n.%d len.%d (%s)\n",fname,symbol,chainName.symbol().c_str(),n,len,&fname[len - n]); return; } } @@ -989,7 +1103,6 @@ void komodo_statefname(char *fname,char *symbol,char *str) if ( symbol != 0 && symbol[0] != 0 && strcmp("KMD",symbol) != 0 ) { if(!mapArgs.count("-datadir")) strcat(fname,symbol); - //printf("statefname.(%s) -> (%s)\n",symbol,fname); #ifdef _WIN32 strcat(fname,"\\"); #else @@ -997,10 +1110,9 @@ void komodo_statefname(char *fname,char *symbol,char *str) #endif } strcat(fname,str); - //LogPrintf("test.(%s) -> [%s] statename.(%s) %s\n",test,ASSETCHAINS_SYMBOL,symbol,fname); } -void komodo_configfile(char *symbol,uint16_t rpcport) +void komodo_configfile(const char *symbol,uint16_t rpcport) { static char myusername[512],mypassword[8192]; FILE *fp; uint16_t kmdport; uint8_t buf2[33]; char fname[512],buf[128],username[512],password[8192]; uint32_t crc,r,r2,i; @@ -1068,11 +1180,10 @@ void komodo_configfile(char *symbol,uint16_t rpcport) KMD_PORT = kmdport; sprintf(KMDUSERPASS,"%s:%s",username,password); fclose(fp); -//LogPrintf("KOMODO.(%s) -> userpass.(%s)\n",fname,KMDUSERPASS); - } //else LogPrintf("couldnt open.(%s)\n",fname); + } } -uint16_t komodo_userpass(char *userpass,char *symbol) +uint16_t komodo_userpass(char *userpass,const char *symbol) { FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[KOMODO_ASSETCHAIN_MAXLEN]; userpass[0] = 0; @@ -1093,66 +1204,85 @@ uint16_t komodo_userpass(char *userpass,char *symbol) { port = _komodo_userpass(username,password,fp); sprintf(userpass,"%s:%s",username,password); - if ( strcmp(symbol,ASSETCHAINS_SYMBOL) == 0 ) + if ( chainName.isSymbol(symbol) ) strcpy(ASSETCHAINS_USERPASS,userpass); fclose(fp); } return(port); } -uint32_t komodo_assetmagic(char *symbol,uint64_t supply,uint8_t *extraptr,int32_t extralen) +/** + * @brief Compute the magic number + * + * @param symbol the chain symbol + * @param supply max supply + * @param extraptr details of chain parameters + * @param extralen length of extraptr + * @return the magic number + */ +uint32_t komodo_assetmagic(const char *symbol,uint64_t supply,uint8_t *extraptr,int32_t extralen) { - uint8_t buf[512]; uint32_t crc0=0; int32_t len = 0; bits256 hash; + uint8_t buf[512]; + uint32_t crc0=0; + int32_t len = 0; + bits256 hash; if ( strcmp(symbol,"KMD") == 0 ) - return(0x8de4eef9); + return 0x8de4eef9; + len = iguana_rwnum(1,&buf[len],sizeof(supply),(void *)&supply); strcpy((char *)&buf[len],symbol); len += strlen(symbol); + if ( extraptr != 0 && extralen != 0 ) { + bits256 hash; vcalc_sha256(0,hash.bytes,extraptr,extralen); crc0 = hash.uints[0]; - int32_t i; for (i=0; i 0 ) + { + uint64_t lastEnd = j == 0 ? 0 : ASSETCHAINS_ENDSUBSIDY[j - 1]; + uint64_t curEnd = ASSETCHAINS_ENDSUBSIDY[j] == 0 ? nHeight : nHeight > ASSETCHAINS_ENDSUBSIDY[j] ? ASSETCHAINS_ENDSUBSIDY[j] : nHeight; + uint64_t period = ASSETCHAINS_HALVING[j]; + if ( period == 0 ) + period = 210000; + uint32_t nSteps = (curEnd - lastEnd) / period; + uint32_t modulo = (curEnd - lastEnd) % period; + uint64_t decay = ASSETCHAINS_DECAY[j]; + + //LogPrintf("period.%llu cur_money %.8f += %.8f * %d\n",(long long)period,(double)cur_money/COIN,(double)reward/COIN,nHeight); + if ( ASSETCHAINS_HALVING[j] == 0 ) + { + // no halving, straight multiply + cur_money += reward * (nHeight - 1); + //LogPrintf("cur_money %.8f\n",(double)cur_money/COIN); + } + // if exactly SATOSHIDEN, linear decay to zero or to next era, same as: + // (next_era_reward + (starting reward - next_era_reward) / 2) * num_blocks + else if ( decay == SATOSHIDEN ) + { + int64_t lowestSubsidy, subsidyDifference, stepDifference, stepTriangle; + int64_t denominator, modulo=1; + int32_t sign = 1; + + if ( j == ASSETCHAINS_LASTERA ) + { + subsidyDifference = reward; + lowestSubsidy = 0; + } + else + { + // Ex: -ac_eras=3 -ac_reward=0,384,24 -ac_end=1440,260640,0 -ac_halving=1,1440,2103840 -ac_decay 100000000,97750000,0 + subsidyDifference = reward - ASSETCHAINS_REWARD[j + 1]; + if (subsidyDifference < 0) + { + sign = -1; + subsidyDifference *= sign; + lowestSubsidy = reward; + } + else + { + lowestSubsidy = ASSETCHAINS_REWARD[j + 1]; + } + } + + // if we have not finished the current era, we need to caluclate a total as if we are at the end, with the current + // subsidy. we will calculate the total of a linear era as follows. Each item represents an area calculation: + // a) the rectangle from 0 to the lowest reward in the era * the number of blocks + // b) the rectangle of the remainder of blocks from the lowest point of the era to the highest point of the era if any remainder + // c) the minor triangle from the start of transition from the lowest point to the start of transition to the highest point + // d) one halving triangle (half area of one full step) + // + // we also need: + // e) number of steps = (n - erastart) / halving interval + // + // the total supply from era start up to height is: + // a + b + c + (d * e) + + // calculate amount in one step's triangular protrusion over minor triangle's hypotenuse + denominator = nSteps * period; + if ( denominator == 0 ) + denominator = 1; + // difference of one step vs. total + stepDifference = (period * subsidyDifference) / denominator; + + // area == coin holding of one step triangle, protruding from minor triangle's hypotenuse + stepTriangle = (period * stepDifference) >> 1; + + // sign is negative if slope is positive (start is less than end) + if (sign < 0) + { + // use steps minus one for our calculations, and add the potentially partial rectangle + // at the end + cur_money += stepTriangle * (nSteps - 1); + cur_money += stepTriangle * (nSteps - 1) * (nSteps - 1); + + // difference times number of steps is height of rectangle above lowest subsidy + cur_money += modulo * stepDifference * nSteps; + } + else + { + // if negative slope, the minor triangle is the full number of steps, as the highest + // level step is full. lowest subsidy is just the lowest so far + lowestSubsidy = reward - (stepDifference * nSteps); + + // add the step triangles, one per step + cur_money += stepTriangle * nSteps; + + // add the minor triangle + cur_money += stepTriangle * nSteps * nSteps; + } + + // add more for the base rectangle if lowest subsidy is not 0 + cur_money += lowestSubsidy * (curEnd - lastEnd); + } + else + { + for ( int k = lastEnd; k < curEnd; k += period ) + { + cur_money += period * reward; + // if zero, we do straight halving + reward = decay ? (reward * decay) / SATOSHIDEN : reward >> 1; + } + cur_money += modulo * reward; + } + } + } + } + } + if ( KOMODO_BIT63SET(cur_money) != 0 ) + return(KOMODO_MAXNVALUE); + if ( ASSETCHAINS_COMMISSION != 0 ) + { + uint64_t newval = (cur_money + (cur_money/COIN * ASSETCHAINS_COMMISSION)); + if ( KOMODO_BIT63SET(newval) != 0 ) + return(KOMODO_MAXNVALUE); + else if ( newval < cur_money ) // check for underflow + return(KOMODO_MAXNVALUE); + return(newval); + } + //LogPrintf("cur_money %.8f\n",(double)cur_money/COIN); + return(cur_money); +} + uint64_t komodo_max_money() { return komodo_current_supply(10000000); @@ -1268,15 +1554,13 @@ uint64_t komodo_ac_block_subsidy(int nHeight) else subsidy += ASSETCHAINS_SUPPLY * SATOSHIDEN + magicExtra; } - else if ( is_STAKED(ASSETCHAINS_SYMBOL) == 2 ) + else if ( is_STAKED(chainName.symbol()) == 2 ) return(0); // LABS fungible chains, cannot have any block reward! return(subsidy); } -extern int64_t MAX_MONEY; -void komodo_cbopretupdate(int32_t forceflag); -void SplitStr(const std::string& strVal, std::vector &outVals); +//void SplitStr(const std::string& strVal, std::vector &outVals); int8_t equihash_params_possible(uint64_t n, uint64_t k) { @@ -1301,27 +1585,79 @@ int8_t equihash_params_possible(uint64_t n, uint64_t k) } /*** - * Parse command line arguments - * @param argv0 the arguments + * @brief get username, password, and port from a config file + * @param[in] path the path to the data directory + * @param[in] filename the filename of the config file (without directory) + * @param[out] userpass the username and password from the config file (colon separated) + * @param[out] port the RPC port found in the config file */ +void get_userpass_and_port(const boost::filesystem::path& path, const std::string& filename, + std::string& userpass, uint16_t& port) +{ + userpass = ""; + port = 0; + boost::filesystem::path datadir_path = path; + datadir_path /= filename; + FILE* fp = fopen(datadir_path.string().c_str(), "rb"); + if ( fp != nullptr ) + { + char username[512]; + char password[4096]; + port = _komodo_userpass(username,password,fp); + if ( username[0] != 0 && password[0] != 0 ) + userpass = std::string(username) + ":" + std::string(password); + fclose(fp); + } + else + LogPrintf("couldnt open.(%s) will not validate dest notarizations\n", datadir_path.string().c_str()); +} + +/**** + * @brief set ports and usernames/passwords from command line and/or config files + * @note modifies ASSETCHAINS_P2PPORT, ASSETCHAINS_RPCPORT, KMDUSERPASS, BTCUSERPASS, DESTPORT + * @note IS_KOMODO_NOTARY should already be set + * @param ltc_config_filename configuration file for ltc (via -notary command line parameter) + */ +void set_kmd_user_password_port(const std::string& ltc_config_filename) +{ + ASSETCHAINS_P2PPORT = 7770; // default port for P2P + ASSETCHAINS_RPCPORT = 7771; // default port for RPC +#ifdef __APPLE__ + std::string filename = "Komodo.conf"; +#else + std::string filename = "komodo.conf"; +#endif + + auto datadir_path = GetDataDir(); + uint16_t ignore; + std::string userpass; + get_userpass_and_port(datadir_path, filename, userpass, ignore); + if (!userpass.empty()) + strncpy(KMDUSERPASS, userpass.c_str(), 8705); + if (IS_KOMODO_NOTARY) + { + auto approot_path = GetAppDir(); // go to app root dir + get_userpass_and_port(approot_path, ltc_config_filename, userpass, DEST_PORT); + if (!userpass.empty()) + strncpy(BTCUSERPASS, userpass.c_str(), 8192); + } +} + void komodo_args(char *argv0) { - uint8_t extrabuf[32756], *extraptr = 0; - int32_t i; - int32_t n; - int32_t nonz=0; + uint8_t disablebits[32]; + uint8_t *extraptr=nullptr; + FILE *fp; + uint16_t nonz=0; // keep track of # CCs enabled int32_t extralen = 0; - uint64_t ccEnablesHeight[512] = {0}; - std::string ntz_dest_path; - ntz_dest_path = GetArg("-notary", ""); - IS_KOMODO_NOTARY = !ntz_dest_path.empty(); + const std::string ntz_dest_path = GetArg("-notary", ""); + IS_KOMODO_NOTARY = ntz_dest_path == "" ? 0 : 1; + STAKED_NOTARY_ID = GetArg("-stakednotary", -1); KOMODO_NSPV = GetArg("-nSPV",0); - uint8_t disablebits[32]; - memset(disablebits,0,sizeof(disablebits)); - memset(ccEnablesHeight,0,sizeof(ccEnablesHeight)); + memset(disablebits,0,sizeof(disablebits)); // everything enabled if ( GetBoolArg("-gen", false) != 0 ) { KOMODO_MININGTHREADS = GetArg("-genproclimit",-1); @@ -1331,19 +1667,19 @@ void komodo_args(char *argv0) LogPrintf("IS_MODE_EXCHANGEWALLET mode active\n"); DONATION_PUBKEY = GetArg("-donation", ""); NOTARY_PUBKEY = GetArg("-pubkey", ""); - IS_KOMODO_DEALERNODE = GetBoolArg("-dealer",false); + IS_KOMODO_DEALERNODE = GetArg("-dealer",0); IS_KOMODO_TESTNODE = GetArg("-testnode",0); ASSETCHAINS_STAKED_SPLIT_PERCENTAGE = GetArg("-splitperc",0); - if ( NOTARY_PUBKEY.size() == 66 ) + if ( strlen(NOTARY_PUBKEY.c_str()) == 66 ) { - decode_hex(NOTARY_PUBKEY33,33,NOTARY_PUBKEY.c_str()); + decode_hex(NOTARY_PUBKEY33,33,(char *)NOTARY_PUBKEY.c_str()); USE_EXTERNAL_PUBKEY = 1; if ( !IS_KOMODO_NOTARY ) { // We dont have any chain data yet, so use system clock to guess. // I think on season change should reccomend notaries to use -notary to avoid needing this. int32_t kmd_season = getacseason(time(NULL)); - for (i=0; i<64; i++) + for (uint16_t i=0; i<64; i++) { if ( strcmp(NOTARY_PUBKEY.c_str(),notaries_elected[kmd_season-1][i][1]) == 0 ) { @@ -1357,17 +1693,17 @@ void komodo_args(char *argv0) } } } - if ( STAKED_NOTARY_ID != -1 && IS_KOMODO_NOTARY ) { + if ( STAKED_NOTARY_ID != -1 && IS_KOMODO_NOTARY == true ) { LogPrintf( "Cannot be STAKED and KMD notary at the same time!\n"); StartShutdown(); } std::string name = GetArg("-ac_name",""); if ( argv0 != 0 ) { - size_t len = strlen(argv0); - for (i=0; i matches suffix (%s) -> ac_name.(%s)\n",argv0,argv0suffix[i],argv0names[i]); @@ -1376,6 +1712,7 @@ void komodo_args(char *argv0) } } } + chainName = assetchain(name); KOMODO_STOPAT = GetArg("-stopat",0); MAX_REORG_LENGTH = GetArg("-maxreorg",MAX_REORG_LENGTH); WITNESS_CACHE_SIZE = MAX_REORG_LENGTH+10; @@ -1388,6 +1725,8 @@ void komodo_args(char *argv0) Split(GetArg("-ac_nk",""), sizeof(ASSETCHAINS_NK)/sizeof(*ASSETCHAINS_NK), ASSETCHAINS_NK, 0); // -ac_ccactivateht=evalcode,height,evalcode,height,evalcode,height.... + uint64_t ccEnablesHeight[512]; + memset(ccEnablesHeight, 0, sizeof(ccEnablesHeight)); Split(GetArg("-ac_ccactivateht",""), sizeof(ccEnablesHeight)/sizeof(*ccEnablesHeight), ccEnablesHeight, 0); // fill map with all eval codes and activation height of 0. for ( int i = 0; i < 256; i++ ) @@ -1415,11 +1754,13 @@ void komodo_args(char *argv0) } KOMODO_EARLYTXID = Parseuint256(GetArg("-earlytxid","0").c_str()); ASSETCHAINS_EARLYTXIDCONTRACT = GetArg("-ac_earlytxidcontract",0); - if ( name.c_str()[0] != 0 ) + + if ( !chainName.isKMD() ) { std::string selectedAlgo = GetArg("-ac_algo", std::string(ASSETCHAINS_ALGORITHMS[0])); - for ( int i = 0; i < ASSETCHAINS_NUMALGOS; i++ ) + uint32_t i; + for ( i = 0; i < ASSETCHAINS_NUMALGOS; i++ ) { if (std::string(ASSETCHAINS_ALGORITHMS[i]) == selectedAlgo) { @@ -1470,7 +1811,7 @@ void komodo_args(char *argv0) for ( int i = 0; i < ASSETCHAINS_MAX_ERAS; i++ ) { - if ( ASSETCHAINS_DECAY[i] == 100000000 && ASSETCHAINS_ENDSUBSIDY == 0 ) + if ( ASSETCHAINS_DECAY[i] == 100000000 && ASSETCHAINS_ENDSUBSIDY[i] == 0 ) { ASSETCHAINS_DECAY[i] = 0; LogPrintf("ERA%u: ASSETCHAINS_DECAY of 100000000 means linear and that needs ASSETCHAINS_ENDSUBSIDY\n", i); @@ -1499,31 +1840,15 @@ void komodo_args(char *argv0) ASSETCHAINS_SCRIPTPUB = GetArg("-ac_script",""); ASSETCHAINS_BEAMPORT = GetArg("-ac_beam",0); ASSETCHAINS_CODAPORT = GetArg("-ac_coda",0); - ASSETCHAINS_CBOPRET = GetArg("-ac_cbopret",0); ASSETCHAINS_CBMATURITY = GetArg("-ac_cbmaturity",0); ASSETCHAINS_ADAPTIVEPOW = GetArg("-ac_adaptivepow",0); - //fprintf(stderr,"ASSETCHAINS_CBOPRET.%llx\n",(long long)ASSETCHAINS_CBOPRET); - if ( ASSETCHAINS_CBOPRET != 0 ) - { - SplitStr(GetArg("-ac_prices",""), ASSETCHAINS_PRICES); - if ( ASSETCHAINS_PRICES.size() > 0 ) - ASSETCHAINS_CBOPRET |= 4; - SplitStr(GetArg("-ac_stocks",""), ASSETCHAINS_STOCKS); - if ( ASSETCHAINS_STOCKS.size() > 0 ) - ASSETCHAINS_CBOPRET |= 8; - for (i=0; i Mineropret; + if ( hexstr.size() != 0 ) { Mineropret.resize(hexstr.size()/2); - decode_hex(Mineropret.data(),hexstr.size()/2,hexstr.c_str()); - for (i=0; i 0 ) { - for (i=0; i<256; i++) + // disable all CCs + for (uint16_t i=0; i<256; i++) { ASSETCHAINS_CCDISABLES[i] = 1; SETBIT(disablebits,i); } - for (i=0; i 0 ) - { - for (i=first; i<=last; i++) - { - CLEARBIT(disablebits,i); - ASSETCHAINS_CCDISABLES[i] = 0; - } - }*/ } if ( ASSETCHAINS_BEAMPORT != 0 ) { @@ -1590,7 +1909,7 @@ void komodo_args(char *argv0) { if (ASSETCHAINS_BEAMPORT == 0) { - fprintf(stderr,"missing -ac_beam for BEAM rpcport\n"); + LogPrintf("missing -ac_beam for BEAM rpcport\n"); StartShutdown(); } } @@ -1598,7 +1917,7 @@ void komodo_args(char *argv0) { if (ASSETCHAINS_CODAPORT == 0) { - fprintf(stderr,"missing -ac_coda for CODA rpcport\n"); + LogPrintf("missing -ac_coda for CODA rpcport\n"); StartShutdown(); } } @@ -1607,7 +1926,7 @@ void komodo_args(char *argv0) Split(GetArg("-ac_pegsccparams",""), sizeof(ASSETCHAINS_PEGSCCPARAMS)/sizeof(*ASSETCHAINS_PEGSCCPARAMS), ASSETCHAINS_PEGSCCPARAMS, 0); if (ASSETCHAINS_ENDSUBSIDY[0]!=1 || ASSETCHAINS_COMMISSION!=0) { - fprintf(stderr,"when using import for pegsCC these must be set: -ac_end=1 -ac_perc=0\n"); + LogPrintf("when using import for pegsCC these must be set: -ac_end=1 -ac_perc=0\n"); StartShutdown(); } } @@ -1645,7 +1964,7 @@ void komodo_args(char *argv0) } if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 ) { - decode_hex(ASSETCHAINS_OVERRIDE_PUBKEY33,33,ASSETCHAINS_OVERRIDE_PUBKEY.c_str()); + decode_hex(ASSETCHAINS_OVERRIDE_PUBKEY33,33,(char *)ASSETCHAINS_OVERRIDE_PUBKEY.c_str()); calc_rmd160_sha256(ASSETCHAINS_OVERRIDE_PUBKEYHASH,ASSETCHAINS_OVERRIDE_PUBKEY33,33); } if ( ASSETCHAINS_COMMISSION == 0 && ASSETCHAINS_FOUNDERS != 0 ) @@ -1679,21 +1998,37 @@ void komodo_args(char *argv0) LogPrintf("ASSETCHAINS_FOUNDERS needs an ASSETCHAINS_OVERRIDE_PUBKEY or ASSETCHAINS_SCRIPTPUB\n"); } } - if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 - || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 - || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 - || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 - || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF - || ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LASTERA > 0 - || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || nonz > 0 - || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 - || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 - || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) || KOMODO_SNAPSHOT_INTERVAL != 0 - || ASSETCHAINS_EARLYTXIDCONTRACT != 0 || ASSETCHAINS_CBMATURITY != 0 || ASSETCHAINS_ADAPTIVEPOW != 0 ) - { - LogPrintf("perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100, - ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2], - (int32_t)ASSETCHAINS_SCRIPTPUB.size()); + if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 + || ASSETCHAINS_REWARD[0] != 0 + || ASSETCHAINS_HALVING[0] != 0 + || ASSETCHAINS_DECAY[0] != 0 + || ASSETCHAINS_COMMISSION != 0 + || ASSETCHAINS_PUBLIC != 0 + || ASSETCHAINS_PRIVATE != 0 + || ASSETCHAINS_TXPOW != 0 + || ASSETCHAINS_FOUNDERS != 0 + || ASSETCHAINS_SCRIPTPUB.size() > 1 + || ASSETCHAINS_SELFIMPORT.size() > 0 + || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 + || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF + || ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH + || ASSETCHAINS_LASTERA > 0 + || ASSETCHAINS_BEAMPORT != 0 + || ASSETCHAINS_CODAPORT != 0 + || nonz > 0 + || ASSETCHAINS_CCLIB.size() > 0 + || ASSETCHAINS_FOUNDERS_REWARD != 0 + || ASSETCHAINS_NOTARY_PAY[0] != 0 + || ASSETCHAINS_BLOCKTIME != 60 + || Mineropret.size() != 0 + || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) + || KOMODO_SNAPSHOT_INTERVAL != 0 + || ASSETCHAINS_EARLYTXIDCONTRACT != 0 + || ASSETCHAINS_CBMATURITY != 0 + || ASSETCHAINS_ADAPTIVEPOW != 0 ) + { + uint8_t extrabuf[32756]; + LogPrintf("perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2],(int32_t)ASSETCHAINS_SCRIPTPUB.size()); extraptr = extrabuf; memcpy(extraptr,ASSETCHAINS_OVERRIDE_PUBKEY33,33), extralen = 33; @@ -1746,21 +2081,20 @@ void komodo_args(char *argv0) extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_FOUNDERS),(void *)&ASSETCHAINS_FOUNDERS); if ( ASSETCHAINS_FOUNDERS_REWARD != 0 ) { - LogPrintf( "set founders reward.%li\n",ASSETCHAINS_FOUNDERS_REWARD); + LogPrintf( "set founders reward.%lld\n",(long long)ASSETCHAINS_FOUNDERS_REWARD); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_FOUNDERS_REWARD),(void *)&ASSETCHAINS_FOUNDERS_REWARD); } } if ( ASSETCHAINS_SCRIPTPUB.size() > 1 ) { - decode_hex(&extraptr[extralen],ASSETCHAINS_SCRIPTPUB.size()/2,ASSETCHAINS_SCRIPTPUB.c_str()); + decode_hex(&extraptr[extralen],ASSETCHAINS_SCRIPTPUB.size()/2,(char *)ASSETCHAINS_SCRIPTPUB.c_str()); extralen += ASSETCHAINS_SCRIPTPUB.size()/2; - //extralen += iguana_rwnum(1,&extraptr[extralen],(int32_t)ASSETCHAINS_SCRIPTPUB.size(),(void *)ASSETCHAINS_SCRIPTPUB.c_str()); LogPrintf("append ac_script %s\n",ASSETCHAINS_SCRIPTPUB.c_str()); } if ( ASSETCHAINS_SELFIMPORT.size() > 0 ) { memcpy(&extraptr[extralen],(char *)ASSETCHAINS_SELFIMPORT.c_str(),ASSETCHAINS_SELFIMPORT.size()); - for (i=0; i 1 ) { - for (i=0; i 0 ) + // ASSETCHAINS_SEED = 1; MAX_MONEY = komodo_max_money(); - int32_t baseid; - if ( (baseid = komodo_baseid(ASSETCHAINS_SYMBOL)) >= 0 && baseid < 32 ) + if ( (baseid = komodo_baseid(chainName.symbol().c_str())) >= 0 && baseid < 32 ) { - LogPrintf("baseid.%d MAX_MONEY.%s %.8f\n",baseid,ASSETCHAINS_SYMBOL,(double)MAX_MONEY/SATOSHIDEN); + LogPrintf("baseid.%d MAX_MONEY.%s %.8f\n",baseid,chainName.symbol().c_str(),(double)MAX_MONEY/SATOSHIDEN); } if ( ASSETCHAINS_CC >= KOMODO_FIRSTFUNGIBLEID && MAX_MONEY < 1000000LL*SATOSHIDEN ) @@ -1859,15 +2162,17 @@ void komodo_args(char *argv0) if ( KOMODO_BIT63SET(MAX_MONEY) != 0 ) MAX_MONEY = KOMODO_MAXNVALUE; LogPrintf("MAX_MONEY %llu %.8f\n",(long long)MAX_MONEY,(double)MAX_MONEY/SATOSHIDEN); - uint16_t tmpport = komodo_port(ASSETCHAINS_SYMBOL,ASSETCHAINS_SUPPLY,&ASSETCHAINS_MAGIC,extraptr,extralen); + uint16_t tmpport = komodo_port(chainName.symbol().c_str(),ASSETCHAINS_SUPPLY,&ASSETCHAINS_MAGIC,extraptr,extralen); if ( GetArg("-port",0) != 0 ) { ASSETCHAINS_P2PPORT = GetArg("-port",0); LogPrintf("set p2pport.%u\n",ASSETCHAINS_P2PPORT); - } else ASSETCHAINS_P2PPORT = tmpport; + } + else + ASSETCHAINS_P2PPORT = tmpport; - char *dirname; - while ( (dirname = (char *)GetDataDir(false).string().c_str()) == 0 || dirname[0] == 0 ) + char* dirname = nullptr; + while ( (dirname= (char *)GetDataDir(false).string().c_str()) == 0 || dirname[0] == 0 ) { LogPrintf("waiting for datadir (%s)\n",dirname); #ifndef _WIN32 @@ -1876,113 +2181,77 @@ void komodo_args(char *argv0) boost::this_thread::sleep(boost::posix_time::milliseconds(3000)); #endif } - if ( ASSETCHAINS_SYMBOL[0] != 0 ) + if ( !chainName.isKMD() ) { - int32_t komodo_baseid(char *origbase); - extern int COINBASE_MATURITY; - if ( strcmp(ASSETCHAINS_SYMBOL,"KMD") == 0 ) + if ( chainName.isSymbol("KMD") ) { - LogPrintf("cant have assetchain named KMD\n"); + LogPrintf("can't have assetchain named KMD\n"); StartShutdown(); } uint16_t port; - if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,ASSETCHAINS_SYMBOL)) != 0 ) + if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,chainName.symbol().c_str())) != 0 ) ASSETCHAINS_RPCPORT = port; - else komodo_configfile(ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT + 1); + else komodo_configfile(chainName.symbol().c_str(),ASSETCHAINS_P2PPORT + 1); if (ASSETCHAINS_CBMATURITY != 0) - COINBASE_MATURITY = ASSETCHAINS_CBMATURITY; - else if (ASSETCHAINS_LASTERA == 0 || is_STAKED(ASSETCHAINS_SYMBOL) != 0) - COINBASE_MATURITY = 1; - if (COINBASE_MATURITY < 1) + Params().SetCoinbaseMaturity(ASSETCHAINS_CBMATURITY); + else if (ASSETCHAINS_LASTERA == 0 || is_STAKED(chainName.symbol()) != 0) + Params().SetCoinbaseMaturity(1); + if (Params().CoinbaseMaturity() < 1) { LogPrintf("ac_cbmaturity must be >0, shutting down\n"); StartShutdown(); } - //fprintf(stderr,"ASSETCHAINS_RPCPORT (%s) %u\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_RPCPORT); } if ( ASSETCHAINS_RPCPORT == 0 ) ASSETCHAINS_RPCPORT = ASSETCHAINS_P2PPORT + 1; uint8_t magic[4]; iguana_rwnum(1,magic,sizeof(ASSETCHAINS_MAGIC),(void *)&ASSETCHAINS_MAGIC); + char magicstr[9]; + for (i=0; i<4; i++) + sprintf(&magicstr[i<<1],"%02x",magic[i]); + magicstr[8] = 0; #ifndef FROM_CLI - std::string fname = std::string(ASSETCHAINS_SYMBOL) + "_7776"; - FILE* fp; - if ( (fp= fopen(fname.c_str(),"wb")) != 0 ) - { - char magicstr[9]; - for (i=0; i<4; i++) - sprintf(&magicstr[i<<1],"%02x",magic[i]); - magicstr[8] = 0; + char fname[512]; + sprintf(fname,"%s_7776",chainName.symbol().c_str()); + if ( (fp= fopen(fname,"wb")) != 0 ) + { int8_t notarypay = 0; if ( ASSETCHAINS_NOTARY_PAY[0] != 0 ) notarypay = 1; + char *iguanafmtstr = (char *)"curl --url \"http://127.0.0.1:7776\" --data \"{\\\"conf\\\":\\\"%s.conf\\\",\\\"path\\\":\\\"${HOME#\"/\"}/.komodo/%s\\\",\\\"unitval\\\":\\\"20\\\",\\\"zcash\\\":1,\\\"RELAY\\\":-1,\\\"VALIDATE\\\":0,\\\"prefetchlag\\\":-1,\\\"poll\\\":100,\\\"active\\\":1,\\\"agent\\\":\\\"iguana\\\",\\\"method\\\":\\\"addcoin\\\",\\\"startpend\\\":4,\\\"endpend\\\":4,\\\"services\\\":129,\\\"maxpeers\\\":8,\\\"newcoin\\\":\\\"%s\\\",\\\"name\\\":\\\"%s\\\",\\\"hasheaders\\\":1,\\\"useaddmultisig\\\":0,\\\"netmagic\\\":\\\"%s\\\",\\\"p2p\\\":%u,\\\"rpc\\\":%u,\\\"pubval\\\":60,\\\"p2shval\\\":85,\\\"wifval\\\":188,\\\"txfee_satoshis\\\":\\\"10000\\\",\\\"isPoS\\\":0,\\\"minoutput\\\":10000,\\\"minconfirms\\\":2,\\\"genesishash\\\":\\\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\\\",\\\"protover\\\":170002,\\\"genesisblock\\\":\\\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\\\",\\\"debug\\\":0,\\\"seedipaddr\\\":\\\"%s\\\",\\\"sapling\\\":1,\\\"notarypay\\\":%i}\""; fprintf(fp,iguanafmtstr,name.c_str(),name.c_str(),name.c_str(),name.c_str(),magicstr,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,"78.47.196.146",notarypay); fclose(fp); - } else LogPrintf("error creating (%s)\n",fname.c_str()); + } else LogPrintf("error creating (%s)\n",fname); #endif if ( ASSETCHAINS_CC < 2 ) { if ( KOMODO_CCACTIVATE != 0 ) { ASSETCHAINS_CC = 2; - fprintf(stderr,"smart utxo CC contracts will activate at height.%d\n",KOMODO_CCACTIVATE); + LogPrintf("smart utxo CC contracts will activate at height.%d\n",KOMODO_CCACTIVATE); } else if ( ccEnablesHeight[0] != 0 ) { ASSETCHAINS_CC = 2; - fprintf(stderr,"smart utxo CC contract %d will activate at height.%d\n",(int32_t)ccEnablesHeight[0],(int32_t)ccEnablesHeight[1]); + LogPrintf("smart utxo CC contract %d will activate at height.%d\n",(int32_t)ccEnablesHeight[0],(int32_t)ccEnablesHeight[1]); } } } else { - char fname[512],username[512],password[4096]; - int32_t iter; - FILE *fp; - ASSETCHAINS_P2PPORT = 7770; - ASSETCHAINS_RPCPORT = 7771; - for (iter=0; iter<2; iter++) - { - strcpy(fname,GetDataDir().string().c_str()); -#ifdef _WIN32 - while ( fname[strlen(fname)-1] != '\\' ) - fname[strlen(fname)-1] = 0; - if ( iter == 0 ) - strcat(fname,"Komodo\\komodo.conf"); - else strcat(fname,ntz_dest_path.c_str()); -#else - while ( fname[strlen(fname)-1] != '/' ) - fname[strlen(fname)-1] = 0; -#ifdef __APPLE__ - if ( iter == 0 ) - strcat(fname,"Komodo/Komodo.conf"); - else strcat(fname,ntz_dest_path.c_str()); -#else - if ( iter == 0 ) - strcat(fname,".komodo/komodo.conf"); - else strcat(fname,ntz_dest_path.c_str()); -#endif -#endif - if ( (fp= fopen(fname,"rb")) != 0 ) - { - uint16_t dest_rpc_port = _komodo_userpass(username,password,fp); - DEST_PORT = iter == 1 ? dest_rpc_port : 0; - sprintf(iter == 0 ? KMDUSERPASS : BTCUSERPASS,"%s:%s",username,password); - fclose(fp); - } else LogPrintf("couldnt open.(%s) will not validate dest notarizations\n",fname); - if ( !IS_KOMODO_NOTARY ) - break; - } + // -ac_name not passed, we are on the KMD chain + set_kmd_user_password_port(ntz_dest_path); } int32_t dpowconfs = KOMODO_DPOWCONFS; - if ( ASSETCHAINS_SYMBOL[0] != 0 ) + if ( !chainName.isKMD() ) { BITCOIND_RPCPORT = GetArg("-rpcport", ASSETCHAINS_RPCPORT); - if ( strcmp("PIRATE",ASSETCHAINS_SYMBOL) == 0 && ASSETCHAINS_HALVING[0] == 77777 ) + //LogPrintf("(%s) port.%u chain params initialized\n",chainName.symbol().c_str(),BITCOIND_RPCPORT); + if ( chainName.isSymbol("PIRATE") && ASSETCHAINS_HALVING[0] == 77777 ) { ASSETCHAINS_HALVING[0] *= 5; - LogPrintf("PIRATE halving changed to %d %.1f days ASSETCHAINS_LASTERA.%lu\n",(int32_t)ASSETCHAINS_HALVING[0],(double)ASSETCHAINS_HALVING[0]/1440,ASSETCHAINS_LASTERA); + LogPrintf("PIRATE halving changed to %d %.1f days ASSETCHAINS_LASTERA.%llu\n",(int32_t)ASSETCHAINS_HALVING[0],(double)ASSETCHAINS_HALVING[0]/1440,(long long)ASSETCHAINS_LASTERA); } else if ( ASSETCHAINS_PRIVATE != 0 ) { @@ -1990,19 +2259,19 @@ void komodo_args(char *argv0) StartShutdown(); } // Set cc enables for all existing ac_cc chains here. - if ( strcmp("AXO",ASSETCHAINS_SYMBOL) == 0 ) + if ( chainName.isSymbol("AXO") ) { // No CCs used on this chain yet. CCDISABLEALL; } - if ( strcmp("CCL",ASSETCHAINS_SYMBOL) == 0 ) + if ( chainName.isSymbol("CCL") ) { // No CCs used on this chain yet. CCDISABLEALL; CCENABLE(EVAL_TOKENS); CCENABLE(EVAL_HEIR); } - if ( strcmp("COQUI",ASSETCHAINS_SYMBOL) == 0 ) + if ( chainName.isSymbol("COQUI") ) { CCDISABLEALL; CCENABLE(EVAL_DICE); @@ -2011,53 +2280,60 @@ void komodo_args(char *argv0) CCENABLE(EVAL_ASSETS); CCENABLE(EVAL_TOKENS); } - if ( strcmp("DION",ASSETCHAINS_SYMBOL) == 0 ) + if ( chainName.isSymbol("DION") ) { // No CCs used on this chain yet. CCDISABLEALL; } - if ( strcmp("EQL",ASSETCHAINS_SYMBOL) == 0 ) + if ( chainName.isSymbol("EQL") ) { // No CCs used on this chain yet. CCDISABLEALL; } - if ( strcmp("ILN",ASSETCHAINS_SYMBOL) == 0 ) + if ( chainName.isSymbol("ILN") ) { // No CCs used on this chain yet. CCDISABLEALL; } - if ( strcmp("OUR",ASSETCHAINS_SYMBOL) == 0 ) + if ( chainName.isSymbol("OUR") ) { // No CCs used on this chain yet. CCDISABLEALL; } - if ( strcmp("ZEXO",ASSETCHAINS_SYMBOL) == 0 ) + if ( chainName.isSymbol("ZEXO") ) { // No CCs used on this chain yet. CCDISABLEALL; } - if ( strcmp("SEC",ASSETCHAINS_SYMBOL) == 0 ) + if ( chainName.isSymbol("SEC") ) { CCDISABLEALL; CCENABLE(EVAL_ASSETS); CCENABLE(EVAL_TOKENS); CCENABLE(EVAL_ORACLES); } - if ( strcmp("KMDICE",ASSETCHAINS_SYMBOL) == 0 ) + if ( chainName.isSymbol("KMDICE") ) { CCDISABLEALL; CCENABLE(EVAL_FAUCET); CCENABLE(EVAL_DICE); CCENABLE(EVAL_ORACLES); } - } else BITCOIND_RPCPORT = GetArg("-rpcport", BaseParams().RPCPort()); + } + else + BITCOIND_RPCPORT = GetArg("-rpcport", BaseParams().RPCPort()); KOMODO_DPOWCONFS = GetArg("-dpowconfs",dpowconfs); - if ( ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"SUPERNET") == 0 || strcmp(ASSETCHAINS_SYMBOL,"DEX") == 0 || strcmp(ASSETCHAINS_SYMBOL,"COQUI") == 0 || strcmp(ASSETCHAINS_SYMBOL,"PIRATE") == 0 || strcmp(ASSETCHAINS_SYMBOL,"KMDICE") == 0 ) + if ( chainName.isKMD() + || chainName.isSymbol("SUPERNET") + || chainName.isSymbol("DEX") + || chainName.isSymbol("COQUI") + || chainName.isSymbol("PIRATE") + || chainName.isSymbol("KMDICE") ) KOMODO_EXTRASATOSHI = 1; } -void komodo_nameset(char *symbol,char *dest,char *source) +void komodo_nameset(char *symbol,char *dest,const char *source) { if ( source[0] == 0 ) { @@ -2071,49 +2347,61 @@ void komodo_nameset(char *symbol,char *dest,char *source) } } -struct komodo_state *komodo_stateptrget(char *base) +/**** + * @brief get the right komodo_state + * @param[in] base what to search for (nullptr == "KMD") + * @returns the correct komodo_state object + */ +komodo_state *komodo_stateptrget(char *base) { - int32_t baseid; + // "KMD" case if ( base == 0 || base[0] == 0 || strcmp(base,(char *)"KMD") == 0 ) - return(&KOMODO_STATES[33]); - else if ( (baseid= komodo_baseid(base)) >= 0 ) - return(&KOMODO_STATES[baseid+1]); - else return(&KOMODO_STATES[0]); + return &KOMODO_STATES[1]; + + // evidently this asset chain + return &KOMODO_STATES[0]; } -struct komodo_state *komodo_stateptr(char *symbol,char *dest) +/**** + * @brief get the symbol and dest based on this chain's ASSETCHAINS_SYMBOL + * @param[out] symbol this chain ("KMD" if ASSETCHAINS_SYMBOL is nullptr) + * @param[out] dest the destination chain ("BTC" in the case of KMD, otherwise "KMD") + * @returns the komodo_state object for symbol + */ +komodo_state *komodo_stateptr(char *symbol,char *dest) { int32_t baseid; - komodo_nameset(symbol,dest,ASSETCHAINS_SYMBOL); + komodo_nameset(symbol,dest,chainName.symbol().c_str()); return(komodo_stateptrget(symbol)); } -/* +/*** + * @brief prefetch file contents, leave next read position where it started + * @param fp the file to read + */ void komodo_prefetch(FILE *fp) { - long fsize,fpos; int32_t incr = 16*1024*1024; - fpos = ftell(fp); + // I am not sure why we do this, perhaps looking for disk errors or + // disk caching? - JMJ + int32_t incr = 16*1024*1024; + long fpos = ftell(fp); // store the current position fseek(fp,0,SEEK_END); - fsize = ftell(fp); - if ( fsize > incr ) + if ( ftell(fp) > incr ) // if the file is greater than 16MB { char *ignore = (char *)malloc(incr); if ( ignore != 0 ) { - rewind(fp); - while ( fread(ignore,1,incr,fp) == incr ) // prefetch - { - // LogPrintf("."); - } + rewind(fp); // go back to the beginning + while ( fread(ignore,1,incr,fp) == incr ) // prefetch in 16MB blocks + LogPrintf("."); free(ignore); } } - fseek(fp,fpos,SEEK_SET); + fseek(fp,fpos,SEEK_SET); // go to where we were when this function was called } -*/ // check if block timestamp is more than S5 activation time -// this function is to activate the ExtractDestination fix +// this function is to activate the ExtractDestination fix bool komodo_is_vSolutionsFixActive() { return GetLatestTimestamp(komodo_currentheight()) > nS5Timestamp; diff --git a/src/komodo_utils.h b/src/komodo_utils.h index f61c8723..c9796206 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -16,6 +16,7 @@ #include #include "komodo_defs.h" +#include "komodo_structs.h" #include "hex.h" #include "key_io.h" #include "cc/CCinclude.h" @@ -27,23 +28,13 @@ #include #endif -#define SATOSHIDEN ((uint64_t)100000000L) -#define dstr(x) ((double)(x) / SATOSHIDEN) +// #define SATOSHIDEN ((uint64_t)100000000L) +// #define dstr(x) ((double)(x) / SATOSHIDEN) #define portable_mutex_t pthread_mutex_t #define portable_mutex_init(ptr) pthread_mutex_init(ptr,NULL) #define portable_mutex_lock pthread_mutex_lock #define portable_mutex_unlock pthread_mutex_unlock -struct allocitem { uint32_t allocsize,type; }; -struct queueitem { struct queueitem *next,*prev; uint32_t allocsize,type; }; - -typedef struct queue -{ - struct queueitem *list; - pthread_mutex_t mutex; - char name[64],initflag; -} queue_t; - #include "mini-gmp.h" #define CRYPTO777_PUBSECPSTR "020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9" @@ -52,242 +43,12 @@ typedef struct queue #define KOMODO_PUBTYPE 60 -struct sha256_vstate { uint64_t length; uint32_t state[8],curlen; uint8_t buf[64]; }; struct rmd160_vstate { uint64_t length; uint8_t buf[64]; uint32_t curlen, state[5]; }; -// following is ported from libtom - -#define STORE32L(x, y) \ -{ (y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \ -(y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); } - -#define LOAD32L(x, y) \ -{ x = (uint32_t)(((uint64_t)((y)[3] & 255)<<24) | \ -((uint32_t)((y)[2] & 255)<<16) | \ -((uint32_t)((y)[1] & 255)<<8) | \ -((uint32_t)((y)[0] & 255))); } - -#define STORE64L(x, y) \ -{ (y)[7] = (uint8_t)(((x)>>56)&255); (y)[6] = (uint8_t)(((x)>>48)&255); \ -(y)[5] = (uint8_t)(((x)>>40)&255); (y)[4] = (uint8_t)(((x)>>32)&255); \ -(y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \ -(y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); } - -#define LOAD64L(x, y) \ -{ x = (((uint64_t)((y)[7] & 255))<<56)|(((uint64_t)((y)[6] & 255))<<48)| \ -(((uint64_t)((y)[5] & 255))<<40)|(((uint64_t)((y)[4] & 255))<<32)| \ -(((uint64_t)((y)[3] & 255))<<24)|(((uint64_t)((y)[2] & 255))<<16)| \ -(((uint64_t)((y)[1] & 255))<<8)|(((uint64_t)((y)[0] & 255))); } - -#define STORE32H(x, y) \ -{ (y)[0] = (uint8_t)(((x)>>24)&255); (y)[1] = (uint8_t)(((x)>>16)&255); \ -(y)[2] = (uint8_t)(((x)>>8)&255); (y)[3] = (uint8_t)((x)&255); } - -#define LOAD32H(x, y) \ -{ x = (uint32_t)(((uint64_t)((y)[0] & 255)<<24) | \ -((uint32_t)((y)[1] & 255)<<16) | \ -((uint32_t)((y)[2] & 255)<<8) | \ -((uint32_t)((y)[3] & 255))); } - -#define STORE64H(x, y) \ -{ (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255); \ -(y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255); \ -(y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255); \ -(y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); } - -#define LOAD64H(x, y) \ -{ x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ -(((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ -(((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ -(((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } - -// Various logical functions -#define RORc(x, y) ( ((((uint32_t)(x)&0xFFFFFFFFUL)>>(uint32_t)((y)&31)) | ((uint32_t)(x)<<(uint32_t)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) -#define S(x, n) RORc((x),(n)) -#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) -#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) -#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) -#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) -#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) -#define MIN(x, y) ( ((x)<(y))?(x):(y) ) - -static inline int32_t sha256_vcompress(struct sha256_vstate * md,uint8_t *buf) -{ - uint32_t S[8],W[64],t0,t1,i; - for (i=0; i<8; i++) // copy state into S - S[i] = md->state[i]; - for (i=0; i<16; i++) // copy the state into 512-bits into W[0..15] - LOAD32H(W[i],buf + (4*i)); - for (i=16; i<64; i++) // fill W[16..63] - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - -#define RND(a,b,c,d,e,f,g,h,i,ki) \ -t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ -t1 = Sigma0(a) + Maj(a, b, c); \ -d += t0; \ -h = t0 + t1; - - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); -#undef RND - for (i=0; i<8; i++) // feedback - md->state[i] = md->state[i] + S[i]; - return(0); -} - -#undef RORc -#undef Ch -#undef Maj -#undef S -#undef R -#undef Sigma0 -#undef Sigma1 -#undef Gamma0 -#undef Gamma1 - -static inline void sha256_vinit(struct sha256_vstate * md) -{ - md->curlen = 0; - md->length = 0; - md->state[0] = 0x6A09E667UL; - md->state[1] = 0xBB67AE85UL; - md->state[2] = 0x3C6EF372UL; - md->state[3] = 0xA54FF53AUL; - md->state[4] = 0x510E527FUL; - md->state[5] = 0x9B05688CUL; - md->state[6] = 0x1F83D9ABUL; - md->state[7] = 0x5BE0CD19UL; -} - -static inline int32_t sha256_vprocess(struct sha256_vstate *md,const uint8_t *in,uint64_t inlen) -{ - uint64_t n; int32_t err; - if ( md->curlen > sizeof(md->buf) ) - return(-1); - while ( inlen > 0 ) - { - if ( md->curlen == 0 && inlen >= 64 ) - { - if ( (err= sha256_vcompress(md,(uint8_t *)in)) != 0 ) - return(err); - md->length += 64 * 8, in += 64, inlen -= 64; - } - else - { - n = MIN(inlen,64 - md->curlen); - memcpy(md->buf + md->curlen,in,(size_t)n); - md->curlen += n, in += n, inlen -= n; - if ( md->curlen == 64 ) - { - if ( (err= sha256_vcompress(md,md->buf)) != 0 ) - return(err); - md->length += 8*64; - md->curlen = 0; - } - } - } - return(0); -} - -static inline int32_t sha256_vdone(struct sha256_vstate *md,uint8_t *out) -{ - int32_t i; - if ( md->curlen >= sizeof(md->buf) ) - return(-1); - md->length += md->curlen * 8; // increase the length of the message - md->buf[md->curlen++] = (uint8_t)0x80; // append the '1' bit - // if len > 56 bytes we append zeros then compress. Then we can fall back to padding zeros and length encoding like normal. - if ( md->curlen > 56 ) - { - while ( md->curlen < 64 ) - md->buf[md->curlen++] = (uint8_t)0; - sha256_vcompress(md,md->buf); - md->curlen = 0; - } - while ( md->curlen < 56 ) // pad upto 56 bytes of zeroes - md->buf[md->curlen++] = (uint8_t)0; - STORE64H(md->length,md->buf+56); // store length - sha256_vcompress(md,md->buf); - for (i=0; i<8; i++) // copy output - STORE32H(md->state[i],out+(4*i)); - return(0); -} - void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len); bits256 bits256_doublesha256(char *deprecated,uint8_t *data,int32_t datalen); -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return 0 if successful - */ -int rmd160_vinit(struct rmd160_vstate * md); - /** Process a block of memory though the hash @param md The hash state @@ -297,34 +58,20 @@ int rmd160_vinit(struct rmd160_vstate * md); */ int rmd160_vprocess (struct rmd160_vstate * md, const unsigned char *in, unsigned long inlen); -/** - Terminate the hash to get the digest - @param md The hash state - @param out [out] The destination of the hash (20 bytes) - @return 0 if successful - */ -int rmd160_vdone(struct rmd160_vstate * md, unsigned char *out); - -void calc_rmd160(char deprecated[41],uint8_t buf[20],uint8_t *msg,int32_t len); - uint32_t calc_crc32(uint32_t crc,const void *buf,size_t size); void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen); -int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); +int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],const char *coinaddr); char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len); -int32_t komodo_is_issuer(); - int32_t bitweight(uint64_t x); int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp); -int32_t komodo_scriptitemlen(int32_t *opretlenp,uint8_t *script); - int32_t komodo_opreturnscript(uint8_t *script,uint8_t type,uint8_t *opret,int32_t opretlen); // get a pseudo random number that is the same for each block individually at all times and different @@ -346,52 +93,35 @@ char *parse_conf_line(char *line,char *field); double OS_milliseconds(); -void lock_queue(queue_t *queue); - -void queue_enqueue(char *name,queue_t *queue,struct queueitem *item); - -struct queueitem *queue_dequeue(queue_t *queue); - -void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize); - -void *queue_free(queue_t *queue); - -void *queue_clone(queue_t *clone,queue_t *queue,int32_t size); - -int32_t queue_size(queue_t *queue); - -void iguana_initQ(queue_t *Q,char *name); - -uint16_t _komodo_userpass(char *username,char *password,FILE *fp); - -void komodo_statefname(char *fname,char *symbol,char *str); - -void komodo_configfile(char *symbol,uint16_t rpcport); - -uint16_t komodo_userpass(char *userpass,char *symbol); - -uint32_t komodo_assetmagic(char *symbol,uint64_t supply,uint8_t *extraptr,int32_t extralen); - -uint16_t komodo_assetport(uint32_t magic,int32_t extralen); - -uint16_t komodo_port(char *symbol,uint64_t supply,uint32_t *magicp,uint8_t *extraptr,int32_t extralen); +#define MAX_STATEFNAME 512 +void komodo_statefname(char *fname, const char *symbol, const char *str); int32_t komodo_whoami(char *pubkeystr,int32_t height,uint32_t timestamp); -uint64_t komodo_max_money(); - uint64_t komodo_ac_block_subsidy(int nHeight); -int8_t equihash_params_possible(uint64_t n, uint64_t k); - void komodo_args(char *argv0); -void komodo_nameset(char *symbol,char *dest,char *source); +/*** + * @brief given a source, calculate the symbol and dest + * @note if source == nullptr, the results will be KMD/BTC, otherwise source/KMD + * @param[out] symbol the symbol (i.e. "KMD") + * @param[out] dest the destination (i.e. "BTC") + * @param[in] source the source (i.e. "KMD") + */ +void komodo_nameset(char *symbol,char *dest,const char *source); -struct komodo_state *komodo_stateptrget(char *base); +/**** + * @brief get the right komodo_state + * @param[in] base what to search for (nullptr == "KMD") + * @returns the correct komodo_state object + */ +komodo_state *komodo_stateptrget(char *base); -struct komodo_state *komodo_stateptr(char *symbol,char *dest); +komodo_state *komodo_stateptr(char *symbol,char *dest); // check if block timestamp is more than S5 activation time // this function is to activate the ExtractDestination fix bool komodo_is_vSolutionsFixActive(); + +void set_kmd_user_password_port(const std::string& ltc_config_filename); diff --git a/src/main.cpp b/src/main.cpp index c5eeadee..f666612c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -53,6 +53,15 @@ #include "policy/fees.h" #include "notaries_staked.h" #include "komodo_extern_globals.h" +#include "komodo_gateway.h" +#include "komodo.h" +#include "komodo_notary.h" +#include "key_io.h" +#include "komodo_utils.h" +#include "komodo_bitcoind.h" +#include "komodo_interest.h" +#include "rpc/net.h" +#include "cc/CCinclude.h" #include #include @@ -83,14 +92,6 @@ using namespace std; #define TMPFILE_START 100000000 CCriticalSection cs_main; -extern uint8_t NOTARY_PUBKEY33[33]; -extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING,KOMODO_EXTRASATOSHI; -int32_t KOMODO_NEWBLOCKS; -int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block); -//void komodo_broadcast(CBlock *pblock,int32_t limit); -bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey); -void komodo_setactivation(int32_t height); -void komodo_pricesupdate(int32_t height,CBlock *pblock); BlockMap mapBlockIndex; CChain chainActive; @@ -238,7 +239,7 @@ namespace { * * Memory used: 1.7MB */ - boost::scoped_ptr recentRejects; + std::unique_ptr recentRejects; uint256 hashRecentRejectsChainTip; /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */ @@ -340,8 +341,12 @@ namespace { int GetHeight() { - CBlockIndex *pindex; - if ( (pindex= chainActive.Tip()) != 0 ) + CBlockIndex *pindex = nullptr; + { + LOCK(cs_main); + pindex = chainActive.Tip(); + } + if ( pindex != nullptr ) return pindex->nHeight; return 0; } @@ -523,8 +528,6 @@ namespace { // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to // download that next block if the window were 1 larger. - if ( ASSETCHAINS_CBOPRET != 0 && IsInitialBlockDownload() == 0 ) - BLOCK_DOWNLOAD_WINDOW = 1; int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW; int nMaxHeight = std::min(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1); NodeId waitingfor = -1; @@ -627,8 +630,8 @@ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& loc return chain.Genesis(); } -CCoinsViewCache *pcoinsTip = NULL; -CBlockTreeDB *pblocktree = NULL; +CCoinsViewCache *pcoinsTip = nullptr; +CBlockTreeDB *pblocktree = nullptr; // Komodo globals @@ -641,7 +644,7 @@ UniValue komodo_snapshot(int top) UniValue result(UniValue::VOBJ); if (fAddressIndex) { - if ( pblocktree != 0 ) { + if ( pblocktree != nullptr ) { result = pblocktree->Snapshot(top); } else { LogPrintf("null pblocktree start with -addressindex=1\n"); @@ -670,18 +673,18 @@ bool komodo_dailysnapshot(int32_t height) uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,undo_height,extraoffset; // NOTE: To make this 100% safe under all sync conditions, it should be using a notarized notarization, from the DB. // Under heavy reorg attack, its possible `komodo_notarized_height` can return a height that can't be found on chain sync. - // However, the DB can reorg the last notarization. By using 2 deep, we know 100% that the previous notarization cannot be reorged by online nodes, - // and as such will always be notarizing the same height. May need to check heights on scan back to make sure they are confirmed in correct order. + // However, the DB can reorg the last notarization. By using 2 deep, we know 100% that the previous notarization cannot be + // reorged by online nodes, and as such will always be notarizing the same height. May need to check heights on scan back + // to make sure they are confirmed in correct order. if ( (extraoffset= height % KOMODO_SNAPSHOT_INTERVAL) != 0 ) { // we are on chain init, and need to scan all the way back to the correct height, other wise our node will have a diffrent snapshot to online nodes. // use the notarizationsDB to scan back from the consesnus height to get the offset we need. - std::string symbol; Notarisation nota; - symbol.assign(ASSETCHAINS_SYMBOL); - if ( ScanNotarisationsDB(height-extraoffset, symbol, 100, nota) == 0 ) + Notarisation nota; + if ( ScanNotarisationsDB(height-extraoffset, chainName.symbol(), 100, nota) == 0 ) undo_height = height-extraoffset-reorglimit; - else undo_height = nota.second.height; - //LogPrintf( "height.%i-extraoffset.%i = startscanfrom.%i to get undo_height.%i\n", height, extraoffset, height-extraoffset, undo_height); + else + undo_height = nota.second.height; } else { @@ -959,6 +962,13 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) return true; } +/** + * Check if transaction is expired and can be included in a block with the + * specified height. Consensus critical. + * @param tx the transaction + * @param nBlockHeight the current block height + * @returns true if transaction is expired (mainly tx.expiryHeight > nBlockHeight) + */ bool IsExpiredTx(const CTransaction &tx, int nBlockHeight) { if (tx.nExpiryHeight == 0 || tx.IsCoinBase()) { @@ -1143,11 +1153,6 @@ bool ContextualCheckCoinbaseTransaction(int32_t slowflag,const CBlock *block,CBl } return(false); } - else if ( slowflag != 0 && ASSETCHAINS_CBOPRET != 0 && validateprices != 0 && nHeight > 0 && tx.vout.size() > 0 ) - { - if ( komodo_opretvalidate(block,previndex,nHeight,tx.vout[tx.vout.size()-1].scriptPubKey) < 0 ) - return(false); - } return(true); } @@ -1358,15 +1363,19 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState &state, libzcash::ProofVerifier& verifier,int32_t txIndex, int32_t numTxs) { - static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n; uint256 merkleroot; - if ( *(int32_t *)&array[0] == 0 ) - numbanned = komodo_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array))); - n = tx.vin.size(); - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) { - for (j=0; j= indallvouts) ) { @@ -1378,8 +1387,8 @@ bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState } } } - - + + uint256 merkleroot; if ( ASSETCHAINS_STAKED != 0 && komodo_newStakerActive(0, tiptime) != 0 && tx.vout.size() == 2 && DecodeStakingOpRet(tx.vout[1].scriptPubKey, merkleroot) != 0 ) { if ( numTxs == 0 || txIndex != numTxs-1 ) @@ -1408,28 +1417,6 @@ bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState } } -// ARRR notary exception -int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime) // from ac_private chains only -{ - int32_t season = getacseason(tiptime); - if ( NOTARY_ADDRESSES[season-1][0][0] == 0 ) - { - uint8_t pubkeys[64][33]; - komodo_notaries(pubkeys,0,tiptime); - } - if ( strcmp(coinaddr,CRYPTO777_KMDADDR) == 0 ) - return(1); - for (int32_t i = 0; i < NUM_KMD_NOTARIES; i++) - { - if ( strcmp(coinaddr,NOTARY_ADDRESSES[season-1][i]) == 0 ) - { - //LogPrintf( "coinaddr.%s notaryaddress[%i].%s\n",coinaddr,i,NOTARY_ADDRESSES[season-1][i]); - return(1); - } - } - return(0); -} - int32_t komodo_acpublic(uint32_t tiptime); bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransaction& tx, CValidationState &state) @@ -1774,19 +1761,29 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF return nMinFee; } - +/***** + * @brief Try to add transaction to memory pool + * @param pool + * @param state + * @param tx + * @param fLimitFree + * @param pfMissingInputs + * @param fRejectAbsurdFee + * @param dosLevel + * @returns true on success + */ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee, int dosLevel) { AssertLockHeld(cs_main); if (pfMissingInputs) *pfMissingInputs = false; uint32_t tiptime; - int flag=0,nextBlockHeight = chainActive.Height() + 1; + int nextBlockHeight = chainActive.Height() + 1; auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus()); if ( nextBlockHeight <= 1 || chainActive.Tip() == 0 ) tiptime = (uint32_t)time(NULL); - else tiptime = (uint32_t)chainActive.Tip()->nTime; -//LogPrintf("addmempool 0\n"); + else + tiptime = (uint32_t)chainActive.Tip()->nTime; // Node operator can choose to reject tx by number of transparent inputs static_assert(std::numeric_limits::max() >= std::numeric_limits::max(), "size_t too small"); size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0); @@ -1800,10 +1797,9 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return false; } } -//LogPrintf("addmempool 1\n"); auto verifier = libzcash::ProofVerifier::Strict(); - if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,chainActive.Tip()->nHeight+1, - chainActive.Tip()->GetMedianTimePast() + 777,0) < 0 ) + if ( chainName.isKMD() && chainActive.Tip() != nullptr + && komodo_validate_interest(tx,chainActive.Tip()->nHeight+1, chainActive.Tip()->GetMedianTimePast() + 777,0) < 0 ) { return error("%s: komodo_validate_interest failed txid.%s", __func__, tx.GetHash().ToString()); } @@ -1843,7 +1839,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa //LogPrintf("AcceptToMemoryPool reject non-final\n"); return state.DoS(0, false, REJECT_NONSTANDARD, "non-final"); } -//LogPrintf("addmempool 3\n"); // is it already in the memory pool? uint256 hash = tx.GetHash(); if (pool.exists(hash)) @@ -1861,7 +1856,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (pool.mapNextTx.count(outpoint)) { // Disable replacement feature for now - return false; + return state.Invalid(false, REJECT_CONFLICT, "txn-mempool-conflict"); } } BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { @@ -1878,7 +1873,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } } } -//LogPrintf("addmempool 4\n"); + { CCoinsView dummy; CCoinsViewCache view(&dummy); @@ -1939,7 +1934,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Bring the best block into scope view.GetBestBlock(); - nValueIn = view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx,chainActive.Tip()->nTime); + nValueIn = view.GetValueIn(GetHeight(),interest,tx); + // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool view.SetBackend(dummy); } @@ -1978,7 +1974,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } } } -//LogPrintf("addmempool 5\n"); + // Grab the branch ID we expect this transaction to commit to. We don't // yet know if it does, but if the entry gets added to the mempool, then // it has passed ContextualCheckInputs and therefore this is correct. @@ -2068,7 +2064,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa flag = 1; KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.Tip()->nHeight + 1; } -//LogPrintf("addmempool 7\n"); if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId)) { @@ -2102,12 +2097,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return true; } +/**** + * @brief Add a transaction to the memory pool without the checks of AcceptToMemoryPool + * @param pool the memory pool to add the transaction to + * @param tx the transaction + * @returns true + */ bool CCTxFixAcceptToMemPoolUnchecked(CTxMemPool& pool, const CTransaction &tx) { // called from CheckBlock which is in cs_main and mempool.cs locks already. auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); CTxMemPoolEntry entry(tx, 0, GetTime(), 0, chainActive.Height(), mempool.HasNoInputsOf(tx), false, consensusBranchId); - //LogPrintf( "adding %s to mempool from block %d\n",tx.GetHash().ToString().c_str(),chainActive.GetHeight()); pool.addUnchecked(tx.GetHash(), entry, false); return true; } @@ -2175,41 +2175,49 @@ struct CompareBlocksByHeightMain } }; -/*uint64_t myGettxout(uint256 hash,int32_t n) -{ - CCoins coins; - LOCK2(cs_main,mempool.cs); - CCoinsViewMemPool view(pcoinsTip, mempool); - if (!view.GetCoins(hash, coins)) - return(0); - if ( n < 0 || (unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() ) - return(0); - else return(coins.vout[n].nValue); -}*/ - -bool myAddtomempool(CTransaction &tx, CValidationState *pstate, bool fSkipExpiry) +/**** + * @brief add a transaction to the mempool + * @param[in] tx the transaction + * @param pstate where to store any error (can be nullptr) + * @param fSkipExpiry set to false to add to pool without many checks + * @returns true on success + */ +bool myAddtomempool(const CTransaction &tx, CValidationState *pstate, bool fSkipExpiry) { CValidationState state; - if (!pstate) + if (pstate == nullptr) pstate = &state; - CTransaction Ltx; bool fMissingInputs,fOverrideFees = false; - if ( mempool.lookup(tx.GetHash(),Ltx) == 0 ) + + CTransaction Ltx; + if ( mempool.lookup(tx.GetHash(),Ltx) == false ) // does not already exist { if ( !fSkipExpiry ) + { + bool fMissingInputs; + bool fOverrideFees = false; return(AcceptToMemoryPool(mempool, *pstate, tx, false, &fMissingInputs, !fOverrideFees, -1)); + } else return(CCTxFixAcceptToMemPoolUnchecked(mempool,tx)); } - else return(true); + return true; } +/***** + * @brief get a transaction by its hash (without locks) + * @param[in] hash what to look for + * @param[out] txOut the found transaction + * @param[out] hashBlock the hash of the block (all zeros if still in mempool) + * @returns true if found + */ bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) { memset(&hashBlock,0,sizeof(hashBlock)); if ( KOMODO_NSPV_SUPERLITE ) { - int64_t rewardsum = 0; int32_t i,retval,txheight,currentheight,height=0,vout = 0; - for (i=0; iReadTxIndex(hash, postx)) { + if (pblocktree->ReadTxIndex(hash, postx)) + { //LogPrintf("OpenBlockFile\n"); CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION); if (file.IsNull()) @@ -2275,10 +2285,16 @@ bool NSPV_myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &ha return false; } -/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */ +/** + * @brief Find a transaction (uses locks) + * @param[in] hash the transaction to look for + * @param[out] txOut the transaction found + * @param[out] hashBlock the block where the transaction was found (all zeros if found in mempool) + * @param[in] fAllowSlow true to continue searching even if there are no transaction indexes + * @returns true if found + */ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) { - CBlockIndex *pindexSlow = NULL; memset(&hashBlock,0,sizeof(hashBlock)); LOCK(cs_main); @@ -2309,7 +2325,10 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock } } - if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it + CBlockIndex *pindexSlow = nullptr; + + if (fAllowSlow) // use coin database to locate block that contains transaction, and scan it + { int nHeight = -1; { CCoinsViewCache &view = *pcoinsTip; @@ -2337,21 +2356,6 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock return false; } -/*char *komodo_getspendscript(uint256 hash,int32_t n) - { - CTransaction tx; uint256 hashBlock; - if ( !GetTransaction(hash,tx,hashBlock,true) ) - { - LogPrintf("null GetTransaction\n"); - return(0); - } - if ( n >= 0 && n < tx.vout.size() ) - return((char *)tx.vout[n].scriptPubKey.ToString().c_str()); - else LogPrintf("getspendscript illegal n.%d\n",n); - return(0); - }*/ - - ////////////////////////////////////////////////////////////////////////////// // // CBlock and CBlockIndex @@ -2427,18 +2431,10 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW) return true; } -//uint64_t komodo_moneysupply(int32_t height); -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; -extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1]; -extern uint32_t ASSETCHAINS_MAGIC; -extern uint64_t ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY; -extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE; -extern int32_t ASSETCHAINS_STAKED; - CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams) { int32_t numhalvings,i; uint64_t numerator; CAmount nSubsidy = 3 * COIN; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) { if ( nHeight == 1 ) return(100000000 * COIN); // ICO allocation @@ -2503,9 +2499,6 @@ bool IsInitialBlockDownload() return true; } - bool state; - arith_uint256 bigZero = arith_uint256(); - arith_uint256 minWork = UintToArith256(chainParams.GetConsensus().nMinimumChainWork); CBlockIndex *ptr = chainActive.Tip(); if (ptr == NULL) @@ -2513,12 +2506,13 @@ bool IsInitialBlockDownload() //LogPrintf("nullptr in IsInitialDownload\n"); return true; } + /* TODO: restore nMinimumChainWork rule for IBD */ if (0 && ptr->nChainWork < UintToArith256(chainParams.GetConsensus().nMinimumChainWork)) { LogPrintf("nChainWork insufficient in IsInitialDownload\n"); return true; } - state = ((chainActive.Height() < ptr->nHeight - 24*60) || + bool state = ((chainActive.Height() < ptr->nHeight - 24*60) || ptr->GetBlockTime() < (GetTime() - nMaxTipAge)); if ( KOMODO_INSYNC != 0 ) state = false; @@ -2799,7 +2793,7 @@ namespace Consensus { } // Ensure that coinbases are matured, no DoS as retry may work later - if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) { + if (nSpendHeight - coins->nHeight < ::Params().CoinbaseMaturity()) { return state.Invalid( error("CheckInputs(): tried to spend coinbase at depth %d/%d", nSpendHeight - coins->nHeight, (int32_t)COINBASE_MATURITY), REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); @@ -2819,7 +2813,7 @@ namespace Consensus { // Check for negative or overflow input values nValueIn += coins->vout[prevout.n].nValue; #ifdef KOMODO_ENABLE_INTEREST - if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 ) + if ( chainName.isKMD() && nSpendHeight > 60000 ) { if ( coins->vout[prevout.n].nValue >= 10*COIN ) { @@ -2937,45 +2931,6 @@ bool ContextualCheckInputs( return true; } - -/*bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector *pvChecks) - { - if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) { - LogPrintf("ContextualCheckInputs failure.0\n"); - return false; - } - - if (!tx.IsCoinBase()) - { - // While checking, GetBestBlock() refers to the parent block. - // This is also true for mempool checks. - CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second; - int nSpendHeight = pindexPrev->nHeight + 1; - for (unsigned int i = 0; i < tx.vin.size(); i++) - { - const COutPoint &prevout = tx.vin[i].prevout; - const CCoins *coins = inputs.AccessCoins(prevout.hash); - // Assertion is okay because NonContextualCheckInputs ensures the inputs - // are available. - assert(coins); - - // If prev is coinbase, check that it's matured - if (coins->IsCoinBase()) { - if ( ASSETCHAINS_SYMBOL[0] == 0 ) - COINBASE_MATURITY = _COINBASE_MATURITY; - if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) { - LogPrintf("ContextualCheckInputs failure.1 i.%d of %d\n",i,(int32_t)tx.vin.size()); - - return state.Invalid( - error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); - } - } - } - } - - return true; - }*/ - namespace { bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart) @@ -3398,6 +3353,16 @@ static int64_t nTimeTotal = 0; bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false); bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos); +/***** + * @brief Apply the effects of this block (with given index) on the UTXO set represented by coins + * @param block the block to add + * @param state the result status + * @param pindex where to insert the block + * @param view the chain + * @param fJustCheck do not actually modify, only do checks + * @param fcheckPOW + * @returns true on success + */ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW) { CDiskBlockPos blockPos; @@ -3656,8 +3621,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } if (!tx.IsCoinBase()) { - nFees += (stakeTxValue= view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx, - chainActive.Tip()->nTime) - valueout); + nFees += (stakeTxValue= view.GetValueIn(chainActive.Tip()->nHeight,interest,tx) - valueout); sum += interest; std::vector vChecks; @@ -3691,8 +3655,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } } - //if ( ASSETCHAINS_SYMBOL[0] == 0 ) - // komodo_earned_interest(pindex->nHeight,sum); CTxUndo undoDummy; if (i > 0) { blockundo.vtxundo.push_back(CTxUndo()); @@ -3740,7 +3702,7 @@ 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); blockReward += nFees + sum; - if ( ASSETCHAINS_SYMBOL[0] == 0 && pindex->nHeight >= KOMODO_NOTARIES_HEIGHT2) + if ( chainName.isKMD() && pindex->nHeight >= KOMODO_NOTARIES_HEIGHT2) blockReward -= sum; if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 ) //ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && @@ -3754,14 +3716,14 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin LogPrintf("checktoshis %.8f vs %.8f numvouts %d\n",dstr(checktoshis),dstr(block.vtx[0].vout[1].nValue),(int32_t)block.vtx[0].vout.size()); } } - if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->nHeight == 1 && block.vtx[0].GetValueOut() != blockReward) + if ( !chainName.isKMD() && pindex->nHeight == 1 && block.vtx[0].GetValueOut() != blockReward) { return state.DoS(100, error("ConnectBlock(): coinbase for block 1 pays wrong amount (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward), REJECT_INVALID, "bad-cb-amount"); } if ( block.vtx[0].GetValueOut() > blockReward+KOMODO_EXTRASATOSHI ) { - if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->nHeight >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward ) + if ( !chainName.isKMD() || pindex->nHeight >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward ) { //LogPrintf( "coinbase pays too much\n"); //sleepflag = true; @@ -4010,13 +3972,16 @@ void static UpdateTip(CBlockIndex *pindexNew) { // New best block nTimeBestReceived = GetTime(); mempool.AddTransactionsUpdated(1); - KOMODO_NEWBLOCKS++; double progress; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) { + + if ( chainName.isKMD() ) + { progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()); - } else { - int32_t longestchain = komodo_longestchain(); - progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0; + } + else + { + int32_t longestchain = komodo_longestchain(); + progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0; } LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__, @@ -4203,7 +4168,7 @@ int32_t komodo_activate_sapling(CBlockIndex *pindex) if ( prevtime <= KOMODO_SAPLING_ACTIVATION && blocktime > KOMODO_SAPLING_ACTIVATION ) { activation = height + 60; - LogPrintf("%s transition at %d (%d, %u) -> (%d, %u)\n",ASSETCHAINS_SYMBOL,height,prevht,prevtime,height,blocktime); + LogPrintf("%s transition at %d (%d, %u) -> (%d, %u)\n",chainName.symbol().c_str(),height,prevht,prevtime,height,blocktime); } if ( prevtime < KOMODO_SAPLING_ACTIVATION-3600*24 ) break; @@ -4215,7 +4180,7 @@ int32_t komodo_activate_sapling(CBlockIndex *pindex) if ( activation != 0 ) { komodo_setactivation(activation); - LogPrintf("%s sapling activation at %d\n",ASSETCHAINS_SYMBOL,activation); + LogPrintf("%s sapling activation at %d\n",chainName.symbol().c_str(),activation); ASSETCHAINS_SAPLING = activation; } return activation; @@ -4227,10 +4192,13 @@ static int64_t nTimeFlush = 0; static int64_t nTimeChainState = 0; static int64_t nTimePostConnect = 0; -/** - * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock - * corresponding to pindexNew, to bypass loading it again from disk. - * You probably want to call mempool.removeWithoutBranchId after this, with cs_main held. +/*** + * @brief Connect a new block to chainActive. + * @note You probably want to call mempool.removeWithoutBranchId after this, with cs_main held. + * @param[out] state holds the state + * @param pindexNew the new index + * @param pblock a pointer to a CBlock (nullptr will load it from disk) + * @returns true on success */ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) { @@ -4266,11 +4234,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * if (state.IsInvalid()) { InvalidBlockFound(pindexNew, state); - /*if ( ASSETCHAINS_CBOPRET != 0 ) - { - pindexNew->nStatus &= ~BLOCK_FAILED_MASK; - LogPrintf("reconsiderblock %d\n",(int32_t)pindexNew->nHeight); - }*/ } return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString()); } @@ -4329,8 +4292,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * komodo_broadcast(pblock,4);*/ if ( KOMODO_NSPV_FULLNODE ) { - if ( ASSETCHAINS_CBOPRET != 0 ) - komodo_pricesupdate(pindexNew->nHeight,pblock); if ( ASSETCHAINS_SAPLING <= 0 && pindexNew->nTime > KOMODO_SAPLING_ACTIVATION - 24*3600 ) komodo_activate_sapling(pindexNew); if ( ASSETCHAINS_CC != 0 && KOMODO_SNAPSHOT_INTERVAL != 0 && (pindexNew->nHeight % KOMODO_SNAPSHOT_INTERVAL) == 0 && pindexNew->nHeight >= KOMODO_SNAPSHOT_INTERVAL ) @@ -4482,7 +4443,7 @@ static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBloc "- " + strprintf(_("New tip: %s, height %d, work %s\n"), pindexMostWork->phashBlock->GetHex(), pindexMostWork->nHeight, pindexMostWork->nChainWork.GetHex()) + "- " + strprintf(_("Fork point: %s %s, height %d"), - ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->nHeight) + "\n\n" + + chainName.symbol().c_str(),pindexFork->phashBlock->GetHex(), pindexFork->nHeight) + "\n\n" + _("Please help, human!"); LogPrintf("*** %s\nif you launch with -maxreorg=%d it might be able to resolve this automatically", msg,reorgLength+10); LogPrintf("*** %s\nif you launch with -maxreorg=%d it might be able to resolve this automatically", msg.c_str(),reorgLength+10); @@ -4512,7 +4473,7 @@ static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBloc if ( !DisconnectTip(state) ) break; } - LogPrintf("reached rewind.%d, best to do: ./komodo-cli -ac_name=%s stop\n",KOMODO_REWIND,ASSETCHAINS_SYMBOL); + LogPrintf("reached rewind.%d, best to do: ./komodo-cli -ac_name=%s stop\n",KOMODO_REWIND,chainName.symbol().c_str()); #ifdef WIN32 boost::this_thread::sleep(boost::posix_time::milliseconds(20000)); #else @@ -4609,8 +4570,8 @@ static void NotifyHeaderTip() { * that is already loaded (to avoid loading it again from disk). */ bool ActivateBestChain(bool fSkipdpow, CValidationState &state, CBlock *pblock) { - CBlockIndex *pindexNewTip = NULL; - CBlockIndex *pindexMostWork = NULL; + CBlockIndex *pindexMostWork = nullptr; + CBlockIndex *pindexNewTip = nullptr; const CChainParams& chainParams = Params(); do { boost::this_thread::interruption_point(); @@ -4621,6 +4582,7 @@ bool ActivateBestChain(bool fSkipdpow, CValidationState &state, CBlock *pblock) const CBlockIndex *pindexFork; bool fInitialDownload; + int nNewHeight; // https://github.com/zcash/zcash/commit/c3646bdf886dcb65e75d9ed60d529c6e828161f3 { LOCK(cs_main); CBlockIndex *pindexOldTip = chainActive.Tip(); @@ -4636,6 +4598,7 @@ bool ActivateBestChain(bool fSkipdpow, CValidationState &state, CBlock *pblock) pindexNewTip = chainActive.Tip(); pindexFork = chainActive.FindFork(pindexOldTip); fInitialDownload = IsInitialBlockDownload(); + nNewHeight = chainActive.Height(); } // When we reach this point, we switched to a new tip (stored in pindexNewTip). @@ -4651,7 +4614,7 @@ bool ActivateBestChain(bool fSkipdpow, CValidationState &state, CBlock *pblock) if (nLocalServices & NODE_NETWORK) { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) - if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) + if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); } // Notify external listeners about the new tip. @@ -4660,9 +4623,8 @@ bool ActivateBestChain(bool fSkipdpow, CValidationState &state, CBlock *pblock) if (pindexFork != pindexNewTip) { uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip); } - -// } //else LogPrintf("initial download skips propagation\n"); - } while(pindexMostWork != chainActive.Tip()); +// } + } while(pindexMostWork != pindexNewTip); CheckBlockIndex(); // Write changes periodically to disk, after relay. @@ -5132,16 +5094,25 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, return true; } -int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime); -int32_t komodo_checkPOW(int64_t stakeTxValue,int32_t slowflag,CBlock *pblock,int32_t height); - +/**** + * @brief various checks of block validity + * @param[out] futureblockp pointer to the future block + * @param[in] height the new height + * @param[out] pindex the block index + * @param[in] block the block to check + * @param[out] state stores results + * @param[in] verifier verification routine + * @param[in] fCheckPOW pass true to check PoW + * @param[in] fCheckMerkleRoot pass true to check merkle root + * @returns true on success, on error, state will contain info + */ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state, libzcash::ProofVerifier& verifier, bool fCheckPOW, bool fCheckMerkleRoot) { - uint8_t pubkey33[33]; uint256 hash; uint32_t tiptime = (uint32_t)block.nTime; + uint8_t pubkey33[33]; uint32_t tiptime = (uint32_t)block.nTime; // These are checks that are independent of context. - hash = block.GetHash(); + uint256 hash = block.GetHash(); // Check that the header is valid (particularly PoW). This is mostly redundant with the call in AcceptBlockHeader. if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW)) { @@ -5151,7 +5122,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C return false; } } - if ( pindex != 0 && pindex->pprev != 0 ) + if ( pindex != nullptr && pindex->pprev != nullptr ) tiptime = (uint32_t)pindex->pprev->nTime; if ( fCheckPOW ) { @@ -5169,7 +5140,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW"); } - if ( height > nDecemberHardforkHeight && ASSETCHAINS_SYMBOL[0] == 0 ) // December 2019 hardfork + if ( height > nDecemberHardforkHeight && chainName.isKMD() ) // December 2019 hardfork { int32_t notaryid; int32_t special = komodo_chosennotary(¬aryid,height,pubkey33,tiptime); @@ -5297,7 +5268,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C if (nSigOps > MAX_BLOCK_SIGOPS) return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"), REJECT_INVALID, "bad-blk-sigops", true); - if ( fCheckPOW && komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 ) + if ( fCheckPOW && komodo_check_deposit(height,block) < 0 ) { //static uint32_t counter; //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 ) @@ -5341,7 +5312,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta int nHeight = pindexPrev->nHeight+1; // Check proof of work - if ( (ASSETCHAINS_SYMBOL[0] != 0 || nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) + if ( (!chainName.isKMD() || nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) { cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) << " for block #" << nHeight << endl; @@ -5432,7 +5403,7 @@ bool ContextualCheckBlock(int32_t slowflag,const CBlock& block, CValidationState const int32_t txheight = nHeight == 0 ? komodo_block2height((CBlock *)&block) : nHeight; /* HF22 - check interest validation against pindexPrev->GetMedianTimePast() + 777 */ - if (ASSETCHAINS_SYMBOL[0] == 0 && + if (chainName.isKMD() && consensusParams.nHF22Height != boost::none && txheight > consensusParams.nHF22Height.get() ) { if (pindexPrev) { @@ -5449,7 +5420,7 @@ bool ContextualCheckBlock(int32_t slowflag,const CBlock& block, CValidationState const CTransaction& tx = block.vtx[i]; // Interest validation - if (komodo_validate_interest(tx, txheight, cmptime, 0) < 0) + if (komodo_validate_interest(tx, txheight, cmptime) < 0) { LogPrintf("validate intrest failed for txnum.%i tx.%s\n", i, tx.ToString()); return error("%s: komodo_validate_interest failed", __func__); @@ -5578,8 +5549,16 @@ bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidat return true; } -uint256 Queued_reconsiderblock; - +/***** + * @brief + * @param futureblockp + * @param block + * @param state + * @param ppindex + * @param fRequested + * @param dbp + * @returns true if block accepted + */ bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) { const CChainParams& chainparams = Params(); @@ -5640,18 +5619,6 @@ bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, C LogPrintf("saplinght.%d tipht.%d blockht.%d cmp.%d\n",saplinght,(int32_t)tmpptr->nHeight,pindex->nHeight,pindex->nHeight < 0 || (pindex->nHeight >= saplinght && pindex->nHeight < saplinght+50000) || (tmpptr->nHeight > saplinght-720 && tmpptr->nHeight < saplinght+720)); if ( pindex->nHeight < 0 || (pindex->nHeight >= saplinght && pindex->nHeight < saplinght+50000) || (tmpptr->nHeight > saplinght-720 && tmpptr->nHeight < saplinght+720) ) *futureblockp = 1; - if ( ASSETCHAINS_CBOPRET != 0 ) - { - CValidationState tmpstate; CBlockIndex *tmpindex; int32_t ht,longest; - ht = (int32_t)pindex->nHeight; - longest = komodo_longestchain(); - if ( (longest == 0 || ht < longest-6) && (tmpindex=komodo_chainactive(ht)) != 0 ) - { - LogPrintf("reconsider height.%d, longest.%d\n",(int32_t)ht,longest); - if ( Queued_reconsiderblock == zeroid ) - Queued_reconsiderblock = pindex->GetBlockHash(); - } - } } if ( *futureblockp == 0 ) { @@ -5712,8 +5679,6 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned return (nFound >= nRequired); } -void komodo_currentheight_set(int32_t height); - CBlockIndex *komodo_ensure(CBlock *pblock, uint256 hash) { CBlockIndex *pindex = 0; @@ -5794,6 +5759,21 @@ CBlockIndex *oldkomodo_ensure(CBlock *pblock, uint256 hash) return(pindex); } +/***** + * @brief Process a new block + * @note can come from the network or locally mined + * @note This only returns after the best known valid + * block is made active. Note that it does not, however, guarantee that the + * specific block passed to it has been checked for validity! + * @param from_miner no longer used + * @param height the new height + * @param[out] state the results + * @param pfrom the node that produced the block (nullptr for local) + * @param pblock the block to process + * @param fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers. + * @param[out] dbp set to position on disk for block + * @returns true on success + */ bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp) { // Preliminary checks @@ -6316,7 +6296,7 @@ bool static LoadBlockIndexDB() PruneBlockIndexCandidates(); double progress; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) { + if ( chainName.isKMD() ) { progress = Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip()); } else { int32_t longestchain = komodo_longestchain(); @@ -6435,6 +6415,13 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth return true; } +/** + * When there are blocks in the active chain with missing data (e.g. if the + * activation height and branch ID of a particular upgrade have been altered), + * rewind the chainstate and remove them from the block index. + * @param params the chain parameters + * @returns true on success + */ bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches) { LOCK(cs_main); @@ -6625,11 +6612,14 @@ bool LoadBlockIndex() KOMODO_LOADINGBLOCKS = 0; return false; } - LogPrintf("finished loading blocks %s\n",ASSETCHAINS_SYMBOL); + LogPrintf("finished loading blocks %s\n",chainName.symbol().c_str()); return true; } - +/** + * Initialize a new block tree database + block data on disk + * @returns true on success + */ bool InitBlockIndex() { const CChainParams& chainparams = Params(); LOCK(cs_main); @@ -6642,7 +6632,7 @@ bool InitBlockIndex() { { return true; } - if ( pblocktree != 0 ) + if ( pblocktree != nullptr ) { // Use the provided setting for -txindex in the new database fTxIndex = GetBoolArg("-txindex", true); @@ -7260,6 +7250,7 @@ void static ProcessGetData(CNode* pfrom) #include "komodo_nSPV_superlite.h" // nSPV superlite client, issuing requests and handling nSPV responses #include "komodo_nSPV_wallet.h" // nSPV_send and support functions, really all the rest is to support this +void komodo_netevent(std::vector payload); bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived) { int32_t nProtocolVersion; @@ -7291,7 +7282,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, uint64_t nNonce = 1; int nVersion; // use temporary for version, don't set version number until validated as connected int minVersion = MIN_PEER_PROTO_VERSION; - if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 ) + if ( is_STAKED(chainName.symbol()) != 0 ) minVersion = STAKEDMIN_PEER_PROTO_VERSION; vRecv >> nVersion >> pfrom->nServices >> nTime >> addrMe; if (nVersion == 10300) @@ -7996,7 +7987,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // only KMD have checkpoints in sources, so, using IsInitialBlockDownload() here is // not applicable for assetchains (!) - if (GetBoolArg("-fixibd", false) && ASSETCHAINS_SYMBOL[0] == 0 && IsInitialBlockDownload()) { + if (GetBoolArg("-fixibd", false) && chainName.isKMD() && IsInitialBlockDownload()) { /** * This is experimental feature avaliable only for KMD during initial block download running with diff --git a/src/main.h b/src/main.h index a06a532d..a09ef3d8 100644 --- a/src/main.h +++ b/src/main.h @@ -66,7 +66,6 @@ class PrecomputedTransactionData; struct CNodeStateStats; #define DEFAULT_MEMPOOL_EXPIRY 1 -#define _COINBASE_MATURITY 100 /** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/ static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 2000000;//MAX_BLOCK_SIZE; @@ -78,7 +77,7 @@ static const bool DEFAULT_ALERTS = true; /** Minimum alert priority for enabling safe mode. */ static const int ALERT_PRIORITY_SAFE_MODE = 4000; /** Maximum reorg length we will accept before we shut down and alert the user. */ -static unsigned int MAX_REORG_LENGTH = _COINBASE_MATURITY - 1; +static unsigned int MAX_REORG_LENGTH = 100 - 1; // based on COINBASE_MATURITY /** Maximum number of signature check operations in an IsStandard() P2SH script */ static const unsigned int MAX_P2SH_SIGOPS = 15; /** The maximum number of sigops we're willing to relay/mine in a single tx */ @@ -203,17 +202,20 @@ void RegisterNodeSignals(CNodeSignals& nodeSignals); /** Unregister a network node */ void UnregisterNodeSignals(CNodeSignals& nodeSignals); -/** - * Process an incoming block. This only returns after the best known valid +/***** + * @brief Process a new block + * @note can come from the network or locally mined + * @note This only returns after the best known valid * block is made active. Note that it does not, however, guarantee that the * specific block passed to it has been checked for validity! - * - * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation. - * @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid. - * @param[in] pblock The block we want to process. - * @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers. - * @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location. - * @return True if state.IsValid() + * @param from_miner no longer used + * @param height the new height + * @param[out] state the results + * @param pfrom the node that produced the block (nullptr for local) + * @param pblock the block to process + * @param fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers. + * @param[out] dbp set to position on disk for block + * @returns true on success */ bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp); /** Check whether enough disk space is available for an incoming block */ @@ -226,11 +228,20 @@ FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false); boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix); /** Import blocks from an external file */ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL); -/** Initialize a new block tree database + block data on disk */ +/** + * Initialize a new block tree database + block data on disk + * @returns true on success + */ bool InitBlockIndex(); -/** Load the block tree and coins database from disk */ -bool LoadBlockIndex(); -/** Unload database information */ +/****** + * @brief Load the block tree and coins database from disk + * @param reindex true if we will be reindexing (will skip the load if we are) + * @returns true on success + */ +bool LoadBlockIndex(bool reindex); +/*** + * Clear all values related to the block index + */ void UnloadBlockIndex(); /** Process protocol messages received from a given node */ bool ProcessMessages(CNode* pfrom); @@ -253,7 +264,14 @@ bool IsInitialBlockDownload(); int IsNotInSync(); /** Format a string that describes several potential problems detected by the core */ std::string GetWarnings(const std::string& strFor); -/** Retrieve a transaction (from memory pool, or from disk, if possible) */ +/** + * @brief Find a transaction (uses locks) + * @param[in] hash the transaction to look for + * @param[out] txOut the transaction found + * @param[out] hashBlock the block where the transaction was found (all zeros if found in mempool) + * @param[in] fAllowSlow true to continue searching even if there are no transaction indexes + * @returns true if found + */ bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false); /** Find the best known block, and make it the tip of the block chain */ bool ActivateBestChain(bool fSkipdpow, CValidationState &state, CBlock *pblock = NULL); @@ -292,7 +310,17 @@ void FlushStateToDisk(); /** Prune block files and flush state to disk. */ void PruneAndFlush(); -/** (try to) add transaction to memory pool **/ +/** + * @brief Try to add transaction to memory pool + * @param pool + * @param state + * @param tx + * @param fLimitFree + * @param pfMissingInputs + * @param fRejectAbsurdFee + * @param dosLevel + * @returns true on success + */ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool* pfMissingInputs, bool fRejectAbsurdFee=false, int dosLevel=-1); @@ -747,6 +775,9 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime); /** * Check if transaction is expired and can be included in a block with the * specified height. Consensus critical. + * @param tx the transaction + * @param nBlockHeight the current block height + * @returns true if transaction is expired (mainly tx.expiryHeight > nBlockHeight) */ bool IsExpiredTx(const CTransaction &tx, int nBlockHeight); @@ -821,7 +852,16 @@ bool PruneOneBlockFile(bool tempfile, const int fileNumber); * of problems. Note that in any case, coins may be modified. */ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL); -/** Apply the effects of this block (with given index) on the UTXO set represented by coins */ +/***** + * @brief Apply the effects of this block (with given index) on the UTXO set represented by coins + * @param block the block to add + * @param state the result status + * @param pindex where to insert the block + * @param view the chain + * @param fJustCheck do not actually modify, only do checks + * @param fcheckPOW + * @returns true on success + */ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false,bool fCheckPOW = false); /** Context-independent validity checks */ @@ -847,17 +887,14 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp); bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL); - - /** * When there are blocks in the active chain with missing data (e.g. if the * activation height and branch ID of a particular upgrade have been altered), * rewind the chainstate and remove them from the block index. - * - * clearWitnessCaches is an output parameter that will be set to true iff - * witness caches should be cleared in order to handle an intended long rewind. + * @param params the chain parameters + * @returns true on success */ -bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches); +bool RewindBlockIndex(const CChainParams& params); class CBlockFileInfo { @@ -931,7 +968,11 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex); bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex); /** The currently-connected chain of blocks (protected by cs_main). */ +#ifdef DEBUG_LOCKORDER +extern MultithreadedCChain chainActive; +#else extern CChain chainActive; +#endif /** Global variable that points to the active CCoinsView (protected by cs_main) */ extern CCoinsViewCache *pcoinsTip; @@ -951,4 +992,7 @@ uint64_t CalculateCurrentUsage(); /** Return a CMutableTransaction with contextual default values based on set of consensus rules at height */ CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight); +int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime); // from ac_private chains only +bool komodo_dailysnapshot(int32_t height); + #endif // BITCOIN_MAIN_H diff --git a/src/metrics.cpp b/src/metrics.cpp index 1901e7a2..3d057b6e 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -27,6 +27,8 @@ #include "utiltime.h" #include "utilmoneystr.h" #include "utilstrencodings.h" +#include "komodo_utils.h" +#include "komodo_globals.h" #include #include @@ -40,7 +42,6 @@ #include #include "komodo_defs.h" -int64_t komodo_block_unlocktime(uint32_t nHeight); void AtomicTimer::start() { @@ -365,7 +366,7 @@ int printMetrics(size_t cols, bool mining) subsidy -= subsidy/5; } - if ((std::max(0, COINBASE_MATURITY - (tipHeight - height)) > 0) || + if ((std::max( 0U, Params().CoinbaseMaturity() - (tipHeight - height)) > 0) || (tipHeight < komodo_block_unlocktime(height) && subsidy >= ASSETCHAINS_TIMELOCKGTE)) { immature += subsidy; } else { diff --git a/src/miner.cpp b/src/miner.cpp index 53aff8d4..b9ef946d 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -20,6 +20,12 @@ #include "pubkey.h" #include "miner.h" +#include "komodo_utils.h" +#include "komodo_globals.h" +#include "komodo_bitcoind.h" +#include "komodo_gateway.h" +#include "komodo_defs.h" +#include "cc/CCinclude.h" #ifdef ENABLE_MINING #include "pow/tromp/equi_miner.h" #endif @@ -59,6 +65,8 @@ #include "notaries_staked.h" //#include "komodo_notary.h" +#include "komodo_bitcoind.h" +#include "komodo_extern_globals.h" #include #include @@ -137,57 +145,45 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, } } -#include "komodo_defs.h" -#include "cc/CCinclude.h" - extern CCriticalSection cs_metrics; -void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len); uint32_t Mining_start,Mining_height; int32_t My_notaryid = -1; -int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); -int32_t komodo_pax_opreturn(int32_t height,uint8_t *opret,int32_t maxsize); -int32_t komodo_baseid(char *origbase); -int32_t komodo_longestchain(); -int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag); -int64_t komodo_block_unlocktime(uint32_t nHeight); -uint64_t komodo_commission(const CBlock *block,int32_t height); -int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig, uint256 merkleroot); -uint256 komodo_calcmerkleroot(CBlock *pblock, uint256 prevBlockHash, int32_t nHeight, bool fNew, CScript scriptPubKey); -int32_t komodo_newStakerActive(int32_t height, uint32_t timestamp); -int32_t komodo_notaryvin(CMutableTransaction &txNew, uint8_t *notarypub33, const CScript &opretIn, uint32_t nLockTimeIn); -int32_t komodo_is_notarytx(const CTransaction& tx); -uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &NotarisationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len); -int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); -int32_t komodo_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *script, int32_t len); -CScript komodo_mineropret(int32_t nHeight); -bool komodo_appendACscriptpub(); -CScript komodo_makeopret(CBlock *pblock, bool fNew); int32_t komodo_waituntilelegible(uint32_t blocktime, int32_t stakeHeight, uint32_t delay) { int64_t adjustedtime = (int64_t)GetTime(); while ( (int64_t)blocktime-ASSETCHAINS_STAKED_BLOCK_FUTURE_MAX > adjustedtime ) { + boost::this_thread::interruption_point(); // allow to interrupt int64_t secToElegible = (int64_t)blocktime-ASSETCHAINS_STAKED_BLOCK_FUTURE_MAX-adjustedtime; if ( delay <= ASSETCHAINS_STAKED_BLOCK_FUTURE_HALF && secToElegible <= ASSETCHAINS_STAKED_BLOCK_FUTURE_HALF ) break; if ( (rand() % 100) < 2-(secToElegible>ASSETCHAINS_STAKED_BLOCK_FUTURE_MAX) ) - LogPrintf( "[%s:%i] %llds until elegible...\n", ASSETCHAINS_SYMBOL, stakeHeight, (long long)secToElegible); + LogPrintf( "[%s:%i] %llds until elegible...\n", chainName.symbol().c_str(), stakeHeight, (long long)secToElegible); if ( chainActive.Tip()->nHeight >= stakeHeight ) { - LogPrintf( "[%s:%i] Chain advanced, reset staking loop.\n", ASSETCHAINS_SYMBOL, stakeHeight); + LogPrintf( "[%s:%i] Chain advanced, reset staking loop.\n", chainName.symbol().c_str(), stakeHeight); return(0); } if( !GetBoolArg("-gen",false) ) return(0); - sleep(1); + //sleep(1); + boost::this_thread::sleep_for(boost::chrono::seconds(1)); // allow to interrupt adjustedtime = (int64_t)GetTime(); } return(1); } -CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake) +/***** + * @breif Generate a new block based on mempool txs, without valid proof-of-work + * @param _pk the public key + * @param _scriptPubKeyIn the script for the public key + * @param gpucount assists in calculating the block's nTime + * @param isStake + * @returns the block template + */ +CBlockTemplate* CreateNewBlock(const CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake) { CScript scriptPubKeyIn(_scriptPubKeyIn); @@ -204,10 +200,12 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 } } else pk = _pk; - uint64_t deposits; int32_t isrealtime,kmdheight; uint32_t blocktime; const CChainParams& chainparams = Params(); - bool fNotarisationBlock = false; std::vector NotarisationNotaries; - //LogPrintf("create new block\n"); + uint32_t blocktime; + const CChainParams& chainparams = Params(); + bool fNotarisationBlock = false; + std::vector NotarisationNotaries; + // Create new block if ( gpucount < 0 ) gpucount = KOMODO_MAXGPUCOUNT; @@ -228,10 +226,15 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 pblocktemplate->vTxFees.push_back(-1); // updated at end pblocktemplate->vTxSigOps.push_back(-1); // updated at end + CBlockIndex *tipindex = nullptr; + { + LOCK(cs_main); + tipindex = chainActive.Tip(); + } // Largest block you're willing to create: - unsigned int nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE(chainActive.Tip()->nHeight+1)); + unsigned int nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE(tipindex->nHeight+1)); // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: - nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE(chainActive.Tip()->nHeight+1)-1000), nBlockMaxSize)); + nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE(tipindex->nHeight+1)-1000), nBlockMaxSize)); // How much of the block should be dedicated to high-priority transactions, // included regardless of the fees they pay @@ -271,7 +274,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 { proposedTime = GetTime(); if (proposedTime == nMedianTimePast) - MilliSleep(10); + MilliSleep(10); // allow to interrupt } } pblock->nTime = GetTime(); @@ -284,8 +287,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 } CCoinsViewCache view(pcoinsTip); - uint32_t expired; uint64_t commission; - + SaplingMerkleTree sapling_tree; assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree)); @@ -322,7 +324,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 /* HF22 - check interest validation against pindexPrev->GetMedianTimePast() + 777 */ uint32_t cmptime = (uint32_t)pblock->nTime; - if (ASSETCHAINS_SYMBOL[0] == 0 && + if (chainName.isKMD() && consensusParams.nHF22Height != boost::none && nHeight > consensusParams.nHF22Height.get() ) { uint32_t cmptime_old = cmptime; @@ -331,7 +333,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 LogPrint("hfnet","%s[%d]: ht.%ld\n", __func__, __LINE__, nHeight); } - if (ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx, nHeight, cmptime, 0) < 0) + if (chainName.isKMD() && komodo_validate_interest(tx, nHeight, cmptime, 0) < 0) { LogPrintf("%s: komodo_validate_interest failure txid.%s nHeight.%d nTime.%u vs locktime.%u (cmptime.%lu)\n", __func__, tx.GetHash().ToString(), nHeight, (uint32_t)pblock->nTime, (uint32_t)tx.nLockTime, cmptime); continue; @@ -576,8 +578,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 //LogPrintf("dont have inputs\n"); continue; } - CAmount nTxFees = view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx, - chainActive.Tip()->nTime)-tx.GetValueOut(); + CAmount nTxFees = view.GetValueIn(chainActive.Tip()->nHeight, interest, tx) - tx.GetValueOut(); nTxSigOps += GetP2SHSigOpCount(tx, view); if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1) @@ -638,14 +639,13 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 if ( ASSETCHAINS_ADAPTIVEPOW <= 0 ) blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetTime()); else blocktime = 1 + std::max((int64_t)(pindexPrev->nTime+1), GetTime()); - //pblock->nTime = blocktime + 1; + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); - //LogPrintf( "nBits.%u\n",pblock->nBits); int32_t stakeHeight = chainActive.Height() + 1; //LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x stake.%i\n", nBlockSize,blocktime,pblock->nBits,isStake); - if ( ASSETCHAINS_SYMBOL[0] != 0 && isStake ) + if ( !chainName.isKMD() && isStake ) { LEAVE_CRITICAL_SECTION(cs_main); LEAVE_CRITICAL_SECTION(mempool.cs); @@ -703,22 +703,19 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 txNew.vout[0].scriptPubKey = scriptPubKeyIn; txNew.vout[0].nValue = GetBlockSubsidy(nHeight,consensusParams) + nFees; txNew.nExpiryHeight = 0; - //LogPrintf( "coinbase txid.%s\n", txNew.GetHash().ToString().c_str()); - //LogPrintf( "MINER: coinbasetx.%s\n", EncodeHexTx(txNew).c_str()); - //LogPrintf("mine ht.%d with %.8f\n",nHeight,(double)txNew.vout[0].nValue/COIN); - - //if ((uint32_t)chainActive.Tip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) { + if ( ASSETCHAINS_ADAPTIVEPOW <= 0 ) txNew.nLockTime = std::max(pindexPrev->GetMedianTimePast()+1, GetTime()); else txNew.nLockTime = std::max((int64_t)(pindexPrev->nTime+1), GetTime()); - if ( ASSETCHAINS_SYMBOL[0] == 0 && IS_KOMODO_NOTARY && My_notaryid >= 0 ) + if ( chainName.isKMD() && IS_KOMODO_NOTARY && My_notaryid >= 0 ) txNew.vout[0].nValue += 5000; pblock->vtx[0] = txNew; - if ( nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && (ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1) && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0) && (commission= komodo_commission((CBlock*)&pblocktemplate->block,(int32_t)nHeight)) != 0 ) + uint64_t commission; + if ( nHeight > 1 && !chainName.isKMD() && (ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1) && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0) && (commission= komodo_commission((CBlock*)&pblocktemplate->block,(int32_t)nHeight)) != 0 ) { - int32_t i; uint8_t *ptr; + uint8_t *ptr; txNew.vout.resize(2); txNew.vout[1].nValue = commission; if ( ASSETCHAINS_SCRIPTPUB.size() > 1 ) @@ -729,8 +726,6 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 LogPrintf( "appended ccopreturn to ASSETCHAINS_SCRIPTPUB.%s\n", ASSETCHAINS_SCRIPTPUB.c_str()); didinit = true; } - //LogPrintf("mine to -ac_script\n"); - //txNew.vout[1].scriptPubKey = CScript() << ParseHex(); int32_t len = strlen(ASSETCHAINS_SCRIPTPUB.c_str()); len >>= 1; txNew.vout[1].scriptPubKey.resize(len); @@ -742,15 +737,12 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 txNew.vout[1].scriptPubKey.resize(35); ptr = (uint8_t *)&txNew.vout[1].scriptPubKey[0]; ptr[0] = 33; - for (i=0; i<33; i++) + for (int32_t i=0; i<33; i++) { ptr[i+1] = ASSETCHAINS_OVERRIDE_PUBKEY33[i]; - //LogPrintf("%02x",ptr[i+1]); } ptr[34] = OP_CHECKSIG; - //LogPrintf(" set ASSETCHAINS_OVERRIDE_PUBKEY33 into vout[1]\n"); } - //LogPrintf("autocreate commision vout\n"); } else if ( (uint64_t)(txNew.vout[0].nValue) >= ASSETCHAINS_TIMELOCKGTE) { @@ -765,7 +757,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 if (scriptPubKeyIn.IsPayToScriptHash() || scriptPubKeyIn.IsPayToCryptoCondition()) { LogPrintf("CreateNewBlock: attempt to add timelock to pay2sh or pay2cc\n"); - if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) ) + if ( chainName.isKMD() || (!chainName.isKMD() && !isStake) ) { LEAVE_CRITICAL_SECTION(cs_main); LEAVE_CRITICAL_SECTION(mempool.cs); @@ -791,7 +783,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 if ( totalsats == 0 ) { LogPrintf( "Could not create notary payment, trying again.\n"); - if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) ) + if ( chainName.isKMD() || (!chainName.isKMD() && !isStake) ) { LEAVE_CRITICAL_SECTION(cs_main); LEAVE_CRITICAL_SECTION(mempool.cs); @@ -801,14 +793,6 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 //LogPrintf( "Created notary payment coinbase totalsat.%lu\n",totalsats); } else LogPrintf( "vout 2 of notarisation is not OP_RETURN scriptlen.%i\n", scriptlen); } - if ( ASSETCHAINS_CBOPRET != 0 ) - { - int32_t numv = (int32_t)txNew.vout.size(); - txNew.vout.resize(numv+1); - txNew.vout[numv].nValue = 0; - txNew.vout[numv].scriptPubKey = komodo_mineropret(nHeight); - //LogPrintf("autocreate commision/cbopret.%lld vout[%d]\n",(long long)ASSETCHAINS_CBOPRET,(int32_t)txNew.vout.size()); - } pblock->vtx[0] = txNew; pblocktemplate->vTxFees[0] = -nFees; @@ -826,14 +810,14 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 pblock->hashFinalSaplingRoot = sapling_tree.root(); // all Verus PoS chains need this data in the block at all times - if ( ASSETCHAINS_SYMBOL[0] == 0 || ASSETCHAINS_STAKED == 0 || KOMODO_MININGTHREADS > 0 ) + if ( chainName.isKMD() || ASSETCHAINS_STAKED == 0 || KOMODO_MININGTHREADS > 0 ) { UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); } pblock->nSolution.clear(); pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); - if ( ASSETCHAINS_SYMBOL[0] == 0 && IS_KOMODO_NOTARY && My_notaryid >= 0 ) + if ( chainName.isKMD() && IS_KOMODO_NOTARY && My_notaryid >= 0 ) { uint32_t r; CScript opret; CMutableTransaction txNotary = CreateNewContextualCMutableTransaction(Params().GetConsensus(), chainActive.Height() + 1); @@ -869,7 +853,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 else { LogPrintf("error adding notaryvin, need to create 0.0001 utxos\n"); - if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) ) + if ( chainName.isKMD() || (!chainName.isKMD() && !isStake) ) { LEAVE_CRITICAL_SECTION(cs_main); LEAVE_CRITICAL_SECTION(mempool.cs); @@ -877,75 +861,28 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 return(0); } } - else if ( ASSETCHAINS_CC == 0 && pindexPrev != 0 && ASSETCHAINS_STAKED == 0 && (ASSETCHAINS_SYMBOL[0] != 0 || !IS_KOMODO_NOTARY || My_notaryid < 0) ) + else if ( ASSETCHAINS_CC == 0 && pindexPrev != 0 && ASSETCHAINS_STAKED == 0 && (!chainName.isKMD() || !IS_KOMODO_NOTARY || My_notaryid < 0) ) { CValidationState state; - //LogPrintf("check validity\n"); if ( !TestBlockValidity(state, *pblock, pindexPrev, false, false)) // invokes CC checks { - if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) ) + if ( chainName.isKMD() || (!chainName.isKMD() && !isStake) ) { LEAVE_CRITICAL_SECTION(cs_main); LEAVE_CRITICAL_SECTION(mempool.cs); } - //throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed"); // crashes the node, moved to GetBlockTemplate and issue return. return(0); } - //LogPrintf("valid\n"); } } - if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) ) + if ( chainName.isKMD() || (!chainName.isKMD() && !isStake) ) { LEAVE_CRITICAL_SECTION(cs_main); LEAVE_CRITICAL_SECTION(mempool.cs); } - //LogPrintf("done new block\n"); return pblocktemplate.release(); } -/* - #ifdef ENABLE_WALLET - boost::optional GetMinerScriptPubKey(CReserveKey& reservekey) - #else - boost::optional GetMinerScriptPubKey() - #endif - { - CKeyID keyID; - CBitcoinAddress addr; - if (addr.SetString(GetArg("-mineraddress", ""))) { - addr.GetKeyID(keyID); - } else { - #ifdef ENABLE_WALLET - CPubKey pubkey; - if (!reservekey.GetReservedKey(pubkey)) { - return boost::optional(); - } - keyID = pubkey.GetID(); - #else - return boost::optional(); - #endif - } - - CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; - return scriptPubKey; - } - - #ifdef ENABLE_WALLET - CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) - { - boost::optional scriptPubKey = GetMinerScriptPubKey(reservekey); - #else - CBlockTemplate* CreateNewBlockWithKey() - { - boost::optional scriptPubKey = GetMinerScriptPubKey(); - #endif - - if (!scriptPubKey) { - return NULL; - } - return CreateNewBlock(*scriptPubKey); - }*/ - ////////////////////////////////////////////////////////////////////////////// // // Internal miner @@ -978,6 +915,14 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& // Internal miner // +/***** + * Create a new block + * @param reserveKey + * @param nHeight + * @param gpucount + * @param isStake + * @returns the block template + */ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight, int32_t gpucount, bool isStake) { CPubKey pubkey; CScript scriptPubKey; uint8_t *script,*ptr; int32_t i,len; @@ -1005,24 +950,21 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight, } else { - //if ( !isStake || ASSETCHAINS_STAKED != 0 ) - { - if (!GetBoolArg("-disablewallet", false)) { - // wallet enabled - if (!reservekey.GetReservedKey(pubkey)) - return NULL; - scriptPubKey.clear(); - scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; - } else { - // wallet disabled - CTxDestination dest = DecodeDestination(GetArg("-mineraddress", "")); - if (IsValidDestination(dest)) { - // CKeyID keyID = boost::get(dest); - // scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; - scriptPubKey = GetScriptForDestination(dest); - } else - return NULL; - } + if (!GetBoolArg("-disablewallet", false)) { + // wallet enabled + if (!reservekey.GetReservedKey(pubkey)) + return NULL; + scriptPubKey.clear(); + scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; + } else { + // wallet disabled + CTxDestination dest = DecodeDestination(GetArg("-mineraddress", "")); + if (IsValidDestination(dest)) { + // CKeyID keyID = boost::get(dest); + // scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; + scriptPubKey = GetScriptForDestination(dest); + } else + return NULL; } } return CreateNewBlock(pubkey, scriptPubKey, gpucount, isStake); @@ -1124,9 +1066,6 @@ static bool ProcessBlockFound(CBlock* pblock) return true; } -int32_t komodo_baseid(char *origbase); -int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t *blocktimes,int32_t *nonzpkeysp,int32_t height); -arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc,int32_t newStakerActive); int32_t FOUND_BLOCK,KOMODO_MAYBEMINED; extern int32_t KOMODO_LASTMINED,KOMODO_INSYNC; arith_uint256 HASHTarget,HASHTarget_POW; @@ -1149,7 +1088,7 @@ void waitForPeers(const CChainParams &chainparams) do { if (fvNodesEmpty) { - MilliSleep(1000 + rand() % 4000); + MilliSleep(1000 + rand() % 4000); // allow to interrupt boost::this_thread::interruption_point(); LOCK(cs_vNodes); fvNodesEmpty = vNodes.empty(); @@ -1166,13 +1105,13 @@ void waitForPeers(const CChainParams &chainparams) { if (++loops <= 10) { - MilliSleep(1000); + MilliSleep(1000); // allow to interrupt } else break; } } } while (fvNodesEmpty || IsNotInSync()); - MilliSleep(100 + rand() % 400); + MilliSleep(100 + rand() % 400); // allow to interrupt } } } @@ -1195,7 +1134,6 @@ CBlockIndex *get_chainactive(int32_t height) #endif int32_t gotinvalid; -extern int32_t getkmdseason(int32_t height); bool check_tromp_solution(equi &eq, std::function)> validBlock) { @@ -1242,16 +1180,13 @@ void static BitcoinMiner() uint8_t *script; uint64_t total; int32_t i,j,gpucount=KOMODO_MAXGPUCOUNT,notaryid = -1; while ( (ASSETCHAIN_INIT == 0 || KOMODO_INITDONE == 0) ) { -#ifdef WIN32 - boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); -#else - sleep(1); -#endif + //sleep(1); + boost::this_thread::sleep_for(boost::chrono::seconds(1)); // allow to interrupt - if ( komodo_baseid(ASSETCHAINS_SYMBOL) < 0 ) + if ( komodo_baseid(chainName.symbol().c_str()) < 0 ) break; } - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) { int newHeight; uint32_t timePast; @@ -1271,8 +1206,8 @@ void static BitcoinMiner() solver = "default"; assert(solver == "tromp" || solver == "default"); LogPrint("pow", "Using Equihash solver \"%s\" with n = %u, k = %u\n", solver, n, k); - if ( ASSETCHAINS_SYMBOL[0] == 0 ) - LogPrintf("notaryid.%d Mining.%s with %s\n",notaryid,ASSETCHAINS_SYMBOL,solver.c_str()); + if ( chainName.isKMD() ) + LogPrintf("notaryid.%d Mining.%s with %s\n",notaryid,chainName.symbol().c_str(),solver.c_str()); std::mutex m_cs; bool cancelSolver = false; boost::signals2::connection c = uiInterface.NotifyBlockTip.connect( @@ -1285,8 +1220,8 @@ void static BitcoinMiner() miningTimer.start(); try { - if ( ASSETCHAINS_SYMBOL[0] != 0 ) - LogPrintf("try %s Mining with %s\n",ASSETCHAINS_SYMBOL,solver.c_str()); + if ( !chainName.isKMD() ) + LogPrintf("try %s Mining with %s\n",chainName.symbol().c_str(),solver.c_str()); while (true) { if (chainparams.MiningRequiresPeers()) @@ -1303,10 +1238,9 @@ void static BitcoinMiner() if (!fvNodesEmpty )//&& !IsInitialBlockDownload()) break; MilliSleep(15000); - //LogPrintf("fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,ASSETCHAINS_SYMBOL,(int32_t)IsInitialBlockDownload()); + //LogPrintf("fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,chainName.symbol().c_str(),(int32_t)IsInitialBlockDownload()); } while (true); - //LogPrintf("%s Found peers\n",ASSETCHAINS_SYMBOL); miningTimer.start(); } // @@ -1349,12 +1283,8 @@ void static BitcoinMiner() static uint32_t counter; if ( counter++ < 10 && ASSETCHAINS_STAKED == 0 ) LogPrintf("created illegal block, retry\n"); -#ifdef WIN32 - boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); -#else - sleep(1); -#endif - + //sleep(1); + boost::this_thread::sleep_for(boost::chrono::seconds(1)); // allow to interrupt continue; } //LogPrintf("get template\n"); @@ -1370,7 +1300,7 @@ void static BitcoinMiner() return; } CBlock *pblock = &pblocktemplate->block; - if ( ASSETCHAINS_SYMBOL[0] != 0 ) + if ( !chainName.isKMD() ) { if ( ASSETCHAINS_REWARD[0] == 0 && !ASSETCHAINS_LASTERA ) { @@ -1378,19 +1308,16 @@ void static BitcoinMiner() { static uint32_t counter; if ( counter++ < 10 ) - LogPrintf("skip generating %s on-demand block, no tx avail\n",ASSETCHAINS_SYMBOL); -#ifdef WIN32 - boost::this_thread::sleep(boost::posix_time::milliseconds(10000)); -#else - sleep(10); -#endif + LogPrintf("skip generating %s on-demand block, no tx avail\n",chainName.symbol().c_str()); + //sleep(10); + boost::this_thread::sleep_for(boost::chrono::seconds(10)); // allow to interrupt continue; - } else LogPrintf("%s vouts.%d mining.%d vs %d\n",ASSETCHAINS_SYMBOL,(int32_t)pblock->vtx[0].vout.size(),Mining_height,ASSETCHAINS_MINHEIGHT); + } else LogPrintf("%s vouts.%d mining.%d vs %d\n",chainName.symbol().c_str(),(int32_t)pblock->vtx[0].vout.size(),Mining_height,ASSETCHAINS_MINHEIGHT); } } // We cant increment nonce for proof transactions, as it modifes the coinbase, meaning CreateBlock must be called again to get a new valid proof to pass validation. - if ( (ASSETCHAINS_SYMBOL[0] == 0 && notaryid >= 0 && Mining_height > nDecemberHardforkHeight ) || (ASSETCHAINS_STAKED != 0 && komodo_newStakerActive(Mining_height, pblock->nTime) != 0) ) //December 2019 hardfork + if ( (chainName.isKMD() && notaryid >= 0 && Mining_height > nDecemberHardforkHeight ) || (ASSETCHAINS_STAKED != 0 && komodo_newStakerActive(Mining_height, pblock->nTime) != 0) ) //December 2019 hardfork nExtraNonce = 0; IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); //LogPrintf("Running KomodoMiner.%s with %u transactions in block\n",solver.c_str(),(int32_t)pblock->vtx.size()); @@ -1402,7 +1329,7 @@ void static BitcoinMiner() pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); savebits = pblock->nBits; HASHTarget = arith_uint256().SetCompact(savebits); - if ( ASSETCHAINS_SYMBOL[0] == 0 && notaryid >= 0 ) + if ( chainName.isKMD() && notaryid >= 0 ) { j = 65; if ( (Mining_height >= 235300 && Mining_height < 236000) || (Mining_height % KOMODO_ELECTION_GAP) > 64 || (Mining_height % KOMODO_ELECTION_GAP) == 0 || Mining_height > 1000000 ) @@ -1455,7 +1382,7 @@ void static BitcoinMiner() (j == 65 && Mining_height > KOMODO_MAYBEMINED + 1 && Mining_height > KOMODO_LASTMINED + 64)) { HASHTarget = arith_uint256().SetCompact(KOMODO_MINDIFF_NBITS); - LogPrintf("I am the chosen one for %s ht.%d\n", ASSETCHAINS_SYMBOL, pindexPrev->nHeight + 1); + LogPrintf("I am the chosen one for %s ht.%d\n", chainName.symbol().c_str(), pindexPrev->nHeight + 1); } else LogPrintf("duplicate at j.%d\n", j); @@ -1516,15 +1443,14 @@ void static BitcoinMiner() if ( ASSETCHAINS_STAKED < 100 ) LogPrintf("Block %d : PoS %d%% vs target %d%% \n",Mining_height,percPoS,(int32_t)ASSETCHAINS_STAKED); } - //else if ( ASSETCHAINS_ADAPTIVEPOW > 0 ) - // HASHTarget_POW = komodo_adaptivepow_target(Mining_height,HASHTarget,pblock->nTime); + gotinvalid = 0; while (true) { //LogPrintf("gotinvalid.%d\n",gotinvalid); if ( gotinvalid != 0 ) break; - // komodo_longestchain(); + // Hash state crypto_generichash_blake2b_state state; @@ -1569,11 +1495,7 @@ void static BitcoinMiner() { while ( GetTime() < B.nTime-2 ) { -#ifdef WIN32 - boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); -#else - sleep(1); -#endif + boost::this_thread::sleep_for(boost::chrono::seconds(1)); // allow to interrupt CBlockIndex *tip = nullptr; { @@ -1593,7 +1515,7 @@ void static BitcoinMiner() { int32_t r; if ( (r= ((Mining_height + NOTARY_PUBKEY33[16]) % 64) / 8) > 0 ) - MilliSleep((rand() % (r * 1000)) + 1000); + MilliSleep((rand() % (r * 1000)) + 1000); // allow to interrupt } } else @@ -1603,14 +1525,14 @@ void static BitcoinMiner() // Need to rebuild block if the found solution for PoS, meets POW target, otherwise it will be rejected. if ( ASSETCHAINS_STAKED < 100 && komodo_newStakerActive(Mining_height,pblock->nTime) != 0 && h < hashTarget_POW ) { - LogPrintf( "[%s:%d] PoS block.%u meets POW_Target.%u building new block\n", ASSETCHAINS_SYMBOL, Mining_height, h.GetCompact(), hashTarget_POW.GetCompact()); + LogPrintf( "[%s:%d] PoS block.%u meets POW_Target.%u building new block\n", chainName.symbol().c_str(), Mining_height, h.GetCompact(), hashTarget_POW.GetCompact()); return(false); } if ( komodo_waituntilelegible(B.nTime, Mining_height, ASSETCHAINS_STAKED_BLOCK_FUTURE_MAX) == 0 ) return(false); } uint256 tmp = B.GetHash(); - LogPrintf("[%s:%d] mined block ",ASSETCHAINS_SYMBOL,Mining_height); + LogPrintf("[%s:%d] mined block ",chainName.symbol().c_str(),Mining_height); int32_t z; for (z=31; z>=0; z--) LogPrintf("%02x",((uint8_t *)&tmp)[z]); LogPrintf( "\n"); @@ -1707,7 +1629,7 @@ void static BitcoinMiner() } */ if (vNodes.empty() && chainparams.MiningRequiresPeers()) { - if ( ASSETCHAINS_SYMBOL[0] == 0 || Mining_height > ASSETCHAINS_MINHEIGHT ) + if ( chainName.isKMD() || Mining_height > ASSETCHAINS_MINHEIGHT ) { LogPrintf("no nodes, break\n"); break; @@ -1721,8 +1643,6 @@ void static BitcoinMiner() } if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60) { - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) - LogPrintf("timeout, break\n"); break; } CBlockIndex *tip = nullptr; @@ -1779,6 +1699,7 @@ void static BitcoinMiner() if (minerThreads != NULL) { minerThreads->interrupt_all(); + minerThreads->join_all(); // prevent thread overlapping (https://github.com/zcash/zcash/commit/a17646b1fd0ce170bdb48399f3433ca94041af73) delete minerThreads; minerThreads = NULL; } diff --git a/src/miner.h b/src/miner.h index a3bedd29..93bf9eb4 100644 --- a/src/miner.h +++ b/src/miner.h @@ -34,6 +34,9 @@ class CWallet; #endif namespace Consensus { struct Params; }; +/*** + * Holds data about the block under construction + */ struct CBlockTemplate { CBlock block; @@ -43,7 +46,7 @@ struct CBlockTemplate #define KOMODO_MAXGPUCOUNT 65 /** Generate a new block, without valid proof-of-work */ -CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& scriptPubKeyIn, int32_t gpucount, bool isStake = false); +CBlockTemplate* CreateNewBlock(const CPubKey _pk,const CScript& scriptPubKeyIn, int32_t gpucount, bool isStake = false); #ifdef ENABLE_WALLET boost::optional GetMinerScriptPubKey(CReserveKey& reservekey); CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight, int32_t gpucount, bool isStake = false); diff --git a/src/mini-gmp.c b/src/mini-gmp.c index f9ee23f1..f0addaf5 100644 --- a/src/mini-gmp.c +++ b/src/mini-gmp.c @@ -4374,7 +4374,7 @@ char *bitcoin_base58encode(char *coinaddr,uint8_t *data,int32_t datalen) return(coinaddr); } -int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr) +int32_t bitcoin_base58decode(uint8_t *data,const char *coinaddr) { uint32_t zeroes,be_sz=0; size_t count; const char *p,*p1; mpz_t bn58,bn; mpz_init_set_ui(bn58,58); diff --git a/src/mini-gmp.h b/src/mini-gmp.h index 8d9d7733..ea12f425 100644 --- a/src/mini-gmp.h +++ b/src/mini-gmp.h @@ -66,7 +66,7 @@ extern "C" { char *bitcoin_base58encode(char *coinaddr,uint8_t *data,int32_t datalen); -int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr); +int32_t bitcoin_base58decode(uint8_t *data,const char *coinaddr); void mp_set_memory_functions (void *(*) (size_t), void *(*) (void *, size_t, size_t), diff --git a/src/net.cpp b/src/net.cpp index e1986fb5..a4ff0cee 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -32,6 +32,9 @@ #include "scheduler.h" #include "ui_interface.h" #include "crypto/common.h" +#include "komodo_defs.h" +#include "komodo_globals.h" +#include "notaries_staked.h" #ifdef _WIN32 #include @@ -74,13 +77,6 @@ namespace { }; } -// -// Global state variables -// -extern uint16_t ASSETCHAINS_P2PPORT; -extern int8_t is_STAKED(const char *chain_name); -extern char ASSETCHAINS_SYMBOL[65]; - bool fDiscover = true; bool fListen = true; uint64_t nLocalServices = NODE_NETWORK; @@ -458,7 +454,7 @@ void CNode::CloseSocketDisconnect() vRecvMsg.clear(); } -extern int32_t KOMODO_NSPV; +/* TODO remove #ifndef KOMODO_NSPV_FULLNODE #define KOMODO_NSPV_FULLNODE (KOMODO_NSPV <= 0) #endif // !KOMODO_NSPV_FULLNODE @@ -466,6 +462,7 @@ extern int32_t KOMODO_NSPV; #ifndef KOMODO_NSPV_SUPERLITE #define KOMODO_NSPV_SUPERLITE (KOMODO_NSPV > 0) #endif // !KOMODO_NSPV_SUPERLITE +*/ void CNode::PushVersion() { @@ -1501,7 +1498,7 @@ void ThreadOpenConnections() static bool done = false; if (!done) { // skip DNS seeds for staked chains. - if ( is_STAKED(ASSETCHAINS_SYMBOL) == 0 ) { + if ( is_STAKED(chainName.symbol()) == 0 ) { //LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n"); LogPrintf("Adding fixed seed nodes.\n"); addrman.Add(convertSeed6(Params().FixedSeeds()), CNetAddr("127.0.0.1")); @@ -1946,9 +1943,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) Discover(threadGroup); // skip DNS seeds for staked chains. - extern int8_t is_STAKED(const char *chain_name); - extern char ASSETCHAINS_SYMBOL[65]; - if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 ) + if ( is_STAKED(chainName.symbol()) != 0 ) SoftSetBoolArg("-dnsseed", false); // diff --git a/src/notaries_staked.cpp b/src/notaries_staked.cpp index bdba00ba..f4f68c3c 100644 --- a/src/notaries_staked.cpp +++ b/src/notaries_staked.cpp @@ -3,31 +3,50 @@ #include "crosschain.h" #include "cc/CCinclude.h" #include "komodo_defs.h" +#include "komodo_globals.h" #include "komodo_hardfork.h" #include "hex.h" #include -extern pthread_mutex_t staked_mutex; +pthread_mutex_t staked_mutex; // todo remove -int8_t is_STAKED(const char *chain_name) +//static bool doneinit_STAKED = false; + +/***** + * Reset the doneinit static (for unit testing) + */ +/*void undo_init_STAKED() +{ + doneinit_STAKED = false; +}*/ + +/**** + * @brief given the chan name, determine the type of chain + * @param chain_name the chain name + * @returns 0=kmd, 1=LABS, 2=LABSxxx, 3=CFEK, 4=TEST, 255=banned + */ +uint8_t is_STAKED(const std::string& symbol) { - static int8_t STAKED,doneinit; - if ( chain_name[0] == 0 ) + // let's not use static vars: + /* static uint8_t STAKED; + if (symbol.empty()) return(0); - if (doneinit == 1 && ASSETCHAINS_SYMBOL[0] != 0) + if (doneinit_STAKED && !chainName.isKMD()) return(STAKED); - else STAKED = 0; - if ( (strcmp(chain_name, "LABS") == 0) ) + else STAKED = 0;*/ + uint8_t STAKED = 0; + + if ( symbol == "LABS" ) STAKED = 1; // These chains are allowed coin emissions. - else if ( (strncmp(chain_name, "LABS", 4) == 0) ) + else if ( symbol.find("LABS") == 0 ) STAKED = 2; // These chains have no coin emission, block subsidy is always 0, and comission is 0. Notary pay is allowed. - else if ( (strcmp(chain_name, "CFEK") == 0) || (strncmp(chain_name, "CFEK", 4) == 0) ) + else if ( symbol == "CFEK" || symbol.find("CFEK") == 0 ) STAKED = 3; // These chains have no speical rules at all. - else if ( (strcmp(chain_name, "TEST") == 0) || (strncmp(chain_name, "TEST", 4) == 0) ) + else if ( symbol == "TEST" || symbol.find("TEST") == 0 ) STAKED = 4; // These chains are for testing consensus to create a chain etc. Not meant to be actually used for anything important. - else if ( (strcmp(chain_name, "THIS_CHAIN_IS_BANNED") == 0) ) + else if ( symbol == "THIS_CHAIN_IS_BANNED" ) STAKED = 255; // Any chain added to this group is banned, no notarisations are valid, as a consensus rule. Can be used to remove a chain from cluster if needed. - doneinit = 1; + //doneinit_STAKED = true; return(STAKED); }; @@ -45,6 +64,8 @@ int32_t STAKED_era(int timestamp) return(0); }; +//char NOTARYADDRS[64][64]; // todo remove + int8_t StakedNotaryID(std::string ¬aryname, char *Raddress) { if ( STAKED_ERA != 0 ) { @@ -65,10 +86,7 @@ int8_t numStakedNotaries(uint8_t pubkeys[64][33],int8_t era) { if ( ChainName[0] == 0 ) { - if ( ASSETCHAINS_SYMBOL[0] == 0 ) - strcpy(ChainName,"KMD"); - else - strcpy(ChainName,ASSETCHAINS_SYMBOL); + strcpy(ChainName, chainName.ToString().c_str()); } if ( era == 0 ) diff --git a/src/notaries_staked.h b/src/notaries_staked.h index 4095eb0f..5d632da7 100644 --- a/src/notaries_staked.h +++ b/src/notaries_staked.h @@ -89,7 +89,9 @@ static const char *notaries_STAKED[NUM_STAKED_ERAS][64][2] = } }; -int8_t is_STAKED(const char *chain_name); +//void undo_init_STAKED(); + +uint8_t is_STAKED(const std::string& symbol); int32_t STAKED_era(int timestamp); int8_t numStakedNotaries(uint8_t pubkeys[64][33],int8_t era); int8_t StakedNotaryID(std::string ¬aryname, char *Raddress); diff --git a/src/notarisationdb.cpp b/src/notarisationdb.cpp index 813ff01e..ab082c9e 100644 --- a/src/notarisationdb.cpp +++ b/src/notarisationdb.cpp @@ -14,7 +14,12 @@ NotarisationDB *pnotarisations; NotarisationDB::NotarisationDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "notarisations", nCacheSize, fMemory, fWipe, false, 64) { } - +/**** + * Get notarisations within a block + * @param block the block to scan + * @param height the height (to find appropriate notaries) + * @returns the notarisations found + */ NotarisationsInBlock ScanBlockNotarisations(const CBlock &block, int nHeight) { EvalRef eval; @@ -32,12 +37,11 @@ NotarisationsInBlock ScanBlockNotarisations(const CBlock &block, int nHeight) continue; //LogPrintf("Checked notarisation data for %s \n",data.symbol); - int authority = GetSymbolAuthority(data.symbol); + CrosschainType authority = CrossChain::GetSymbolAuthority(data.symbol); if (authority == CROSSCHAIN_KOMODO) { if (!eval->CheckNotaryInputs(tx, nHeight, block.nTime)) continue; - //LogPrintf("Authorised notarisation data for %s \n",data.symbol); } else if (authority == CROSSCHAIN_STAKED) { // We need to create auth_STAKED dynamically here based on timestamp int32_t staked_era = STAKED_era(timestamp); @@ -51,15 +55,12 @@ NotarisationsInBlock ScanBlockNotarisations(const CBlock &block, int nHeight) // pass era slection off to notaries_staked.cpp file auth_STAKED = Choose_auth_STAKED(staked_era); } - if (!CheckTxAuthority(tx, auth_STAKED)) + if (!CrossChain::CheckTxAuthority(tx, auth_STAKED)) continue; } if (parsed) { vNotarisations.push_back(std::make_pair(tx.GetHash(), data)); - //LogPrintf("Parsed a notarisation for: %s, txid:%s, ccid:%i, momdepth:%i\n", - // data.symbol, tx.GetHash().GetHex().data(), data.ccId, data.MoMDepth); - //if (!data.MoMoM.IsNull()) LogPrintf("MoMoM:%s\n", data.MoMoM.GetHex().data()); } else LogPrintf("WARNING: Couldn't parse notarisation for tx: %s at height %i\n", tx.GetHash().GetHex().data(), nHeight); @@ -67,12 +68,6 @@ NotarisationsInBlock ScanBlockNotarisations(const CBlock &block, int nHeight) return vNotarisations; } -bool IsTXSCL(const char* symbol) -{ - return strlen(symbol) >= 5 && strncmp(symbol, "TXSCL", 5) == 0; -} - - bool GetBlockNotarisations(uint256 blockHash, NotarisationsInBlock &nibs) { return pnotarisations->Read(blockHash, nibs); @@ -100,63 +95,48 @@ void WriteBackNotarisations(const NotarisationsInBlock notarisations, CDBBatch & } } - +/*** + * Erase given notarisations from db + * @param notarisations what to erase + * @param batch the collection of db transactions + */ void EraseBackNotarisations(const NotarisationsInBlock notarisations, CDBBatch &batch) { - BOOST_FOREACH(const Notarisation &n, notarisations) + for(const Notarisation &n : notarisations) { if (!n.second.txHash.IsNull()) batch.Erase(n.second.txHash); } } -/* +/***** * Scan notarisationsdb backwards for blocks containing a notarisation * for given symbol. Return height of matched notarisation or 0. + * @param height where to start the search + * @param symbol the symbol to look for + * @param scanLimitBlocks max number of blocks to search + * @param out the first Notarization found + * @returns height (0 indicates error) */ int ScanNotarisationsDB(int height, std::string symbol, int scanLimitBlocks, Notarisation& out) { if (height < 0 || height > chainActive.Height()) - return false; + return 0; - for (int i=0; i height) break; - NotarisationsInBlock notarisations; - uint256 blockHash = *chainActive[height-i]->phashBlock; - if (!GetBlockNotarisations(blockHash, notarisations)) - continue; - - BOOST_FOREACH(Notarisation& nota, notarisations) { - if (strcmp(nota.second.symbol, symbol.data()) == 0) { - out = nota; - return height-i; - } - } - } - return 0; -} - -int ScanNotarisationsDB2(int height, std::string symbol, int scanLimitBlocks, Notarisation& out) -{ - int32_t i,maxheight,ht; - maxheight = chainActive.Height(); - if ( height < 0 || height > maxheight ) - return false; - for (i=0; i maxheight ) + if (i > height) break; NotarisationsInBlock notarisations; - uint256 blockHash = *chainActive[ht]->phashBlock; - if ( !GetBlockNotarisations(blockHash,notarisations) ) - continue; - BOOST_FOREACH(Notarisation& nota,notarisations) + uint256 blockHash = *chainActive[height-i]->phashBlock; + if (GetBlockNotarisations(blockHash, notarisations)) { - if ( strcmp(nota.second.symbol,symbol.data()) == 0 ) - { - out = nota; - return(ht); + for(Notarisation& nota : notarisations) { + if (strcmp(nota.second.symbol, symbol.data()) == 0) + { + out = nota; + return height-i; + } } } } diff --git a/src/notarisationdb.h b/src/notarisationdb.h index af5d4df2..a2d64365 100644 --- a/src/notarisationdb.h +++ b/src/notarisationdb.h @@ -18,13 +18,48 @@ extern NotarisationDB *pnotarisations; typedef std::pair Notarisation; typedef std::vector NotarisationsInBlock; +/**** + * Get notarisations within a block + * @param block the block to scan + * @param height the height (to find appropriate notaries) + * @returns the notarisations found + */ NotarisationsInBlock ScanBlockNotarisations(const CBlock &block, int nHeight); +/***** + * Get the notarisations of the block + * @param blockHash the block to examine + * @param nibs the notarisations + * @returns true on success + */ bool GetBlockNotarisations(uint256 blockHash, NotarisationsInBlock &nibs); +/*** + * Look up the value of the hash + * @param notarisationHash the key + * @param n the value + * @returns true on success + */ bool GetBackNotarisation(uint256 notarisationHash, Notarisation &n); +/*** + * Write given notarisations into db + * @param notarisations what to write + * @param the collection of db transactions + */ void WriteBackNotarisations(const NotarisationsInBlock notarisations, CDBBatch &batch); +/*** + * Erase given notarisations from db + * @param notarisations what to erase + * @param batch the collection of db transactions + */ void EraseBackNotarisations(const NotarisationsInBlock notarisations, CDBBatch &batch); +/***** + * Scan notarisationsdb backwards for blocks containing a notarisation + * for given symbol. Return height of matched notarisation or 0. + * @param height where to start the search + * @param symbol the symbol to look for + * @param scanLimitBlocks max number of blocks to search + * @param out the first Notarization found + * @returns height (0 indicates error) + */ int ScanNotarisationsDB(int height, std::string symbol, int scanLimitBlocks, Notarisation& out); -int ScanNotarisationsDB2(int height, std::string symbol, int scanLimitBlocks, Notarisation& out); -bool IsTXSCL(const char* symbol); #endif /* NOTARISATIONDB_H */ diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index cd91211b..9195c559 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -67,14 +67,8 @@ void TxConfirmStats::ClearCurrent(unsigned int nBlockHeight) unsigned int TxConfirmStats::FindBucketIndex(double val) { - extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; auto it = bucketMap.lower_bound(val); - if ( it != bucketMap.end() ) - { -// static uint32_t counter; -// if ( counter++ < 1 ) -// LogPrintf("%s FindBucketIndex violation: from val %f\n",ASSETCHAINS_SYMBOL,val); - } + // assert(it != bucketMap.end()); return it->second; } diff --git a/src/pow.cpp b/src/pow.cpp index fcf421bd..ae400435 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -29,6 +29,10 @@ #include "streams.h" #include "uint256.h" #include "util.h" +#include "komodo.h" +#include "komodo_notary.h" +#include "komodo_extern_globals.h" +#include "komodo_bitcoind.h" #include "sodium.h" @@ -382,7 +386,9 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead if (pindexFirst == NULL) return nProofOfWorkLimit; - bool fNegative,fOverflow; int32_t zawyflag = 0; arith_uint256 easy,origtarget,bnAvg {bnTot / params.nPowAveragingWindow}; + bool fNegative,fOverflow; + int32_t zawyflag = 0; arith_uint256 easy,origtarget; + arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow}; // average number of bits in the lookback window nbits = CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params); if ( ASSETCHAINS_ADAPTIVEPOW > 0 ) { @@ -496,6 +502,14 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead return(nbits); } +/**** + * @brief calculate the nBits value (work required) for the next block + * @param bnAvg the average nBits value (work required) across the lookback window + * @param nLastBlockTime the time of the most recent block in the lookback window + * @param nFirstBlockTime the time of the first block in the lookback window + * @param params the chain's consensus parameters + * @return the nBits value for the next block + */ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg, int64_t nLastBlockTime, int64_t nFirstBlockTime, const Consensus::Params& params) @@ -521,7 +535,7 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg, else bnLimit = UintToArith256(params.powAlternate); - const arith_uint256 bnPowLimit = bnLimit; //UintToArith256(params.powLimit); + const arith_uint256 bnPowLimit = bnLimit; arith_uint256 bnNew {bnAvg}; bnNew /= params.AveragingWindowTimespan(); bnNew *= nActualTimespan; @@ -580,11 +594,10 @@ int32_t komodo_currentheight(); void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height); bool komodo_checkopret(CBlock *pblock, CScript &merkleroot); CScript komodo_makeopret(CBlock *pblock, bool fNew); -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; #define KOMODO_ELECTION_GAP 2000 int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height); -int32_t KOMODO_LOADINGBLOCKS = 1; +/* KOMODO_LOADINGBLOCKS moved from here to komodo_globals.cpp and made boolean */ extern std::string NOTARY_PUBKEY; @@ -610,7 +623,6 @@ bool isSecondBlockAllowed(int32_t notaryid, uint32_t blocktime, uint32_t thresho bool CheckProofOfWork(const CBlockHeader &blkHeader, uint8_t *pubkey33, int32_t height, const Consensus::Params& params) { - extern int32_t KOMODO_REWIND; uint256 hash; bool fNegative,fOverflow; uint8_t origpubkey33[33]; int32_t i,nonzpkeys=0,nonz=0,special=0,special2=0,notaryid=-1,flag = 0, mids[66]; uint32_t tiptime,blocktimes[66]; arith_uint256 bnTarget; uint8_t pubkeys[66][33]; @@ -626,7 +638,7 @@ bool CheckProofOfWork(const CBlockHeader &blkHeader, uint8_t *pubkey33, int32_t height = komodo_currentheight() + 1; //LogPrintf("set height to %d\n",height); } - if ( height > 34000 && ASSETCHAINS_SYMBOL[0] == 0 ) // 0 -> non-special notary + if ( height > 34000 && chainName.isKMD() ) // 0 -> non-special notary { special = komodo_chosennotary(¬aryid,height,pubkey33,tiptime); for (i=0; i<33; i++) @@ -667,7 +679,7 @@ bool CheckProofOfWork(const CBlockHeader &blkHeader, uint8_t *pubkey33, int32_t /* in KMD chain after nHeightAfterGAPSecondBlockAllowed height we should allow notary nodes to mine a second block if nMaxGAPAllowed since last block passed */ - if (ASSETCHAINS_SYMBOL[0] == 0 && height > nHeightAfterGAPSecondBlockAllowed) + if (chainName.isKMD() && height > nHeightAfterGAPSecondBlockAllowed) { const uint32_t &blocktime = blkHeader.nTime; if (blocktime /* upcoming block time */ >= tiptime /* last block in chain time */ + nMaxGAPAllowed && @@ -730,15 +742,6 @@ bool CheckProofOfWork(const CBlockHeader &blkHeader, uint8_t *pubkey33, int32_t { //LogPrintf("EASY MINING ht.%d\n",height); bnTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow); - /* - const void* pblock = &blkHeader; - CScript merkleroot = CScript(); - if ( height > nDecemberHardforkHeight && !komodo_checkopret((CBlock*)pblock, merkleroot) ) // December 2019 hardfork - { - LogPrintf("failed or missing merkleroot expected.%s != merkleroot.%s\n", komodo_makeopret((CBlock*)pblock, false).ToString().c_str(), merkleroot.ToString().c_str()); - return false; - } - */ } } } @@ -750,15 +753,13 @@ bool CheckProofOfWork(const CBlockHeader &blkHeader, uint8_t *pubkey33, int32_t arith_uint256 bnMaxPoSdiff; bnTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow); } - //else if ( ASSETCHAINS_ADAPTIVEPOW > 0 && ASSETCHAINS_STAKED == 0 ) - // bnTarget = komodo_adaptivepow_target(height,bnTarget,blkHeader.nTime); // Check proof of work matches claimed amount if ( UintToArith256(hash = blkHeader.GetHash()) > bnTarget ) { - if ( KOMODO_LOADINGBLOCKS != 0 ) + if ( KOMODO_LOADINGBLOCKS ) return true; - if ( ASSETCHAINS_SYMBOL[0] != 0 || height > 792000 ) + if ( !chainName.isKMD() || height > 792000 ) { //if ( 0 && height > 792000 ) if ( Params().NetworkIDString() != "regtest" ) @@ -779,12 +780,6 @@ bool CheckProofOfWork(const CBlockHeader &blkHeader, uint8_t *pubkey33, int32_t return false; } } - /*for (i=31; i>=0; i--) - LogPrintf("%02x",((uint8_t *)&hash)[i]); - LogPrintf(" hash vs "); - for (i=31; i>=0; i--) - LogPrintf("%02x",((uint8_t *)&bnTarget)[i]); - LogPrintf(" height.%d notaryid.%d PoW valid\n",height,notaryid);*/ return true; } diff --git a/src/qt/komodo.cpp b/src/qt/komodo.cpp index 9f4c4729..6561e4da 100644 --- a/src/qt/komodo.cpp +++ b/src/qt/komodo.cpp @@ -13,8 +13,6 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; extern uint32_t ASSETCHAIN_INIT; extern std::string NOTARY_PUBKEY; -void komodo_passport_iteration(); -void komodo_cbopretupdate(int32_t forceflag); CBlockIndex *komodo_chainactive(int32_t height); //#include "chainparams.h" @@ -355,19 +353,24 @@ void KomodoCore::shutdown() while (!fShutdown) { - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + /* TODO: move to ThreadUpdateKomodoInternals */ + if ( chainName.isKMD() ) { - //if (!ShutdownRequested()) komodo_passport_iteration(); - if ( KOMODO_NSPV_FULLNODE ) - komodo_passport_iteration(); - MilliSleep(1000); + if ( KOMODO_NSPV_FULLNODE ) { + komodo_update_interest(); + komodo_longestchain(); + } + for (i=0; i<10; i++) + { + fShutdown = ShutdownRequested(); + if ( fShutdown != 0 ) + break; + MilliSleep(1000); + } } else { - //komodo_interestsum(); - //komodo_longestchain(); - if ( ASSETCHAINS_CBOPRET != 0 ) - komodo_cbopretupdate(0); + /* for ACs we do nothing at present */ for (i=0; i<=ASSETCHAINS_BLOCKTIME/5; i++) { fShutdown = ShutdownRequested(); diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 4509a853..d95822b4 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -272,7 +272,8 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco if (wtx.IsCoinBase()) { - quint32 numBlocksToMaturity = COINBASE_MATURITY + 1; + // quint32 numBlocksToMaturity = COINBASE_MATURITY + 1; + quint32 numBlocksToMaturity = ::Params().CoinbaseMaturity() + 1; strHTML += "
" + tr("Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.").arg(QString::number(numBlocksToMaturity)) + "
"; } diff --git a/src/rest.cpp b/src/rest.cpp index 10fa6507..afedad60 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -28,6 +28,8 @@ #include "txmempool.h" #include "utilstrencodings.h" #include "version.h" +#include "rpc/rawtransaction.h" +#include "rpc/blockchain.h" #include #include @@ -71,13 +73,6 @@ struct CCoin { } }; -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); -extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); -extern UniValue mempoolInfoToJSON(); -extern UniValue mempoolToJSON(bool fVerbose = false); -extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); -extern UniValue blockheaderToJSON(const CBlockIndex* blockindex); - static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, string message) { req->WriteHeader("Content-Type", "text/plain"); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f75a283c..65e72e4e 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -36,6 +36,15 @@ #include "script/script_error.h" #include "script/sign.h" #include "script/standard.h" +#include "komodo_defs.h" +#include "komodo_structs.h" +#include "komodo_globals.h" +#include "komodo_notary.h" +#include "komodo_bitcoind.h" +#include "komodo_utils.h" +#include "komodo_kv.h" +#include "komodo_gateway.h" +#include "rpc/rawtransaction.h" #include @@ -44,16 +53,17 @@ #include #include "cc/CCinclude.h" -#include "cc/CCPrices.h" using namespace std; -extern int32_t KOMODO_INSYNC; -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); -void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); -int32_t komodo_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 *txidp); -#include "komodo_defs.h" +// TODO: remove +//extern int32_t KOMODO_INSYNC; +//extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +//void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); +//int32_t komodo_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 *txidp); +//#include "komodo_defs.h" #include "komodo_structs.h" +#include "komodo_interest.h" double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty) { @@ -964,7 +974,7 @@ UniValue kvsearch(const UniValue& params, bool fHelp, const CPubKey& mypk) LOCK(cs_main); if ( (keylen= (int32_t)strlen(params[0].get_str().c_str())) > 0 ) { - ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL))); + ret.push_back(Pair("coin",chainName.ToString())); ret.push_back(Pair("currentheight", (int64_t)chainActive.Tip()->nHeight)); ret.push_back(Pair("key",params[0].get_str())); ret.push_back(Pair("keylen",keylen)); @@ -1105,391 +1115,6 @@ UniValue notaries(const UniValue& params, bool fHelp, const CPubKey& mypk) return ret; } -int32_t komodo_pending_withdraws(char *opretstr); -int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base); -extern char CURRENCIES[][8]; - -UniValue paxpending(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); char opretbuf[10000*2]; int32_t opretlen,baseid; uint64_t available,deposited,issued,withdrawn,approved,redeemed; - if ( fHelp || params.size() != 0 ) - throw runtime_error("paxpending needs no args\n"); - LOCK(cs_main); - if ( (opretlen= komodo_pending_withdraws(opretbuf)) > 0 ) - ret.push_back(Pair("withdraws", opretbuf)); - else ret.push_back(Pair("withdraws", (char *)"")); - for (baseid=0; baseid<32; baseid++) - { - UniValue item(UniValue::VOBJ); UniValue obj(UniValue::VOBJ); - if ( pax_fiatstatus(&available,&deposited,&issued,&withdrawn,&approved,&redeemed,CURRENCIES[baseid]) == 0 ) - { - if ( deposited != 0 || issued != 0 || withdrawn != 0 || approved != 0 || redeemed != 0 ) - { - item.push_back(Pair("available", ValueFromAmount(available))); - item.push_back(Pair("deposited", ValueFromAmount(deposited))); - item.push_back(Pair("issued", ValueFromAmount(issued))); - item.push_back(Pair("withdrawn", ValueFromAmount(withdrawn))); - item.push_back(Pair("approved", ValueFromAmount(approved))); - item.push_back(Pair("redeemed", ValueFromAmount(redeemed))); - obj.push_back(Pair(CURRENCIES[baseid],item)); - a.push_back(obj); - } - } - } - ret.push_back(Pair("fiatstatus", a)); - return ret; -} - -UniValue paxprice(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if ( fHelp || params.size() > 4 || params.size() < 2 ) - throw runtime_error("paxprice \"base\" \"rel\" height\n"); - LOCK(cs_main); - UniValue ret(UniValue::VOBJ); uint64_t basevolume=0,relvolume,seed; - std::string base = params[0].get_str(); - std::string rel = params[1].get_str(); - int32_t height; - if ( params.size() == 2 ) - height = chainActive.Tip()->nHeight; - else height = atoi(params[2].get_str().c_str()); - //if ( params.size() == 3 || (basevolume= COIN * atof(params[3].get_str().c_str())) == 0 ) - basevolume = 100000; - relvolume = komodo_paxprice(&seed,height,(char *)base.c_str(),(char *)rel.c_str(),basevolume); - ret.push_back(Pair("base", base)); - ret.push_back(Pair("rel", rel)); - ret.push_back(Pair("height", height)); - char seedstr[32]; - sprintf(seedstr,"%llu",(long long)seed); - ret.push_back(Pair("seed", seedstr)); - if ( height < 0 || height > chainActive.Height() ) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); - else - { - CBlockIndex *pblockindex = chainActive[height]; - if ( pblockindex != 0 ) - ret.push_back(Pair("timestamp", (int64_t)pblockindex->nTime)); - if ( basevolume != 0 && relvolume != 0 ) - { - ret.push_back(Pair("price",((double)relvolume / (double)basevolume))); - ret.push_back(Pair("invprice",((double)basevolume / (double)relvolume))); - ret.push_back(Pair("basevolume",ValueFromAmount(basevolume))); - ret.push_back(Pair("relvolume",ValueFromAmount(relvolume))); - } else ret.push_back(Pair("error", "overflow or error in one or more of parameters")); - } - return ret; -} -// fills pricedata with raw price, correlated and smoothed values for numblock -/*int32_t prices_extract(int64_t *pricedata,int32_t firstheight,int32_t numblocks,int32_t ind) -{ - int32_t height,i,n,width,numpricefeeds = -1; uint64_t seed,ignore,rngval; uint32_t rawprices[1440*6],*ptr; int64_t *tmpbuf; - width = numblocks+PRICES_DAYWINDOW*2+PRICES_SMOOTHWIDTH; // need 2*PRICES_DAYWINDOW previous raw price points to calc PRICES_DAYWINDOW correlated points to calc, in turn, smoothed point - komodo_heightpricebits(&seed,rawprices,firstheight + numblocks - 1); - if ( firstheight < width ) - return(-1); - for (i=0; i2; i++,ht--) - { - if ( ht < 0 || ht > chainActive.Height() ) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); - else - { - if ( (n= komodo_heightpricebits(0,rawprices,ht)) > 0 ) - { - if ( n != numpricefeeds ) - throw JSONRPCError(RPC_INVALID_PARAMETER, "numprices != first numprices"); - else - { - for (j=0; j= width ) - { - for (i=0; i= 0 ) - { - if ( checkprices[1] != correlated[i] ) - { - //LogPrintf("ind.%d ht.%d %.8f != %.8f\n",j,nextheight-1-i,(double)checkprices[1]/COIN,(double)correlated[i]/COIN); - correlated[i] = checkprices[1]; - } - } - } - } - tmpbuf = (int64_t *)calloc(sizeof(int64_t),2*PRICES_DAYWINDOW); - for (i=0; i= 0 ) - { - if ( checkprices[2] != smoothed ) - { - LogPrintf("ind.%d ht.%d %.8f != %.8f\n",j,nextheight-1-i,(double)checkprices[2]/COIN,(double)smoothed/COIN); - smoothed = checkprices[2]; - } - } - UniValue parr(UniValue::VARR); - parr.push_back(ValueFromAmount((int64_t)prices[offset] * komodo_pricemult(j))); - parr.push_back(ValueFromAmount(correlated[i])); - parr.push_back(ValueFromAmount(smoothed)); - // compare to alternate method - p.push_back(parr); - } - free(tmpbuf); - } - else - { - for (i=0; i vexpr; - SplitStr(sexpr, vexpr); - - // debug print parsed strings: - std::cerr << "parsed synthetic: "; - for (auto s : vexpr) - std::cerr << s << " "; - std::cerr << std::endl; - - return PricesBet(txfee, amount, leverage, vexpr); -} - -// pricesaddfunding rpc implementation -UniValue pricesaddfunding(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (fHelp || params.size() != 2) - throw runtime_error("pricesaddfunding bettxid amount\n" - "where amount is in coins\n"); - LOCK(cs_main); - UniValue ret(UniValue::VOBJ); - - if (ASSETCHAINS_CBOPRET == 0) - throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); - - CAmount txfee = 10000; - uint256 bettxid = Parseuint256(params[0].get_str().c_str()); - if (bettxid.IsNull()) - throw runtime_error("invalid bettxid\n"); - - CAmount amount = atof(params[1].get_str().c_str()) * COIN; - if (amount <= 0) - throw runtime_error("invalid amount\n"); - - return PricesAddFunding(txfee, bettxid, amount); -} - -// rpc pricessetcostbasis implementation -UniValue pricessetcostbasis(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (fHelp || params.size() != 1) - throw runtime_error("pricessetcostbasis bettxid\n"); - LOCK(cs_main); - UniValue ret(UniValue::VOBJ); - - if (ASSETCHAINS_CBOPRET == 0) - throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); - - uint256 bettxid = Parseuint256(params[0].get_str().c_str()); - if (bettxid.IsNull()) - throw runtime_error("invalid bettxid\n"); - - int64_t txfee = 10000; - - return PricesSetcostbasis(txfee, bettxid); -} - -// pricescashout rpc implementation -UniValue pricescashout(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (fHelp || params.size() != 1) - throw runtime_error("pricescashout bettxid\n"); - LOCK(cs_main); - UniValue ret(UniValue::VOBJ); - - if (ASSETCHAINS_CBOPRET == 0) - throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); - - uint256 bettxid = Parseuint256(params[0].get_str().c_str()); - if (bettxid.IsNull()) - throw runtime_error("invalid bettxid\n"); - - int64_t txfee = 10000; - - return PricesCashout(txfee, bettxid); -} - -// pricesrekt rpc implementation -UniValue pricesrekt(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (fHelp || params.size() != 2) - throw runtime_error("pricesrekt bettxid height\n"); - LOCK(cs_main); - UniValue ret(UniValue::VOBJ); - - if (ASSETCHAINS_CBOPRET == 0) - throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); - - uint256 bettxid = Parseuint256(params[0].get_str().c_str()); - if (bettxid.IsNull()) - throw runtime_error("invalid bettxid\n"); - - int32_t height = atoi(params[0].get_str().c_str()); - - int64_t txfee = 10000; - - return PricesRekt(txfee, bettxid, height); -} - -// pricesrekt rpc implementation -UniValue pricesgetorderbook(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (fHelp || params.size() != 0) - throw runtime_error("pricesgetorderbook\n"); - LOCK(cs_main); - UniValue ret(UniValue::VOBJ); - - if (ASSETCHAINS_CBOPRET == 0) - throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); - - return PricesGetOrderbook(); -} - -// pricesrekt rpc implementation -UniValue pricesrefillfund(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (fHelp || params.size() != 1) - throw runtime_error("pricesrefillfund amount\n"); - LOCK(cs_main); - UniValue ret(UniValue::VOBJ); - - if (ASSETCHAINS_CBOPRET == 0) - throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); - - CAmount amount = atof(params[0].get_str().c_str()) * COIN; - - return PricesRefillFund(amount); -} - - UniValue gettxout(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (fHelp || params.size() < 2 || params.size() > 3) @@ -1718,10 +1343,10 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp, const CPubKey& my LOCK(cs_main); double progress; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) { + if ( chainName.isKMD() ) { progress = Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()); } else { - int32_t longestchain = KOMODO_LONGESTCHAIN;//komodo_longestchain(); + int32_t longestchain = KOMODO_LONGESTCHAIN; progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0; } UniValue obj(UniValue::VOBJ); diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h new file mode 100644 index 00000000..a731b546 --- /dev/null +++ b/src/rpc/blockchain.h @@ -0,0 +1,20 @@ +#pragma once +/****************************************************************************** + * Copyright © 2021 Komodo Core Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +UniValue mempoolInfoToJSON(); +UniValue mempoolToJSON(bool fVerbose = false); +UniValue blockheaderToJSON(const CBlockIndex* blockindex); diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 81accc7d..7d002e34 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -160,9 +160,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "z_shieldcoinbase", 3}, { "z_getoperationstatus", 0}, { "z_getoperationresult", 0}, - { "paxprice", 4 }, - { "paxprices", 3 }, - { "paxpending", 0 }, { "notaries", 2 }, { "minerids", 1 }, { "kvsearch", 1 }, diff --git a/src/rpc/crosschain.cpp b/src/rpc/crosschain.cpp index 7fdf87d1..f425783c 100644 --- a/src/rpc/crosschain.cpp +++ b/src/rpc/crosschain.cpp @@ -35,10 +35,15 @@ #include "script/sign.h" #include "script/standard.h" #include "notaries_staked.h" +#include "komodo_notary.h" +#include "komodo_bitcoind.h" +#include "komodo_ccdata.h" +#include "notaries_staked.h" #include "key_io.h" #include "cc/CCImportGateway.h" #include "cc/CCtokens.h" +#include "cc/import.h" #include #include @@ -47,24 +52,6 @@ using namespace std; -extern std::string CCerror; -extern std::string ASSETCHAINS_SELFIMPORT; -extern uint16_t ASSETCHAINS_CODAPORT, ASSETCHAINS_BEAMPORT; -int32_t ensure_CCrequirements(uint8_t evalcode); -bool EnsureWalletIsAvailable(bool avoidException); - - -int32_t komodo_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); -int32_t komodo_MoMoMdata(char *hexstr,int32_t hexsize,struct komodo_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height); -struct komodo_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi); -uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth); -int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); -extern std::string ASSETCHAINS_SELFIMPORT; - -//std::string MakeSelfImportSourceTx(CTxDestination &dest, int64_t amount, CMutableTransaction &mtx); -//int32_t GetSelfimportProof(std::string source, CMutableTransaction &mtx, CScript &scriptPubKey, TxProof &proof, std::string rawsourcetx, int32_t &ivout, uint256 sourcetxid, uint64_t burnAmount); -std::string MakeCodaImportTx(uint64_t txfee, std::string receipt, std::string srcaddr, std::vector vouts); - UniValue assetchainproof(const UniValue& params, bool fHelp, const CPubKey& mypk) { uint256 hash; @@ -75,7 +62,7 @@ UniValue assetchainproof(const UniValue& params, bool fHelp, const CPubKey& mypk hash = uint256S(params[0].get_str()); CTransaction tx; - auto proof = GetAssetchainProof(hash,tx); + auto proof = CrossChain::GetAssetchainProof(hash,tx); auto proofData = E_MARSHAL(ss << proof); return HexStr(proofData); } @@ -107,7 +94,7 @@ UniValue height_MoM(const UniValue& params, bool fHelp, const CPubKey& mypk) } //LogPrintf("height_MoM height.%d\n",height); depth = komodo_MoM(¬arized_height,&MoM,&kmdtxid,height,&MoMoM,&MoMoMoffset,&MoMoMdepth,&kmdstarti,&kmdendi); - ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL))); + ret.push_back(Pair("coin", chainName.ToString())); ret.push_back(Pair("height",height)); ret.push_back(Pair("timestamp",(uint64_t)timestamp)); if ( depth > 0 ) @@ -116,7 +103,7 @@ UniValue height_MoM(const UniValue& params, bool fHelp, const CPubKey& mypk) ret.push_back(Pair("notarized_height",notarized_height)); ret.push_back(Pair("MoM",MoM.GetHex())); ret.push_back(Pair("kmdtxid",kmdtxid.GetHex())); - if ( ASSETCHAINS_SYMBOL[0] != 0 ) + if ( !chainName.isKMD() ) { ret.push_back(Pair("MoMoM",MoMoM.GetHex())); ret.push_back(Pair("MoMoMoffset",MoMoMoffset)); @@ -143,7 +130,7 @@ UniValue MoMoMdata(const UniValue& params, bool fHelp, const CPubKey& mypk) uint256 destNotarisationTxid; std::vector moms; - uint256 MoMoM = CalculateProofRoot(symbol, ccid, kmdheight-5, moms, destNotarisationTxid); + uint256 MoMoM = CrossChain::CalculateProofRoot(symbol, ccid, kmdheight-5, moms, destNotarisationTxid); UniValue valMoms(UniValue::VARR); for (int i=0; i txData(ParseHexV(params[0], "argument 1")); @@ -205,7 +192,7 @@ UniValue migrate_converttoexport(const UniValue& params, bool fHelp, const CPubK if (targetSymbol.size() == 0 || targetSymbol.size() > 32) throw runtime_error("targetSymbol length must be >0 and <=32"); - if (strcmp(ASSETCHAINS_SYMBOL,targetSymbol.c_str()) == 0) + if ( chainName.isSymbol( targetSymbol) ) throw runtime_error("cant send a coin to the same chain"); /// Tested 44 vins p2pkh inputs as working. Set this at 25, but its a tx size limit. @@ -223,13 +210,7 @@ UniValue migrate_converttoexport(const UniValue& params, bool fHelp, const CPubK if (burnAmount > 1000000LL*COIN) throw JSONRPCError(RPC_TYPE_ERROR, "Cannot export more than 1 million coins per export."); - /* note: we marshal to rawproof in a different way (to be able to add other objects) - rawproof.resize(strlen(ASSETCHAINS_SYMBOL)); - ptr = rawproof.data(); - for (i=0; i 32) throw runtime_error("targetSymbol length must be >0 and <=32"); - if (strcmp(ASSETCHAINS_SYMBOL, targetSymbol.c_str()) == 0) + if ( chainName.isSymbol(targetSymbol) ) throw runtime_error("cant send a coin to the same chain"); std::string dest_addr_or_pubkey = params[1].get_str(); @@ -308,8 +289,7 @@ UniValue migrate_createburntransaction(const UniValue& params, bool fHelp, const CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - const std::string chainSymbol(ASSETCHAINS_SYMBOL); - std::vector rawproof; //(chainSymbol.begin(), chainSymbol.end()); + std::vector rawproof; if (tokenid.IsNull()) { // coins int64_t inputs; @@ -325,7 +305,7 @@ UniValue migrate_createburntransaction(const UniValue& params, bool fHelp, const mtx.vout.push_back(CTxOut(burnAmount, scriptPubKey)); // 'model' vout ret.push_back(Pair("payouts", HexStr(E_MARSHAL(ss << mtx.vout)))); // save 'model' vout - rawproof = E_MARSHAL(ss << chainSymbol); // add src chain name + rawproof = E_MARSHAL(ss << chainName.symbol()); // add src chain name CTxOut burnOut = MakeBurnOutput(burnAmount+txfee, ccid, targetSymbol, mtx.vout, rawproof); //make opret with burned amount @@ -394,7 +374,7 @@ UniValue migrate_createburntransaction(const UniValue& params, bool fHelp, const mtx.vout.push_back(CTxOut((CAmount)0, EncodeTokenCreateOpRet('c', vorigpubkey, name, description, voprets))); // make token import opret ret.push_back(Pair("payouts", HexStr(E_MARSHAL(ss << mtx.vout)))); // save payouts for import tx - rawproof = E_MARSHAL(ss << chainSymbol << tokenbasetx); // add src chain name and token creation tx + rawproof = E_MARSHAL(ss << chainName.symbol() << tokenbasetx); // add src chain name and token creation tx CTxOut burnOut = MakeBurnOutput(0, ccid, targetSymbol, mtx.vout, rawproof); //make opret with amount=0 because tokens are burned, not coins (see next vout) mtx.vout.clear(); // remove payouts @@ -503,13 +483,13 @@ void CheckBurnTxSource(uint256 burntxid, UniValue &info) { throw std::runtime_error("No opreturn in burn tx"); - if (sourceSymbol != ASSETCHAINS_SYMBOL) + if ( !chainName.isSymbol(sourceSymbol) ) throw std::runtime_error("Incorrect source chain in rawproof"); if (targetCCid != ASSETCHAINS_CC) throw std::runtime_error("Incorrect CCid in burn tx"); - if (targetSymbol == ASSETCHAINS_SYMBOL) + if ( chainName.isSymbol(targetSymbol) ) throw std::runtime_error("Must not be called on the destination chain"); // fill info to return for the notary operator (if manual notarization) or user @@ -549,7 +529,7 @@ UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp, con if (ASSETCHAINS_CC < KOMODO_FIRSTFUNGIBLEID) throw runtime_error("-ac_cc < KOMODO_FIRSTFUNGIBLEID"); - if (ASSETCHAINS_SYMBOL[0] == 0) + if ( chainName.isKMD() ) throw runtime_error("Must be called on assetchain"); vector txData(ParseHexV(params[0], "argument 1")); @@ -572,7 +552,7 @@ UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp, con ImportProof importProof; if (params.size() == 2) { // standard MoMoM based notarization // get MoM import proof - importProof = ImportProof(GetAssetchainProof(burnTx.GetHash(), burnTx)); + importProof = ImportProof(CrossChain::GetAssetchainProof(burnTx.GetHash(), burnTx)); } else { // notarization by manual operators notary tx UniValue info(UniValue::VOBJ); @@ -605,7 +585,7 @@ UniValue migrate_completeimporttransaction(const UniValue& params, bool fHelp, c "and extends proof to target chain proof root\n" "offset is optional, use it to increase the used KMD height, use when import fails."); - if (ASSETCHAINS_SYMBOL[0] != 0) + if ( !chainName.isKMD() ) throw runtime_error("Must be called on KMD"); CTransaction importTx; @@ -616,7 +596,7 @@ UniValue migrate_completeimporttransaction(const UniValue& params, bool fHelp, c if ( params.size() == 2 ) offset = params[1].get_int(); - CompleteImportTransaction(importTx, offset); + CrossChain::CompleteImportTransaction(importTx, offset); std::string importTxHex = HexStr(E_MARSHAL(ss << importTx)); UniValue ret(UniValue::VOBJ); @@ -645,7 +625,7 @@ UniValue migrate_checkburntransactionsource(const UniValue& params, bool fHelp, throw runtime_error("migrate_checkburntransactionsource burntxid\n\n" "checks if params stored in the burn tx match to its tx chain"); - if (ASSETCHAINS_SYMBOL[0] == 0) + if (chainName.isKMD()) throw runtime_error("Must be called on asset chain"); uint256 burntxid = Parseuint256(params[0].get_str().c_str()); @@ -673,7 +653,7 @@ UniValue migrate_createnotaryapprovaltransaction(const UniValue& params, bool fH "Creates a tx for destination chain with burn tx proof\n" "txoutproof should be retrieved by komodo-cli migrate_checkburntransactionsource call on the source chain\n" ); - if (ASSETCHAINS_SYMBOL[0] == 0) + if (chainName.isKMD()) throw runtime_error("Must be called on asset chain"); uint256 burntxid = Parseuint256(params[0].get_str().c_str()); @@ -765,7 +745,7 @@ UniValue selfimport(const UniValue& params, bool fHelp, const CPubKey& mypk) CMutableTransaction templateMtx; // prepare self-import 'quasi-burn' tx and also create vout for import tx (in mtx.vout): - if (GetSelfimportProof(sourceMtx, templateMtx, proofNull) < 0) + if ( !GetSelfimportProof(sourceMtx, templateMtx, proofNull) ) throw std::runtime_error("Failed creating selfimport template tx"); vouts = templateMtx.vout; @@ -790,7 +770,7 @@ UniValue selfimport(const UniValue& params, bool fHelp, const CPubKey& mypk) return result; } -bool GetNotarisationNotaries(uint8_t notarypubkeys[64][33], int8_t &numNN, const std::vector &vin, std::vector &NotarisationNotaries); +///bool GetNotarisationNotaries(uint8_t notarypubkeys[64][33], int8_t &numNN, const std::vector &vin, std::vector &NotarisationNotaries); UniValue importdual(const UniValue& params, bool fHelp, const CPubKey& mypk) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 0c4f7708..4c5410ff 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -23,6 +23,7 @@ #include "consensus/consensus.h" #include "consensus/validation.h" #include "core_io.h" +#include "komodo_bitcoind.h" #ifdef ENABLE_MINING #include "crypto/equihash.h" #endif @@ -48,14 +49,6 @@ using namespace std; -#include "komodo_defs.h" - -extern int32_t ASSETCHAINS_FOUNDERS; -uint64_t komodo_commission(const CBlock *pblock,int32_t height); -int32_t komodo_blockload(CBlock& block,CBlockIndex *pindex); -arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc,int32_t newStakerActive); -int32_t komodo_newStakerActive(int32_t height, uint32_t timestamp); - /** * Return average network hashes per second based on the last 'lookup' blocks, * or over the difficulty averaging window if 'lookup' is nonpositive. @@ -193,7 +186,99 @@ UniValue getgenerate(const UniValue& params, bool fHelp, const CPubKey& mypk) return obj; } -extern uint8_t NOTARY_PUBKEY33[33]; +/***** + * Calculate the PoW value for a block + * @param pblock the block to work on + * @returns true when the PoW is completed + */ +bool CalcPoW(CBlock *pblock) +{ + unsigned int n = Params().EquihashN(); + unsigned int k = Params().EquihashK(); + // Hash state + crypto_generichash_blake2b_state eh_state; + EhInitialiseState(n, k, eh_state); + + // I = the block header minus nonce and solution. + CEquihashInput I{*pblock}; + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << I; + + // H(I||... + crypto_generichash_blake2b_update(&eh_state, (unsigned char*)&ss[0], ss.size()); + + while (true) { + // Yes, there is a chance every nonce could fail to satisfy the -regtest + // target -- 1 in 2^(2^256). That ain't gonna happen + pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1); + + // H(I||V||... + crypto_generichash_blake2b_state curr_state; + curr_state = eh_state; + crypto_generichash_blake2b_update(&curr_state, + pblock->nNonce.begin(), + pblock->nNonce.size()); + + // (x_1, x_2, ...) = A(I, V, n, k) + std::function)> validBlock = + [&pblock](std::vector soln) + { + LOCK(cs_main); + pblock->nSolution = soln; + solutionTargetChecks.increment(); + return CheckProofOfWork(*pblock,NOTARY_PUBKEY33,chainActive.Height(),Params().GetConsensus()); + }; + bool found = EhBasicSolveUncancellable(n, k, curr_state, validBlock); + ehSolverRuns.increment(); + if (found) { + return true; + } + } + // this should never get hit + return false; +} + +/**** + * @brief Generate 1 block + * @param wallet the wallet that should be used + * @returns the block created or nullptr if there was a problem + */ +std::shared_ptr generateBlock(CWallet* wallet, CValidationState* validationState) +{ + CReserveKey reservekey(wallet); + int nHeight; + + { // Don't keep cs_main locked + LOCK(cs_main); + nHeight = chainActive.Height(); + } + + std::unique_ptr pblocktemplate(CreateNewBlockWithKey(reservekey,nHeight,KOMODO_MAXGPUCOUNT)); + if (pblocktemplate == nullptr) + return nullptr; + + CBlock *pblock = &pblocktemplate->block; + { + unsigned int nExtraNonce = 0; + LOCK(cs_main); + IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); + } + + CalcPoW(pblock); // add PoW + CValidationState state; + CBlockIndex *tipindex = nullptr; + { + LOCK(cs_main); + tipindex = chainActive.Tip(); + } + if (!ProcessNewBlock(1,tipindex->nHeight+1,state, NULL, pblock, true, NULL)) + { + if (validationState != nullptr) + (*validationState) = state; + return nullptr; + } + return std::shared_ptr( new CBlock(*pblock) ); +} //Value generate(const Array& params, bool fHelp) UniValue generate(const UniValue& params, bool fHelp, const CPubKey& mypk) @@ -251,8 +336,6 @@ UniValue generate(const UniValue& params, bool fHelp, const CPubKey& mypk) } unsigned int nExtraNonce = 0; UniValue blockHashes(UniValue::VARR); - unsigned int n = Params().EquihashN(); - unsigned int k = Params().EquihashK(); uint64_t lastTime = 0; while (nHeight < nHeightEnd) { @@ -273,46 +356,7 @@ UniValue generate(const UniValue& params, bool fHelp, const CPubKey& mypk) IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); } - // Hash state - crypto_generichash_blake2b_state eh_state; - EhInitialiseState(n, k, eh_state); - - // I = the block header minus nonce and solution. - CEquihashInput I{*pblock}; - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << I; - - // H(I||... - crypto_generichash_blake2b_update(&eh_state, (unsigned char*)&ss[0], ss.size()); - - while (true) { - // Yes, there is a chance every nonce could fail to satisfy the -regtest - // target -- 1 in 2^(2^256). That ain't gonna happen - pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1); - - // H(I||V||... - crypto_generichash_blake2b_state curr_state; - curr_state = eh_state; - crypto_generichash_blake2b_update(&curr_state, - pblock->nNonce.begin(), - pblock->nNonce.size()); - - // (x_1, x_2, ...) = A(I, V, n, k) - std::function)> validBlock = - [&pblock](std::vector soln) - { - LOCK(cs_main); - pblock->nSolution = soln; - solutionTargetChecks.increment(); - return CheckProofOfWork(*pblock,NOTARY_PUBKEY33,chainActive.Height(),Params().GetConsensus()); - }; - bool found = EhBasicSolveUncancellable(n, k, curr_state, validBlock); - ehSolverRuns.increment(); - if (found) { - goto endloop; - } - } -endloop: + CValidationState state; if (!ProcessNewBlock(1,chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL)) throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); @@ -386,7 +430,6 @@ UniValue setgenerate(const UniValue& params, bool fHelp, const CPubKey& mypk) } #endif -CBlockIndex *komodo_chainactive(int32_t height); arith_uint256 zawy_ctB(arith_uint256 bnTarget,uint32_t solvetime); UniValue genminingCSV(const UniValue& params, bool fHelp, const CPubKey& mypk) @@ -395,7 +438,7 @@ UniValue genminingCSV(const UniValue& params, bool fHelp, const CPubKey& mypk) if (fHelp || params.size() != 0 ) throw runtime_error("genminingCSV\n"); LOCK(cs_main); - sprintf(fname,"%s_mining.csv",ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL); + sprintf(fname,"%s_mining.csv",chainName.ToString().c_str()); if ( (fp= fopen(fname,"wb")) != 0 ) { fprintf(fp,"height,nTime,nBits,bnTarget,bnTargetB,diff,solvetime\n"); @@ -694,7 +737,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp } // currently we have checkpoints only in KMD chain, so we checking IsInitialBlockDownload only for KMD itself - if (ASSETCHAINS_SYMBOL[0] == 0 && IsInitialBlockDownload()) { + if (chainName.isKMD() && IsInitialBlockDownload()) { throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Komodo is downloading blocks..."); } @@ -777,7 +820,6 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp ENTER_CRITICAL_SECTION(cs_main); if (!pblocktemplate) throw std::runtime_error("CreateNewBlock(): create block failed"); - //throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory or no available utxo for staking"); // Need to update only after we know CreateNewBlockWithKey succeeded pindexPrev = pindexPrevNew; @@ -869,8 +911,6 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp result.push_back(Pair("ac_staked", (int64_t)ASSETCHAINS_STAKED)); result.push_back(Pair("origtarget", hashTarget.GetHex())); } - /*else if ( ASSETCHAINS_ADAPTIVEPOW > 0 ) - result.push_back(Pair("target",komodo_adaptivepow_target((int32_t)(pindexPrev->nHeight+1),hashTarget,pblock->nTime).GetHex()));*/ else result.push_back(Pair("target", hashTarget.GetHex())); result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 136b49cb..76cb5597 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -31,6 +31,11 @@ #include "cc/eval.h" #include "cc/CCinclude.h" #include "hex.h" +#include "komodo_bitcoind.h" +#include "komodo_notary.h" +#include "komodo_utils.h" +#include "komodo_globals.h" +#include "cc/CCinclude.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" #include "wallet/walletdb.h" @@ -60,10 +65,8 @@ using namespace std; * Or alternatively, create a specific query method for the information. **/ -int32_t Jumblr_depositaddradd(char *depositaddr); +/*int32_t Jumblr_depositaddradd(char *depositaddr); int32_t Jumblr_secretaddradd(char *secretaddr); -uint64_t komodo_interestsum(); -int32_t komodo_longestchain(); int32_t komodo_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 *txidp); bool komodo_txnotarizedconfirmed(uint256 txid); uint32_t komodo_chainactive_timestamp(); @@ -71,13 +74,12 @@ int32_t komodo_whoami(char *pubkeystr,int32_t height,uint32_t timestamp); extern uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE; extern bool IS_KOMODO_NOTARY; extern int32_t KOMODO_LASTMINED,JUMBLR_PAUSE,KOMODO_LONGESTCHAIN,STAKED_NOTARY_ID,STAKED_ERA,KOMODO_INSYNC; -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; uint32_t komodo_segid32(char *coinaddr); int64_t komodo_coinsupply(int64_t *zfundsp,int64_t *sproutfundsp,int32_t height); int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp); int8_t StakedNotaryID(std::string ¬aryname, char *Raddress); uint64_t komodo_notarypayamount(int32_t nHeight, int64_t notarycount); -int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); +int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);*/ #define KOMODO_VERSION "0.7.2" extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; @@ -192,6 +194,19 @@ UniValue geterablockheights(const UniValue& params, bool fHelp, const CPubKey& m return(ret); } +/** + * @note Do not add or change anything in the information returned by this + * method. `getinfo` exists for backwards-compatibility only. It combines + * information from wildly different sources in the program, which is a mess, + * and is thus planned to be deprecated eventually. + * + * Based on the source of the information, new information should be added to: + * - `getblockchaininfo`, + * - `getnetworkinfo` or + * - `getwalletinfo` + * + * Or alternatively, create a specific query method for the information. + **/ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) { uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,longestchain,kmdnotarized_height,txid_height; @@ -244,18 +259,18 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) obj.push_back(Pair("notarizedtxid", notarized_desttxid.ToString())); if ( KOMODO_NSPV_FULLNODE ) { - txid_height = notarizedtxid_height(ASSETCHAINS_SYMBOL[0] != 0 ? (char *)"KMD" : (char *)"BTC",(char *)notarized_desttxid.ToString().c_str(),&kmdnotarized_height); + txid_height = notarizedtxid_height(!chainName.isKMD() ? (char *)"KMD" : (char *)"BTC",(char *)notarized_desttxid.ToString().c_str(),&kmdnotarized_height); if ( txid_height > 0 ) obj.push_back(Pair("notarizedtxid_height", txid_height)); else obj.push_back(Pair("notarizedtxid_height", "mempool")); - if ( ASSETCHAINS_SYMBOL[0] != 0 ) + if ( !chainName.isKMD() ) obj.push_back(Pair("KMDnotarized_height", kmdnotarized_height)); obj.push_back(Pair("notarized_confirms", txid_height < kmdnotarized_height ? (kmdnotarized_height - txid_height + 1) : 0)); //fprintf(stderr,"after notarized_confirms %u\n",(uint32_t)time(NULL)); #ifdef ENABLE_WALLET if (pwalletMain) { obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) { obj.push_back(Pair("interest", ValueFromAmount(KOMODO_INTERESTSUM))); obj.push_back(Pair("balance", ValueFromAmount(KOMODO_WALLETBALANCE))); //pwalletMain->GetBalance() @@ -306,15 +321,14 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) } if ( ASSETCHAINS_CC != 0 ) obj.push_back(Pair("CCid", (int)ASSETCHAINS_CC)); - obj.push_back(Pair("name", ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL)); + obj.push_back(Pair("name", chainName.ToString())); obj.push_back(Pair("p2pport", ASSETCHAINS_P2PPORT)); obj.push_back(Pair("rpcport", ASSETCHAINS_RPCPORT)); - if ( ASSETCHAINS_SYMBOL[0] != 0 ) + if ( !chainName.isKMD() ) { - if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 ) + if ( is_STAKED(chainName.symbol()) != 0 ) obj.push_back(Pair("StakedEra", STAKED_ERA)); - //obj.push_back(Pair("name", ASSETCHAINS_SYMBOL)); obj.push_back(Pair("magic", (int)ASSETCHAINS_MAGIC)); obj.push_back(Pair("premine", ASSETCHAINS_SUPPLY)); @@ -445,7 +459,7 @@ UniValue coinsupply(const UniValue& params, bool fHelp, const CPubKey& mypk) if ( (supply= komodo_coinsupply(&zfunds,&sproutfunds,height)) > 0 ) { result.push_back(Pair("result", "success")); - result.push_back(Pair("coin", ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL)); + result.push_back(Pair("coin", chainName.ToString())); result.push_back(Pair("height", (int)height)); result.push_back(Pair("supply", ValueFromAmount(supply))); result.push_back(Pair("zfunds", ValueFromAmount(zfunds))); @@ -479,64 +493,6 @@ UniValue coinsupply(const UniValue& params, bool fHelp, const CPubKey& mypk) return(result); } -UniValue jumblr_deposit(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - int32_t retval; UniValue result(UniValue::VOBJ); - if (fHelp || params.size() != 1) - throw runtime_error("jumblr_deposit \"depositaddress\"\n"); - CBitcoinAddress address(params[0].get_str()); - bool isValid = address.IsValid(); - if ( isValid != 0 ) - { - string addr = params[0].get_str(); - if ( (retval= Jumblr_depositaddradd((char *)addr.c_str())) >= 0 ) - { - result.push_back(Pair("result", retval)); - JUMBLR_PAUSE = 0; - } - else result.push_back(Pair("error", retval)); - } else result.push_back(Pair("error", "invalid address")); - return(result); -} - -UniValue jumblr_secret(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - int32_t retval; UniValue result(UniValue::VOBJ); - if (fHelp || params.size() != 1) - throw runtime_error("jumblr_secret \"secretaddress\"\n"); - CBitcoinAddress address(params[0].get_str()); - bool isValid = address.IsValid(); - if ( isValid != 0 ) - { - string addr = params[0].get_str(); - retval = Jumblr_secretaddradd((char *)addr.c_str()); - result.push_back(Pair("result", "success")); - result.push_back(Pair("num", retval)); - JUMBLR_PAUSE = 0; - } else result.push_back(Pair("error", "invalid address")); - return(result); -} - -UniValue jumblr_pause(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - int32_t retval; UniValue result(UniValue::VOBJ); - if (fHelp ) - throw runtime_error("jumblr_pause\n"); - JUMBLR_PAUSE = 1; - result.push_back(Pair("result", "paused")); - return(result); -} - -UniValue jumblr_resume(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - int32_t retval; UniValue result(UniValue::VOBJ); - if (fHelp ) - throw runtime_error("jumblr_resume\n"); - JUMBLR_PAUSE = 0; - result.push_back(Pair("result", "resumed")); - return(result); -} - UniValue validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (fHelp || params.size() != 1) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index f1e3e75a..9ea2dae5 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -28,6 +28,7 @@ #include "util.h" #include "version.h" #include "deprecation.h" +#include "komodo_defs.h" #include @@ -213,7 +214,7 @@ int32_t komodo_longestchain() if ( num > (n >> 1) ) { if ( 0 && height != KOMODO_LONGESTCHAIN ) - fprintf(stderr,"set %s KOMODO_LONGESTCHAIN <- %d\n",ASSETCHAINS_SYMBOL,height); + LogPrintf("set %s KOMODO_LONGESTCHAIN <- %d\n",chainName.symbol().c_str(),height); KOMODO_LONGESTCHAIN = height; return(height); } diff --git a/src/rpc/net.h b/src/rpc/net.h new file mode 100644 index 00000000..e00ae3d6 --- /dev/null +++ b/src/rpc/net.h @@ -0,0 +1,20 @@ +#pragma once +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +/****************************************************************************** + * Copyright © 2021 Komodo Core Developers * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +int32_t komodo_longestchain(); \ No newline at end of file diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 464658b2..8566c83e 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -36,11 +36,15 @@ #include "script/standard.h" #include "uint256.h" #include "importcoin.h" +#include "komodo_notary.h" +#include "komodo_bitcoind.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" #endif #include "komodo_defs.h" +#include "assetchain.h" +#include "komodo_interest.h" #include @@ -48,13 +52,8 @@ #include -int32_t komodo_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 *txidp); - using namespace std; -extern char ASSETCHAINS_SYMBOL[]; -int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); - void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex) { txnouttype type; @@ -140,8 +139,6 @@ UniValue TxJoinSplitToJSON(const CTransaction& tx) { return vjoinsplit; } -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); - UniValue TxShieldedSpendsToJSON(const CTransaction& tx) { UniValue vdesc(UniValue::VARR); for (const SpendDescription& spendDesc : tx.vShieldedSpend) { @@ -272,7 +269,7 @@ void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue& const CTxOut& txout = tx.vout[i]; UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); - if ( ASSETCHAINS_SYMBOL[0] == 0 && pindex != 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.Tip()) != 0 ) + if ( chainName.isKMD() && pindex != 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.Tip()) != 0 ) { int64_t interest; int32_t txheight; uint32_t locktime; interest = komodo_accrued_interest(&txheight,&locktime,tx.GetHash(),i,0,txout.nValue,(int32_t)tipindex->nHeight); @@ -374,7 +371,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) const CTxOut& txout = tx.vout[i]; UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); - if ( KOMODO_NSPV_FULLNODE && ASSETCHAINS_SYMBOL[0] == 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.Tip()) != 0 ) + if ( KOMODO_NSPV_FULLNODE && chainName.isKMD() && tx.nLockTime >= 500000000 && (tipindex= chainActive.Tip()) != 0 ) { int64_t interest; int32_t txheight; uint32_t locktime; interest = komodo_accrued_interest(&txheight,&locktime,tx.GetHash(),i,0,txout.nValue,(int32_t)tipindex->nHeight); @@ -561,56 +558,6 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp, const CPubKey& my return result; } -int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid,int32_t n) -{ - int32_t i,m; uint8_t *ptr; - LOCK(cs_main); - /*CCoins coins; - for (iter=0; iter<2; iter++) - { - if ( iter == 0 ) - { - LOCK(mempool.cs); - CCoinsViewMemPool view(pcoinsTip,mempool); - if ( view.GetCoins(txid,coins) == 0 ) - { - //LogPrintf("cant get view\n"); - continue; - } - mempool.pruneSpent(txid, coins); // TODO: this should be done by the CCoinsViewMemPool - } - else if ( pcoinsTip->GetCoins(txid,coins) == 0 ) - { - //LogPrintf("cant get pcoinsTip->GetCoins\n"); - continue; - } - if ( n < 0 || (unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() ) - { - LogPrintf("iter.%d n.%d vs voutsize.%d\n",iter,n,(int32_t)coins.vout.size()); - continue; - } - ptr = (uint8_t *)coins.vout[n].scriptPubKey.data(); - m = coins.vout[n].scriptPubKey.size(); - for (i=0; i @@ -255,8 +256,6 @@ UniValue help(const UniValue& params, bool fHelp, const CPubKey& mypk) return tableRPC.help(strCommand); } -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; - #ifdef ENABLE_WALLET void GenerateBitcoins(bool b, CWallet *pw, int t); #else @@ -281,7 +280,7 @@ UniValue stop(const UniValue& params, bool fHelp, const CPubKey& mypk) // Shutdown will take long enough that the response should get back StartShutdown(); - sprintf(buf,"%s server stopping",ASSETCHAINS_SYMBOL[0] != 0 ? ASSETCHAINS_SYMBOL : "Komodo"); + sprintf(buf,"%s server stopping", !chainName.isKMD() ? chainName.symbol().c_str() : "Komodo"); return buf; } @@ -333,9 +332,6 @@ static const CRPCCommand vRPCCommands[] = { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true }, { "blockchain", "verifychain", &verifychain, true }, { "blockchain", "getspentinfo", &getspentinfo, false }, - //{ "blockchain", "paxprice", &paxprice, true }, - //{ "blockchain", "paxpending", &paxpending, true }, - //{ "blockchain", "paxprices", &paxprices, true }, { "blockchain", "notaries", ¬aries, true }, //{ "blockchain", "height_MoM", &height_MoM, true }, //{ "blockchain", "txMoMproof", &txMoMproof, true }, @@ -479,23 +475,6 @@ static const CRPCCommand vRPCCommands[] = { "oracles", "oraclessample", &oraclessample, true }, { "oracles", "oraclessamples", &oraclessamples, true }, - // Prices - { "prices", "prices", &prices, true }, - { "prices", "pricesaddress", &pricesaddress, true }, - { "prices", "priceslist", &priceslist, true }, - { "prices", "mypriceslist", &mypriceslist, true }, - { "prices", "pricesinfo", &pricesinfo, true }, - { "prices", "pricesbet", &pricesbet, true }, - { "prices", "pricessetcostbasis", &pricessetcostbasis, true }, - { "prices", "pricescashout", &pricescashout, true }, - { "prices", "pricesrekt", &pricesrekt, true }, - { "prices", "pricesaddfunding", &pricesaddfunding, true }, - { "prices", "pricesgetorderbook", &pricesgetorderbook, true }, - { "prices", "pricesrefillfund", &pricesrefillfund, true }, - - // Pegs - { "pegs", "pegsaddress", &pegsaddress, true }, - // Payments { "payments", "paymentsaddress", &paymentsaddress, true }, { "payments", "paymentstxidopret", &payments_txidopret, true }, @@ -559,17 +538,6 @@ static const CRPCCommand vRPCCommands[] = //{ "tokens", "tokenfillswap", &tokenfillswap, true }, { "tokens", "tokenconvert", &tokenconvert, true }, - // pegs - { "pegs", "pegscreate", &pegscreate, true }, - { "pegs", "pegsfund", &pegsfund, true }, - { "pegs", "pegsget", &pegsget, true }, - { "pegs", "pegsredeem", &pegsredeem, true }, - { "pegs", "pegsliquidate", &pegsliquidate, true }, - { "pegs", "pegsexchange", &pegsexchange, true }, - { "pegs", "pegsaccounthistory", &pegsaccounthistory, true }, - { "pegs", "pegsaccountinfo", &pegsaccountinfo, true }, - { "pegs", "pegsworstaccounts", &pegsworstaccounts, true }, - { "pegs", "pegsinfo", &pegsinfo, true }, /* Address index */ { "addressindex", "getaddressmempool", &getaddressmempool, true }, @@ -590,10 +558,6 @@ static const CRPCCommand vRPCCommands[] = { "util", "estimatefee", &estimatefee, true }, { "util", "estimatepriority", &estimatepriority, true }, { "util", "z_validateaddress", &z_validateaddress, true }, /* uses wallet if enabled */ - { "util", "jumblr_deposit", &jumblr_deposit, true }, - { "util", "jumblr_secret", &jumblr_secret, true }, - { "util", "jumblr_pause", &jumblr_pause, true }, - { "util", "jumblr_resume", &jumblr_resume, true }, { "util", "invalidateblock", &invalidateblock, true }, { "util", "reconsiderblock", &reconsiderblock, true }, @@ -845,7 +809,7 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms // Return immediately if in warmup { LOCK(cs_rpcWarmup); - if (fRPCInWarmup) + if (fRPCInWarmup && strMethod != "help") throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); } @@ -884,12 +848,12 @@ std::vector CRPCTable::listCommands() const std::string HelpExampleCli(const std::string& methodname, const std::string& args) { - if ( ASSETCHAINS_SYMBOL[0] == 0 ) { + if ( chainName.isKMD() ) { return "> komodo-cli " + methodname + " " + args + "\n"; - } else if ((strncmp(ASSETCHAINS_SYMBOL, "HUSH3", 5) == 0) ) { + } else if ( chainName.SymbolStartsWith("HUSH3") ) { return "> hush-cli " + methodname + " " + args + "\n"; } else { - return "> komodo-cli -ac_name=" + strprintf("%s", ASSETCHAINS_SYMBOL) + " " + methodname + " " + args + "\n"; + return "> komodo-cli -ac_name=" + strprintf("%s", chainName.symbol().c_str()) + " " + methodname + " " + args + "\n"; } } @@ -901,8 +865,8 @@ std::string HelpExampleRpc(const std::string& methodname, const std::string& arg string experimentalDisabledHelpMsg(const string& rpc, const string& enableArg) { - string daemon = ASSETCHAINS_SYMBOL[0] == 0 ? "komodod" : "hushd"; - string ticker = ASSETCHAINS_SYMBOL[0] == 0 ? "komodo" : ASSETCHAINS_SYMBOL; + string daemon = chainName.isKMD() ? "komodod" : "hushd"; + string ticker = chainName.isKMD() ? "komodo" : chainName.symbol(); return "\nWARNING: " + rpc + " is disabled.\n" "To enable it, restart " + daemon + " with the -experimentalfeatures and\n" diff --git a/src/rpc/server.h b/src/rpc/server.h index 719989c2..0e6a4d36 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -281,11 +281,6 @@ extern UniValue oraclessubscribe(const UniValue& params, bool fHelp, const CPubK extern UniValue oraclesdata(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue oraclessample(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue oraclessamples(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pricesaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue priceslist(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue mypriceslist(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pricesinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pegsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue paymentsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue payments_release(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue payments_fund(const UniValue& params, bool fHelp, const CPubKey& mypk); @@ -348,16 +343,6 @@ extern UniValue FSMcreate(const UniValue& params, bool fHelp, const CPubKey& myp extern UniValue FSMlist(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue FSMinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue auctionaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pegscreate(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pegsfund(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pegsget(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pegsredeem(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pegsliquidate(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pegsexchange(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pegsaccounthistory(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pegsaccountinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pegsworstaccounts(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pegsinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp //extern UniValue getnewaddress64(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp @@ -414,11 +399,6 @@ extern UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp, const CPubK extern UniValue zc_raw_receive(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue jumblr_deposit(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue jumblr_secret(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue jumblr_pause(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue jumblr_resume(const UniValue& params, bool fHelp, const CPubKey& mypk); - extern UniValue getrawtransaction(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rcprawtransaction.cpp extern UniValue listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue lockunspent(const UniValue& params, bool fHelp, const CPubKey& mypk); @@ -523,20 +503,6 @@ extern UniValue notaries(const UniValue& params, bool fHelp, const CPubKey& mypk extern UniValue minerids(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue kvsearch(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue paxprice(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue paxpending(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue paxprices(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue paxdeposit(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue paxwithdraw(const UniValue& params, bool fHelp, const CPubKey& mypk); - -extern UniValue prices(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pricesbet(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pricessetcostbasis(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pricescashout(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pricesrekt(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pricesaddfunding(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pricesgetorderbook(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue pricesrefillfund(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue letsdebug(const UniValue& params, bool fHelp, const CPubKey& mypk); diff --git a/src/rpc/testtransactions.cpp b/src/rpc/testtransactions.cpp deleted file mode 100644 index c41e97e1..00000000 --- a/src/rpc/testtransactions.cpp +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include - -#include "amount.h" -#include "chain.h" -#include "chainparams.h" -#include "checkpoints.h" -#include "crosschain.h" -#include "base58.h" -#include "consensus/validation.h" -#include "cc/eval.h" -#include "main.h" -#include "primitives/transaction.h" -#include "rpc/server.h" -#include "streams.h" -#include "sync.h" -#include "util.h" -#include "script/script.h" -#include "script/script_error.h" -#include "script/sign.h" -#include "script/standard.h" - -#include - -#include - -#include - - -#include "cc/CCinclude.h" -#include "cc/CCPrices.h" - -using namespace std; - -int32_t ensure_CCrequirements(uint8_t evalcode); - -UniValue test_ac(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - // make fake token tx: - struct CCcontract_info *cp, C; - - if (fHelp || (params.size() != 4)) - throw runtime_error("incorrect params\n"); - if (ensure_CCrequirements(EVAL_HEIR) < 0) - throw runtime_error(CC_REQUIREMENTS_MSG); - - std::vector pubkey1; - std::vector pubkey2; - - pubkey1 = ParseHex(params[0].get_str().c_str()); - pubkey2 = ParseHex(params[1].get_str().c_str()); - - CPubKey pk1 = pubkey2pk(pubkey1); - CPubKey pk2 = pubkey2pk(pubkey2); - - if (!pk1.IsValid() || !pk2.IsValid()) - throw runtime_error("invalid pubkey\n"); - - int64_t txfee = 10000; - int64_t amount = atoll(params[2].get_str().c_str()) * COIN; - uint256 fundingtxid = Parseuint256((char *)params[3].get_str().c_str()); - - CPubKey myPubkey = pubkey2pk(Mypubkey()); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - - int64_t normalInputs = AddNormalinputs(mtx, myPubkey, txfee + amount, 60); - - if (normalInputs < txfee + amount) - throw runtime_error("not enough normals\n"); - - mtx.vout.push_back(MakeCC1of2vout(EVAL_HEIR, amount, pk1, pk2)); - - CScript opret; - fundingtxid = revuint256(fundingtxid); - - opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'A' << fundingtxid << (uint8_t)0); - - cp = CCinit(&C, EVAL_HEIR); - return(FinalizeCCTx(0, cp, mtx, myPubkey, txfee, opret)); -} - -UniValue test_heirmarker(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - // make fake token tx: - struct CCcontract_info *cp, C; - - if (fHelp || (params.size() != 1)) - throw runtime_error("incorrect params\n"); - if (ensure_CCrequirements(EVAL_HEIR) < 0) - throw runtime_error(CC_REQUIREMENTS_MSG); - - uint256 fundingtxid = Parseuint256((char *)params[0].get_str().c_str()); - - CPubKey myPubkey = pubkey2pk(Mypubkey()); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - - int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60); - if (normalInputs < 10000) - throw runtime_error("not enough normals\n"); - - mtx.vin.push_back(CTxIn(fundingtxid, 1)); - mtx.vout.push_back(MakeCC1vout(EVAL_HEIR, 10000, myPubkey)); - - CScript opret; - fundingtxid = revuint256(fundingtxid); - - opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'C' << fundingtxid << (uint8_t)0); - - cp = CCinit(&C, EVAL_HEIR); - return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, opret)); -} - -UniValue test_burntx(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - // make fake token tx: - struct CCcontract_info *cp, C; - - if (fHelp || (params.size() != 1)) - throw runtime_error("incorrect params\n"); - if (ensure_CCrequirements(EVAL_TOKENS) < 0) - throw runtime_error(CC_REQUIREMENTS_MSG); - - uint256 tokenid = Parseuint256((char *)params[0].get_str().c_str()); - - CPubKey myPubkey = pubkey2pk(Mypubkey()); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - - int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60); - if (normalInputs < 10000) - throw runtime_error("not enough normals\n"); - - CPubKey burnpk = pubkey2pk(ParseHex(CC_BURNPUBKEY)); - - mtx.vin.push_back(CTxIn(tokenid, 0)); - mtx.vin.push_back(CTxIn(tokenid, 1)); - mtx.vout.push_back(MakeTokensCC1vout(EVAL_TOKENS, 1, burnpk)); - - std::vector voutPubkeys; - voutPubkeys.push_back(burnpk); - - cp = CCinit(&C, EVAL_TOKENS); - - std::vector vopret; - GetNonfungibleData(tokenid, vopret); - if (vopret.size() > 0) - cp->additionalTokensEvalcode2 = vopret.begin()[0]; - - uint8_t tokenpriv[33]; - char unspendableTokenAddr[64]; - CPubKey unspPk = GetUnspendable(cp, tokenpriv); - GetCCaddress(cp, unspendableTokenAddr, unspPk); - CCaddr2set(cp, EVAL_TOKENS, unspPk, tokenpriv, unspendableTokenAddr); - return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, EncodeTokenOpRet(tokenid, voutPubkeys, std::make_pair(0, vscript_t())))); -} - -UniValue test_proof(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); - std::vectorproof; - - if (fHelp || (params.size() != 2)) - throw runtime_error("incorrect params\n"); - - - proof = ParseHex(params[0].get_str()); - uint256 cointxid = Parseuint256((char *)params[1].get_str().c_str()); - - std::vector txids; - - CMerkleBlock merkleBlock; - if (!E_UNMARSHAL(proof, ss >> merkleBlock)) { - result.push_back(Pair("error", "could not unmarshal proof")); - return result; - } - uint256 merkleRoot = merkleBlock.txn.ExtractMatches(txids); - - result.push_back(Pair("source_root", merkleRoot.GetHex())); - - for (int i = 0; i < txids.size(); i++) - std::cerr << "merkle block txid=" << txids[0].GetHex() << std::endl; - - - std::vector vMatches(txids.size()); - for (auto v : vMatches) v = true; - CPartialMerkleTree verifTree(txids, vMatches); - - result.push_back(Pair("verif_root", verifTree.ExtractMatches(txids).GetHex())); - - if (std::find(txids.begin(), txids.end(), cointxid) == txids.end()) { - fprintf(stderr, "invalid proof for this cointxid\n"); - } - - std::vector vMerkleTree; - bool f; - ::BuildMerkleTree(&f, txids, vMerkleTree); - - std::vector vMerkleBranch = ::GetMerkleBranch(0, txids.size(), vMerkleTree); - - uint256 ourResult = SafeCheckMerkleBranch(zeroid, vMerkleBranch, 0); - result.push_back(Pair("SafeCheckMerkleBranch", ourResult.GetHex())); - - return result; -} - -extern CScript prices_costbasisopret(uint256 bettxid, CPubKey mypk, int32_t height, int64_t costbasis); -UniValue test_pricesmarker(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - // make fake token tx: - struct CCcontract_info *cp, C; - - if (fHelp || (params.size() != 1)) - throw runtime_error("incorrect params\n"); - if (ensure_CCrequirements(EVAL_PRICES) < 0) - throw runtime_error(CC_REQUIREMENTS_MSG); - - uint256 bettxid = Parseuint256((char *)params[0].get_str().c_str()); - - cp = CCinit(&C, EVAL_PRICES); - CPubKey myPubkey = pubkey2pk(Mypubkey()); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - - int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60); - if (normalInputs < 10000) - throw runtime_error("not enough normals\n"); - - mtx.vin.push_back(CTxIn(bettxid, 1)); - mtx.vout.push_back(CTxOut(1000, CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG)); - - return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, prices_costbasisopret(bettxid, myPubkey, 100, 100))); -} - - -static const CRPCCommand commands[] = -{ // category name actor (function) okSafeMode - // --------------------- ------------------------ ----------------------- ---------- - - /* Not shown in help */ - { "hidden", "test_ac", &test_ac, true }, - { "hidden", "test_heirmarker", &test_heirmarker, true }, - { "hidden", "test_proof", &test_proof, true }, - { "hidden", "test_burntx", &test_burntx, true }, - { "hidden", "test_pricesmarker", &test_pricesmarker, true } -}; - -void RegisterTesttransactionsRPCCommands(CRPCTable &tableRPC) -{ - for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) - tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); -} diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 24398622..1f5d8b1c 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1204,6 +1204,17 @@ SigVersion SignatureHashVersion(const CTransaction& txTo) } } +/***** + * Generate a signature hash + * @param scriptCode the scriptPubKey + * @param txTo the transaction we are trying to create + * @param nIn the index of the vIn that has the data to sign + * @param nHashType the hash type (i.e. SIGHASH_ALL) + * @param amount the amount (for hidden txs) + * @param consensusBranchId the branch id + * @param cache additional data + * @returns the signature + */ uint256 SignatureHash( const CScript& scriptCode, const CTransaction& txTo, diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 5b1abfdd..c114d5ec 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -36,13 +36,6 @@ using namespace std; typedef vector valtype; extern uint8_t ASSETCHAINS_TXPOW; extern char NSPV_wifstr[],NSPV_pubkeystr[]; -extern int32_t KOMODO_NSPV; -#ifndef KOMODO_NSPV_FULLNODE -#define KOMODO_NSPV_FULLNODE (KOMODO_NSPV <= 0) -#endif // !KOMODO_NSPV_FULLNODE -#ifndef KOMODO_NSPV_SUPERLITE -#define KOMODO_NSPV_SUPERLITE (KOMODO_NSPV > 0) -#endif // !KOMODO_NSPV_SUPERLITE uint256 SIG_TXHASH; diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 4e77f7f1..13c75e85 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -204,7 +204,13 @@ static bool MatchMultisig(const CScript& script, unsigned int& required, std::ve return (it + 1 == script.end()); } - +/**** + * @brief interrogate a script + * @param[in] scriptPubKey what to examine + * @param[out] typeRet the type of transaction + * @param[out] vSolutionsRet results + * @returns true on success + */ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutionsRet) { vSolutionsRet.clear(); diff --git a/src/sendalert.cpp b/src/sendalert.cpp index 7936f725..a3e138b2 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -53,7 +53,6 @@ the bad alert. */ -#include "main.h" #include "net.h" #include "alert.h" #include "init.h" diff --git a/src/txdb.cpp b/src/txdb.cpp index 425b1e83..772665cd 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -27,6 +27,7 @@ #include "pow.h" #include "uint256.h" #include "core_io.h" +#include "komodo_bitcoind.h" #include "ui_interface.h" #include "init.h" @@ -440,7 +441,6 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, int type, } bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address); -uint32_t komodo_segid32(char *coinaddr); #define DECLARE_IGNORELIST std::map ignoredMap = { \ {"RReUxSs5hGE39ELU23DfydX8riUuzdrHAE", 1}, \ @@ -567,7 +567,6 @@ extern std::vector > vAddressSnapshot; UniValue CBlockTreeDB::Snapshot(int top) { - int topN = 0; std::vector > vaddr; //std::vector >> tokenids; std::map addressAmounts; diff --git a/src/txdb.h b/src/txdb.h index 195f4c18..229890e9 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -53,7 +53,9 @@ static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024; //! min. -dbcache in (MiB) static const int64_t nMinDbCache = 4; -/** CCoinsView backed by the coin database (chainstate/) */ +/** + * CCoinsView backed by the coin database (chainstate/) +*/ class CCoinsViewDB : public CCoinsView { protected: @@ -65,7 +67,17 @@ class CCoinsViewDB : public CCoinsView bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const; bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const; bool GetNullifier(const uint256 &nf, ShieldedType type) const; + /*** + * @param txid the transaction id + * @param coins the coins within the txid + * @returns true on success + */ bool GetCoins(const uint256 &txid, CCoins &coins) const; + /**** + * Determine if a txid exists + * @param txid + * @returns true if the txid exists in the database + */ bool HaveCoins(const uint256 &txid) const; uint256 GetBestBlock() const; uint256 GetBestAnchor(ShieldedType type) const; @@ -80,42 +92,208 @@ class CCoinsViewDB : public CCoinsView bool GetStats(CCoinsStats &stats) const; }; -/** Access to the block database (blocks/index/) */ +/** + * Access to the block database (blocks/index/) + * This database consists of: + * - CBlockFileInfo records that contain info about the individual files that store blocks + * - CBlockIndex info about the blocks themselves + * - txid / CDiskTxPos index + * - spent index + * - unspent index + * - address / amount + * - timestamp index + * - block hash / timestamp index + */ class CBlockTreeDB : public CDBWrapper { public: + /**** + * ctor + * + * @param nCacheSize leveldb cache size + * @param fMemory use leveldb memory environment + * @param fWipe wipe data + * @param compression enable leveldb compression + * @param maxOpenFiles leveldb max open files + */ CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false, bool compression = true, int maxOpenFiles = 1000); private: CBlockTreeDB(const CBlockTreeDB&); void operator=(const CBlockTreeDB&); public: - bool WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo); + /*** + * Write a batch of records and sync + * @param fileInfo the block file info records to write + * @param nLastFile the value for DB_LAST_BLOCK + * @param blockinfo the block index records to write + * @returns true on success + */ + bool WriteBatchSync(const std::vector >& fileInfo, int nLastFile, + const std::vector& blockinfo); + /*** + * Erase a batch of block index records and sync + * @param blockinfo the records + * @returns true on success + */ bool EraseBatchSync(const std::vector& blockinfo); + /*** + * Read the file information + * @param nFile the file to read + * @param fileinfo where to store the results + * @returns true on success + */ bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo); + /**** + * Read the value of DB_LAST_BLOCK + * @param nFile where to store the results + * @returns true on success + */ bool ReadLastBlockFile(int &nFile); + /*** + * Write to the DB_REINDEX_FLAG + * @param fReindex true to set DB_REINDEX_FLAG, false to erase the key + * @returns true on success + */ bool WriteReindexing(bool fReindex); + /**** + * Retrieve the value of DB_REINDEX_FLAG + * @param fReindex true if DB_REINDEX_FLAG exists + * @returns true on success + */ bool ReadReindexing(bool &fReindex); + /*** + * Retrieve the location of a particular transaction index value + * @param txid what to look for + * @param pos the results + * @returns true on success + */ bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos); + /**** + * Write transaction index records + * @param list the records to write + * @returns true on success + */ bool WriteTxIndex(const std::vector > &list); + /**** + * Read a value from the spent index + * @param key the key + * @param value the value + * @returns true on success + */ bool ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); + /**** + * Update a batch of spent index entries + * @param vect the entries to add/update + * @returns true on success + */ bool UpdateSpentIndex(const std::vector >&vect); + /**** + * Update the unspent indexes for an address + * @param vect the name/value pairs + * @returns true on success + */ bool UpdateAddressUnspentIndex(const std::vector >&vect); + /**** + * Read the unspent key/value pairs for a particular address + * @param addressHash the address + * @param type the address type + * @param vect the results + * @returns true on success + */ bool ReadAddressUnspentIndex(uint160 addressHash, int type, std::vector > &vect); + /***** + * Write a batch of address index / amount records + * @param vect a collection of address index/amount records + * @returns true on success + */ bool WriteAddressIndex(const std::vector > &vect); + /**** + * Remove a batch of address index / amount records + * @param vect the records to erase + * @returns true on success + */ bool EraseAddressIndex(const std::vector > &vect); + /**** + * Read a range of address index / amount records for a particular address + * @param addressHash the address to look for + * @param type the address type + * @param addressIndex the address index / amount records found + * @param start the starting index + * @param end the end + * @returns true on success + */ bool ReadAddressIndex(uint160 addressHash, int type, std::vector > &addressIndex, int start = 0, int end = 0); + /**** + * Write a timestamp entry to the db + * @param timestampIndex the record to write + * @returns true on success + */ bool WriteTimestampIndex(const CTimestampIndexKey ×tampIndex); - bool ReadTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector > &vect); + /**** + * Read the timestamp entry from the db + * @param high ending timestamp (most recent) + * @param low starting timestamp (oldest) + * @param fActiveOnly only include on-chain active entries in the results + * @param vect the results + * @returns true on success + */ + bool ReadTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, + std::vector > &vect); + /**** + * Write a block hash / timestamp record + * @param blockhashIndex the key (the hash) + * @param logicalts the value (the timestamp) + * @returns true on success + */ bool WriteTimestampBlockIndex(const CTimestampBlockIndexKey &blockhashIndex, const CTimestampBlockIndexValue &logicalts); + /***** + * Given a hash, find its timestamp + * @param hash the hash (the key) + * @param logicalTS the timestamp (the value) + * @returns true on success + */ bool ReadTimestampBlockIndex(const uint256 &hash, unsigned int &logicalTS); + /*** + * Store a flag value in the DB + * @param name the key + * @param fValue the value + * @returns true on success + */ bool WriteFlag(const std::string &name, bool fValue); + /*** + * Read a flag value from the DB + * @param name the key + * @param fValue the value + * @returns true on success + */ bool ReadFlag(const std::string &name, bool &fValue); + /**** + * Load the block headers from disk + * NOTE: this does no consistency check beyond verifying records exist + * @returns true on success + */ bool LoadBlockIndexGuts(); + /**** + * Check if a block is on the active chain + * @param hash the block hash + * @returns true if the block exists on the active chain + */ bool blockOnchainActive(const uint256 &hash); + /**** + * Get a snapshot + * @param top max number of results, sorted by amount descending (aka richlist) + * @returns the data ( a collection of (addr, amount, segid) ) + */ UniValue Snapshot(int top); + /**** + * Get a snapshot + * @param addressAmounts the results + * @param ret results summary (passing nullptr skips compiling this summary) + * @returns true on success + */ bool Snapshot2(std::map &addressAmounts, UniValue *ret); }; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 4037843e..e5c1e900 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -31,7 +31,9 @@ #include "utilmoneystr.h" #include "validationinterface.h" #include "version.h" -#define _COINBASE_MATURITY 100 +#include "komodo_globals.h" +#include "komodo_utils.h" +#include "komodo_bitcoind.h" using namespace std; @@ -391,15 +393,8 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list& rem } } -extern uint64_t ASSETCHAINS_TIMELOCKGTE; -int64_t komodo_block_unlocktime(uint32_t nHeight); - void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) { - // Remove transactions spending a coinbase which are now immature - extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) - COINBASE_MATURITY = _COINBASE_MATURITY; // Remove transactions spending a coinbase which are now immature and no-longer-final transactions LOCK(cs); list transactionsToRemove; @@ -414,7 +409,7 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem continue; const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); if (nCheckFrequency != 0) assert(coins); - if (!coins || (coins->IsCoinBase() && (((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY) && + if (!coins || (coins->IsCoinBase() && (((signed long)nMemPoolHeight) - coins->nHeight < Params().CoinbaseMaturity()) && ((signed long)nMemPoolHeight < komodo_block_unlocktime(coins->nHeight) && coins->IsAvailable(0) && coins->vout[0].nValue >= ASSETCHAINS_TIMELOCKGTE))) { transactionsToRemove.push_back(tx); @@ -508,33 +503,26 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list } } -int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag); -extern char ASSETCHAINS_SYMBOL[]; - void CTxMemPool::removeExpired(unsigned int nBlockHeight) { CBlockIndex *tipindex; // Remove expired txs from the mempool LOCK(cs); - list transactionsToRemove; + std::list transactionsToRemove; for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { const CTransaction& tx = it->GetTx(); tipindex = chainActive.Tip(); - /* cmptime = chainActive.Tip()->GetMedianTimePast() + 777 - here for interest validation, inside - CTxMemPool::removeExpired. need to test, may be here better to validate against pindexNew->nTime. - In ConnectBlock we have a condition for each tx like komodo_validate_interest(..., block.nTime), so - blocks mined with such txes will be valid. Mean, may be chainActive.Tip()->GetMedianTimePast() + 777 - is "too earlier" condition. [nBlockHeight should be equal tipindex->nHeight+1 here] - */ - - // if (IsExpiredTx(tx, nBlockHeight) || (ASSETCHAINS_SYMBOL[0] == 0 && tipindex != 0 && komodo_validate_interest(tx,tipindex->nHeight+1,tipindex->GetMedianTimePast() + 777,0)) < 0) - bool fInterestNotValidated = ASSETCHAINS_SYMBOL[0] == 0 && tipindex != 0 && komodo_validate_interest(tx,tipindex->nHeight+1,tipindex->GetMedianTimePast() + 777,0) < 0; + bool fInterestNotValidated = chainName.isKMD() + && tipindex != 0 + && komodo_validate_interest(tx,tipindex->nHeight+1,tipindex->GetMedianTimePast() + 777,0) < 0; if (IsExpiredTx(tx, nBlockHeight) || fInterestNotValidated) { if (fInterestNotValidated && tipindex != 0) - LogPrintf("Removing interest violate txid.%s nHeight.%d nTime.%u vs locktime.%u\n",tx.GetHash().ToString(),tipindex->nHeight+1,tipindex->GetMedianTimePast() + 777,tx.nLockTime); + LogPrintf("Removing interest violate txid.%s nHeight.%d nTime.%u vs locktime.%u\n", + tx.GetHash().ToString(),tipindex->nHeight+1, + tipindex->GetMedianTimePast() + 777,tx.nLockTime); transactionsToRemove.push_back(tx); } } diff --git a/src/util.cpp b/src/util.cpp index fd41b102..1669b28e 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -30,7 +30,7 @@ #include "sync.h" #include "utilstrencodings.h" #include "utiltime.h" -#include "komodo_defs.h" +#include "komodo_globals.h" #include #include @@ -536,52 +536,71 @@ void PrintExceptionContinue(const std::exception* pex, const char* pszThread) strMiscWarning = message; } -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; -//int64_t MAX_MONEY = 200000000 * 100000000LL; - -boost::filesystem::path GetDefaultDataDir() +/** + * @brief get the OS-specific default application data directory + * @note Windows: be "C:\Users\[username]\AppData\Roaming" + * @note Mac: ~/Library/Application Support + * @note Unix: ~/ + * @returns the default path to the application data directory + */ +boost::filesystem::path GetAppDir() { - namespace fs = boost::filesystem; - char symbol[KOMODO_ASSETCHAIN_MAXLEN]; - if ( ASSETCHAINS_SYMBOL[0] != 0 ){ - strcpy(symbol,ASSETCHAINS_SYMBOL); - } - - else symbol[0] = 0; - // Windows < Vista: C:\Documents and Settings\Username\Application Data\Zcash - // Windows >= Vista: C:\Users\Username\AppData\Roaming\Zcash - // Mac: ~/Library/Application Support/Zcash - // Unix: ~/.zcash + // Windows < Vista: C:\Documents and Settings\Username\Application Data + // Windows >= Vista: C:\Users\Username\AppData\Roaming + // Mac: ~/Library/Application Support + // Unix: ~ + fs::path pathRet; + #ifdef _WIN32 // Windows - if ( symbol[0] == 0 ) - return GetSpecialFolderPath(CSIDL_APPDATA) / "Komodo"; - else return GetSpecialFolderPath(CSIDL_APPDATA) / "Komodo" / symbol; + pathRet = GetSpecialFolderPath(CSIDL_APPDATA); #else - fs::path pathRet; + // Linux or Mac char* pszHome = getenv("HOME"); if (pszHome == NULL || strlen(pszHome) == 0) pathRet = fs::path("/"); else pathRet = fs::path(pszHome); -#ifdef MAC_OSX + #ifdef MAC_OSX // Mac - pathRet /= "Library/Application Support"; + pathRet /= "Library"; TryCreateDirectory(pathRet); - if ( symbol[0] == 0 ) - return pathRet / "Komodo"; + pathRet /= "Application Support"; + TryCreateDirectory(pathRet); // not sure why this is needed as GetDataDir will create the whole path + #endif +#endif + return pathRet; +} + +/**** + * @brief get the OS-specific default komodod data directory + * @note Windows: be "C:\Users\[username]\AppData\Roaming\Komodo" + * @note Mac: ~/Library/Application Support/Komodo + * @note Unix: ~/.komodo + * @returns the default path to the Komodo data directory + */ +boost::filesystem::path GetDefaultDataDir() +{ + fs::path pathRet = GetAppDir(); + +#if defined(_WIN32) || defined(MAC_OSX) + if (chainName.isKMD()) + { + pathRet /= "Komodo"; + } else { pathRet /= "Komodo"; TryCreateDirectory(pathRet); - return pathRet / symbol; + pathRet /= chainName.symbol(); } + return pathRet; #else // Unix - if ( symbol[0] == 0 ) + if (chainName.isKMD()) return pathRet / ".komodo"; - else return pathRet / ".komodo" / symbol; -#endif + else + return pathRet / ".komodo" / chainName.symbol(); #endif } @@ -657,7 +676,13 @@ const boost::filesystem::path GetExportDir() return path; } - +/**** + * @brief determine the data directory + * @note looks at the -datadir command-line parameter or OS-specific defaults + * @note creates the directory if it does not already exist + * @param fNetSpecific if true, adds network-specific subdirectory (i.e. "regtest" or "testnet3") + * @returns the full OS-specific data directory including Komodo (i.e. "~/.komodo") + */ const boost::filesystem::path &GetDataDir(bool fNetSpecific) { namespace fs = boost::filesystem; @@ -685,8 +710,6 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific) path /= BaseParams().DataDir(); fs::create_directories(path); - //std::string assetpath = path + "/assets"; - //boost::filesystem::create_directory(assetpath); return path; } @@ -699,8 +722,8 @@ void ClearDatadirCache() boost::filesystem::path GetConfigFile() { char confname[512]; - if ( !mapArgs.count("-conf") && ASSETCHAINS_SYMBOL[0] != 0 ){ - sprintf(confname,"%s.conf",ASSETCHAINS_SYMBOL); + if ( !mapArgs.count("-conf") && !chainName.isKMD() ){ + sprintf(confname,"%s.conf",chainName.symbol().c_str()); } else { @@ -742,7 +765,6 @@ void ReadConfigFile(map& mapSettingsRet, } // If datadir is changed in .conf file: ClearDatadirCache(); - extern uint16_t BITCOIND_RPCPORT; BITCOIND_RPCPORT = GetArg("-rpcport",BaseParams().RPCPort()); } diff --git a/src/util.h b/src/util.h index 7e35a8c5..3b0305b9 100644 --- a/src/util.h +++ b/src/util.h @@ -143,6 +143,21 @@ void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length); bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest); bool TryCreateDirectories(const boost::filesystem::path& p); bool TryCreateDirectory(const boost::filesystem::path& p); +/** + * @brief get the OS-specific default application data directory + * @note Windows: be "C:\Users\[username]\AppData\Roaming" + * @note Mac: ~/Library/Application Support + * @note Unix: ~/ + * @returns the default path to the application data directory + */ +boost::filesystem::path GetAppDir(); +/**** + * @brief get the OS-specific default komodod data directory + * @note Windows: be "C:\Users\[username]\AppData\Roaming\Komodo" + * @note Mac: ~/Library/Application Support/Komodo + * @note Unix: ~/.komodo + * @returns the default path to the Komodo data directory + */ boost::filesystem::path GetDefaultDataDir(); const boost::filesystem::path &GetDataDir(bool fNetSpecific = true); void ClearDatadirCache(); diff --git a/src/utiltime.cpp b/src/utiltime.cpp index bd7fd501..8f5835b5 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -9,32 +9,45 @@ #include "utiltime.h" +#include #include #include #include -using namespace std; - static int64_t nMockTime = 0; //! For unit testing +/*** + * Get the current time + */ int64_t GetTime() { - if (nMockTime) return nMockTime; + if (nMockTime) + return nMockTime; return time(NULL); } +/*** + * Set the current time (for unit testing) + * @param nMocKtimeIn the time that will be returned by GetTime() + */ void SetMockTime(int64_t nMockTimeIn) { nMockTime = nMockTimeIn; } +/*** + * @returns the system time in milliseconds since the epoch (1/1/1970) + */ int64_t GetTimeMillis() { return std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); } +/**** + * @returns the system time in microseconds since the epoch (1/1/1970) + */ int64_t GetTimeMicros() { return std::chrono::duration_cast( @@ -46,11 +59,21 @@ int64_t GetSystemTimeInSeconds() return GetTimeMicros()/1000000; } +/**** + * @param n the number of milliseconds to put the current thread to sleep + */ void MilliSleep(int64_t n) { + //std::this_thread::sleep_for(std::chrono::milliseconds(n)); <-- unable to use due to boost interrupt logic boost::this_thread::sleep_for(boost::chrono::milliseconds(n)); } +/*** + * Convert time into a formatted string + * @param pszFormat the format + * @param nTime the time + * @returns the time in the format + */ std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime) { // std::locale takes ownership of the pointer diff --git a/src/utiltime.h b/src/utiltime.h index 0dfcfbbc..45aa4ba1 100644 --- a/src/utiltime.h +++ b/src/utiltime.h @@ -2,20 +2,43 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_UTILTIME_H -#define BITCOIN_UTILTIME_H +#pragma once #include #include +/*** + * Set the current time (for unit testing) + * @param nMocKtimeIn the time that will be returned by GetTime() + */ +void SetMockTime(int64_t nMockTimeIn); + +/*** + * @brief Get the current time + */ int64_t GetTime(); + +/*** + * @returns the system time in milliseconds since the epoch (1/1/1970) + */ int64_t GetTimeMillis(); + +/**** + * @returns the system time in microseconds since the epoch (1/1/1970) + */ int64_t GetTimeMicros(); + int64_t GetSystemTimeInSeconds(); // Like GetTime(), but not mockable -void SetMockTime(int64_t nMockTimeIn); + +/**** + * @param n the number of milliseconds to put the current thread to sleep + */ void MilliSleep(int64_t n); +/*** + * Convert time into a formatted string + * @param pszFormat the format + * @param nTime the time + * @returns the time in the format + */ std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime); - -#endif // BITCOIN_UTILTIME_H diff --git a/src/wallet-utility.cpp b/src/wallet-utility.cpp index 4622a105..7137334b 100644 --- a/src/wallet-utility.cpp +++ b/src/wallet-utility.cpp @@ -9,7 +9,10 @@ #include #include "komodo_defs.h" -char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; + +#include "assetchain.h" +assetchain chainName; + int64_t MAX_MONEY = 200000000 * 100000000LL; uint64_t ASSETCHAINS_SUPPLY; uint16_t BITCOIND_RPCPORT = 7771; diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index afac9c6e..9556723c 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -39,6 +39,7 @@ #include "wallet.h" #include "walletdb.h" #include "zcash/IncrementalMerkleTree.hpp" +#include "komodo_bitcoind.h" #include #include @@ -46,7 +47,6 @@ #include #include "paymentdisclosuredb.h" -int32_t komodo_blockheight(uint256 hash); using namespace libzcash; diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 08f22a71..a1ef6860 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -39,6 +39,10 @@ #include "zcash/IncrementalMerkleTree.hpp" #include "sodium.h" #include "miner.h" +#include "komodo_notary.h" +#include "komodo_bitcoind.h" +#include "rpc/rawtransaction.h" +#include "komodo_bitcoind.h" #include @@ -52,15 +56,6 @@ using namespace libzcash; -extern char ASSETCHAINS_SYMBOL[65]; - -int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); -int32_t komodo_blockheight(uint256 hash); -int tx_height( const uint256 &hash ); -bool komodo_hardfork_active(uint32_t time); -extern UniValue signrawtransaction(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue sendrawtransaction(const UniValue& params, bool fHelp, const CPubKey& mypk); - int find_output(UniValue obj, int n) { UniValue outputMapValue = find_value(obj, "outputmap"); if (!outputMapValue.isArray()) { @@ -374,7 +369,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { } // for Komodo, set lock time to accure interest, for other chains, set // locktime to spend time locked coinbases - if (ASSETCHAINS_SYMBOL[0] == 0) + if (chainName.isKMD()) { //if ((uint32_t)chainActive.Tip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) if ( !komodo_hardfork_active((uint32_t)chainActive.Tip()->nTime) ) @@ -391,7 +386,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { CTxIn in(COutPoint(txid, vout)); rawTx.vin.push_back(in); } - if (ASSETCHAINS_SYMBOL[0] == 0) + if (chainName.isKMD()) { //if ((uint32_t)chainActive.Tip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) if ( !komodo_hardfork_active((uint32_t)chainActive.Tip()->nTime) ) diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index 6db4eb6c..9cedc431 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -38,6 +38,7 @@ #include "zcash/IncrementalMerkleTree.hpp" #include "sodium.h" #include "miner.h" +#include "komodo_globals.h" #include #include @@ -51,7 +52,6 @@ #include "paymentdisclosuredb.h" using namespace libzcash; -extern uint64_t ASSETCHAINS_TIMELOCKGTE; static int find_output(UniValue obj, int n) { UniValue outputMapValue = find_value(obj, "outputmap"); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 83aa75a6..146fb493 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -28,7 +28,7 @@ #include "util.h" #include "utiltime.h" #include "wallet.h" - +#include "komodo_nSPV_defs.h" #include #include @@ -972,13 +972,6 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp, const CPubKey& m return EncodeViewingKey(vk); } -extern int32_t KOMODO_NSPV; -#ifndef KOMODO_NSPV_FULLNODE -#define KOMODO_NSPV_FULLNODE (KOMODO_NSPV <= 0) -#endif // !KOMODO_NSPV_FULLNODE -#ifndef KOMODO_NSPV_SUPERLITE -#define KOMODO_NSPV_SUPERLITE (KOMODO_NSPV > 0) -#endif // !KOMODO_NSPV_SUPERLITE uint256 zeroid; UniValue NSPV_getinfo_req(int32_t reqht); UniValue NSPV_login(char *wifstr); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 536623ef..233aaabb 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -38,6 +38,12 @@ #include "script/interpreter.h" #include "zcash/zip32.h" #include "notaries_staked.h" +#include "komodo.h" +#include "komodo_bitcoind.h" +#include "komodo_notary.h" +#include "komodo_kv.h" +#include "komodo_gateway.h" +#include "komodo_globals.h" #include "utiltime.h" #include "asyncrpcoperation.h" @@ -54,13 +60,15 @@ #include #include -//#include #include #include +#include "main.h" +#include "rpc/rawtransaction.h" #include "komodo_defs.h" +#include "komodo_interest.h" #include "hex.h" #include @@ -68,18 +76,9 @@ using namespace std; using namespace libzcash; -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; -extern std::string ASSETCHAINS_OVERRIDE_PUBKEY; const std::string ADDR_TYPE_SPROUT = "sprout"; const std::string ADDR_TYPE_SAPLING = "sapling"; -extern UniValue TxJoinSplitToJSON(const CTransaction& tx); -extern int32_t KOMODO_INSYNC; -uint32_t komodo_segid32(char *coinaddr); -int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); -int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime); // from ac_private chains only -CBlockIndex *komodo_getblockindex(uint256 hash); - int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; std::string CCerror; @@ -91,8 +90,6 @@ UniValue z_getoperationstatus_IMPL(const UniValue&, bool); #define VALID_PLAN_NAME(x) (strlen(x) <= PLAN_NAME_MAX) #define THROW_IF_SYNCING(INSYNC) if (INSYNC == 0) { throw runtime_error(strprintf("%s: Chain still syncing at height %d, aborting to prevent linkability analysis!",__FUNCTION__,chainActive.Tip()->nHeight)); } -int tx_height( const uint256 &hash ); - std::string HelpRequiringPassphrase() { return pwalletMain && pwalletMain->IsCrypted() @@ -136,8 +133,6 @@ void Unlock2NSPV(const CPubKey &pk) } } -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); - void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) { //int32_t i,n,txheight; uint32_t locktime; uint64_t interest = 0; @@ -167,17 +162,9 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) entry.push_back(Pair("vjoinsplit", TxJoinSplitToJSON(wtx))); } -string AccountFromValue(const UniValue& value) +const std::string AccountFromValue(const UniValue& value) { - string strAccount = value.get_str(); - //if (strAccount != "") - // throw JSONRPCError(RPC_WALLET_ACCOUNTS_UNSUPPORTED, "Accounts are unsupported"); - return strAccount; -} - -char *komodo_chainname() -{ - return(ASSETCHAINS_SYMBOL[0] == 0 ? (char *)"KMD" : ASSETCHAINS_SYMBOL); + return value.get_str(); } void OS_randombytes(unsigned char *x,long xlen); @@ -190,11 +177,11 @@ UniValue getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) if (fHelp || params.size() > 1) throw runtime_error( "getnewaddress ( \"account\" )\n" - "\nReturns a new " + strprintf("%s",komodo_chainname()) + " address for receiving payments.\n" + "\nReturns a new " + chainName.ToString() + " address for receiving payments.\n" "\nArguments:\n" "1. \"account\" (string, optional) DEPRECATED. If provided, it MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "\nResult:\n" - "\"" + strprintf("%s",komodo_chainname()) + "_address\" (string) The new " + strprintf("%s",komodo_chainname()) + " address\n" + "\"" + chainName.ToString() + "_address\" (string) The new " + chainName.ToString() + " address\n" "\nExamples:\n" + HelpExampleCli("getnewaddress", "") + HelpExampleRpc("getnewaddress", "") @@ -284,11 +271,11 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp, const CPubKey& my if (fHelp || params.size() != 1) throw runtime_error( "getaccountaddress \"account\"\n" - "\nDEPRECATED. Returns the current " + strprintf("%s",komodo_chainname()) + " address for receiving payments to this account.\n" + "\nDEPRECATED. Returns the current " + chainName.ToString() + " address for receiving payments to this account.\n" "\nArguments:\n" "1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "\nResult:\n" - "\"" + strprintf("%s",komodo_chainname()) + "_address\" (string) The account " + strprintf("%s",komodo_chainname()) + " address\n" + "\"" + chainName.ToString() + "_address\" (string) The account " + chainName.ToString() + " address\n" "\nExamples:\n" + HelpExampleCli("getaccountaddress", "") + HelpExampleCli("getaccountaddress", "\"\"") @@ -316,7 +303,7 @@ UniValue getrawchangeaddress(const UniValue& params, bool fHelp, const CPubKey& if (fHelp || params.size() > 1) throw runtime_error( "getrawchangeaddress\n" - "\nReturns a new " + strprintf("%s",komodo_chainname()) + " address, for receiving change.\n" + "\nReturns a new " + chainName.ToString() + " address, for receiving change.\n" "This is for use with raw transactions, NOT normal use.\n" "\nResult:\n" "\"address\" (string) The address\n" @@ -350,10 +337,10 @@ UniValue setaccount(const UniValue& params, bool fHelp, const CPubKey& mypk) if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( - "setaccount \"" + strprintf("%s",komodo_chainname()) + "_address\" \"account\"\n" + "setaccount \"" + chainName.ToString() + "_address\" \"account\"\n" "\nDEPRECATED. Sets the account associated with the given address.\n" "\nArguments:\n" - "1. \"" + strprintf("%s",komodo_chainname()) + "_address\" (string, required) The " + strprintf("%s",komodo_chainname()) + " address to be associated with an account.\n" + "1. \"" + chainName.ToString() + "_address\" (string, required) The " + chainName.ToString() + " address to be associated with an account.\n" "2. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "\nExamples:\n" + HelpExampleCli("setaccount", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\" \"tabby\"") @@ -396,10 +383,10 @@ UniValue getaccount(const UniValue& params, bool fHelp, const CPubKey& mypk) if (fHelp || params.size() != 1) throw runtime_error( - "getaccount \"" + strprintf("%s",komodo_chainname()) + "_address\"\n" + "getaccount \"" + chainName.ToString() + "_address\"\n" "\nDEPRECATED. Returns the account associated with the given address.\n" "\nArguments:\n" - "1. \"" + strprintf("%s",komodo_chainname()) + "_address\" (string, required) The " + strprintf("%s",komodo_chainname()) + " address for account lookup.\n" + "1. \"" + chainName.ToString() + "_address\" (string, required) The " + chainName.ToString() + " address for account lookup.\n" "\nResult:\n" "\"accountname\" (string) the account address\n" "\nExamples:\n" @@ -436,7 +423,7 @@ UniValue getaddressesbyaccount(const UniValue& params, bool fHelp, const CPubKey "1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "\nResult:\n" "[ (json array of string)\n" - " \"" + strprintf("%s",komodo_chainname()) + "_address\" (string) a " + strprintf("%s",komodo_chainname()) + " address associated with the given account\n" + " \"" + chainName.ToString() + "_address\" (string) a " + chainName.ToString() + " address associated with the given account\n" " ,...\n" "]\n" "\nExamples:\n" @@ -515,19 +502,19 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( - "sendtoaddress \"" + strprintf("%s",komodo_chainname()) + "_address\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n" + "sendtoaddress \"" + chainName.ToString() + "_address\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n" "\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n" + HelpRequiringPassphrase() + "\nArguments:\n" - "1. \"" + strprintf("%s",komodo_chainname()) + "_address\" (string, required) The " + strprintf("%s",komodo_chainname()) + " address to send to.\n" - "2. \"amount\" (numeric, required) The amount in " + strprintf("%s",komodo_chainname()) + " to send. eg 0.1\n" + "1. \"" + chainName.ToString() + "_address\" (string, required) The " + chainName.ToString() + " address to send to.\n" + "2. \"amount\" (numeric, required) The amount in " + chainName.ToString() + " to send. eg 0.1\n" "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" "4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n" " to which you're sending the transaction. This is not part of the \n" " transaction, just kept in your wallet.\n" "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n" - " The recipient will receive less " + strprintf("%s",komodo_chainname()) + " than you enter in the amount field.\n" + " The recipient will receive less " + chainName.ToString() + " than you enter in the amount field.\n" "\nResult:\n" "\"transactionid\" (string) The transaction id.\n" "\nExamples:\n" @@ -541,7 +528,7 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { if ( komodo_isnotaryvout((char *)params[0].get_str().c_str(),chainActive.Tip()->nTime) == 0 ) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid " + strprintf("%s",komodo_chainname()) + " address"); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid " + chainName.ToString() + " address"); } } LOCK2(cs_main, pwalletMain->cs_wallet); @@ -574,34 +561,39 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) return wtx.GetHash().GetHex(); } -#include "komodo_defs.h" - +/* TODO: remove #define KOMODO_KVPROTECTED 1 #define KOMODO_KVBINARY 2 #define KOMODO_KVDURATION 1440 #define IGUANA_MAXSCRIPTSIZE 10001 -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); +#define CRYPTO777_KMDADDR "RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA" +#include "komodo_defs.h"*/ + +/* +#define IGUANA_MAXSCRIPTSIZE 10001 int32_t komodo_opreturnscript(uint8_t *script,uint8_t type,uint8_t *opret,int32_t opretlen); #define CRYPTO777_KMDADDR "RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA" -extern int32_t KOMODO_PAX; extern uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE; -int32_t komodo_is_issuer(); int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); -int32_t komodo_isrealtime(int32_t *kmdheightp); -int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base); int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); -int32_t komodo_kvcmp(uint8_t *refvalue,uint16_t refvaluesize,uint8_t *value,uint16_t valuesize); uint64_t komodo_kvfee(uint32_t flags,int32_t opretlen,int32_t keylen); uint256 komodo_kvsig(uint8_t *buf,int32_t len,uint256 privkey); int32_t komodo_kvduration(uint32_t flags); uint256 komodo_kvprivkey(uint256 *pubkeyp,char *passphrase); int32_t komodo_kvsigverify(uint8_t *buf,int32_t len,uint256 _pubkey,uint256 sig); +*/ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) { static uint256 zeroes; CWalletTx wtx; UniValue ret(UniValue::VOBJ); - uint8_t keyvalue[IGUANA_MAXSCRIPTSIZE*8],opretbuf[IGUANA_MAXSCRIPTSIZE*8]; int32_t i,coresize,haveprivkey,duration,opretlen,height; uint16_t keylen=0,valuesize=0,refvaluesize=0; uint8_t *key,*value=0; uint32_t flags,tmpflags,n; struct komodo_kv *ptr; uint64_t fee; uint256 privkey,pubkey,refpubkey,sig; + uint8_t keyvalue[IGUANA_MAXSCRIPTSIZE*8],opretbuf[IGUANA_MAXSCRIPTSIZE*8]; + int32_t i,coresize,haveprivkey,duration,opretlen,height; + uint16_t keylen=0,valuesize=0,refvaluesize=0; + uint8_t *key,*value=0; + uint32_t flags,tmpflags,n; + uint64_t fee; + uint256 privkey,pubkey,refpubkey,sig; if (fHelp || params.size() < 3 ) throw runtime_error( "kvupdate key \"value\" days passphrase\n" @@ -630,7 +622,7 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) ); if (!EnsureWalletIsAvailable(fHelp)) return 0; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( chainName.isKMD() ) return(0); haveprivkey = 0; memset(&sig,0,sizeof(sig)); @@ -681,13 +673,10 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) ret.push_back(Pair("error",(char *)"error verifying sig, passphrase is probably wrong")); LogPrintf("VERIFY ERROR\n"); return ret; - } // else LogPrintf("verified immediately\n"); + } } } - //for (i=0; i<32; i++) - // LogPrintf("%02x",((uint8_t *)&sig)[i]); - //LogPrintf(" sig for keylen.%d + valuesize.%d\n",keylen,refvaluesize); - ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL))); + ret.push_back(Pair("coin", chainName.ToString())); height = chainActive.Tip()->nHeight; if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 ) ret.push_back(Pair("owner",refpubkey.GetHex())); @@ -739,87 +728,6 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) return ret; } -UniValue paxdeposit(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint64_t available,deposited,issued,withdrawn,approved,redeemed,seed,komodoshis = 0; int32_t height; char destaddr[64]; uint8_t i,pubkey37[33]; - bool fSubtractFeeFromAmount = false; - if ( KOMODO_PAX == 0 ) - { - throw runtime_error("paxdeposit disabled without -pax"); - } - if ( komodo_is_issuer() != 0 ) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "paxdeposit only from KMD"); - if (!EnsureWalletIsAvailable(fHelp)) - throw runtime_error("paxdeposit needs wallet"); //return Value::null; - if (fHelp || params.size() != 3) - throw runtime_error("paxdeposit address fiatoshis base"); - LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); - if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Komodo address"); - int64_t fiatoshis = atof(params[1].get_str().c_str()) * COIN; - std::string base = params[2].get_str(); - std::string dest; - height = chainActive.Tip()->nHeight; - if ( pax_fiatstatus(&available,&deposited,&issued,&withdrawn,&approved,&redeemed,(char *)base.c_str()) != 0 || available < fiatoshis ) - { - LogPrintf("available %llu vs fiatoshis %llu\n",(long long)available,(long long)fiatoshis); - throw runtime_error("paxdeposit not enough available inventory"); - } - komodoshis = PAX_fiatdest(&seed,0,destaddr,pubkey37,(char *)params[0].get_str().c_str(),height,(char *)base.c_str(),fiatoshis); - dest.append(destaddr); - CBitcoinAddress destaddress(CRYPTO777_KMDADDR); - if (!destaddress.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid dest Komodo address"); - for (i=0; i<33; i++) - LogPrintf("%02x",pubkey37[i]); - LogPrintf(" 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(); - CWalletTx wtx; - 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,'D',pubkey37,37); - SendMoney(address.Get(),fee,fSubtractFeeFromAmount,wtx,opretbuf,opretlen,komodoshis); - return wtx.GetHash().GetHex(); -} - -UniValue paxwithdraw(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - CWalletTx wtx; std::string dest; int32_t kmdheight; 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; - throw runtime_error("paxwithdraw deprecated"); - if (fHelp || params.size() != 2) - throw runtime_error("paxwithdraw address fiatamount"); - if ( komodo_isrealtime(&kmdheight) == 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 Komodo 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 Komodo address"); - for (i=0; i<33; i++) - LogPrintf("%02x",pubkey37[i]); - LogPrintf(" kmdheight.%d srcaddr.(%s) %s fiatoshis.%lld -> dest.(%s) komodoshis.%llu seed.%llx\n",kmdheight,(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 = fiatoshis / 1000; - if ( fee < 10000 ) - fee = 10000; - iguana_rwnum(1,&pubkey37[33],sizeof(kmdheight),&kmdheight); - opretlen = komodo_opreturnscript(opretbuf,'W',pubkey37,37); - SendMoney(destaddress.Get(),fee,fSubtractFeeFromAmount,wtx,opretbuf,opretlen,fiatoshis); - return wtx.GetHash().GetHex(); -} - UniValue listaddressgroupings(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (!EnsureWalletIsAvailable(fHelp)) @@ -835,8 +743,8 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp, const CPubKey& "[\n" " [\n" " [\n" - " \"" + strprintf("%s",komodo_chainname()) + " address\", (string) The " + strprintf("%s",komodo_chainname()) + " address\n" - " amount, (numeric) The amount in " + strprintf("%s",komodo_chainname()) + "\n" + " \"" + chainName.ToString() + " address\", (string) The " + chainName.ToString() + " address\n" + " amount, (numeric) The amount in " + chainName.ToString() + "\n" " \"account\" (string, optional) The account (DEPRECATED)\n" " ]\n" " ,...\n" @@ -937,13 +845,13 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp, const CPubKey& if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( - "getreceivedbyaddress \"" + strprintf("%s",komodo_chainname()) + "_address\" ( minconf )\n" - "\nReturns the total amount received by the given " + strprintf("%s",komodo_chainname()) + " address in transactions with at least minconf confirmations.\n" + "getreceivedbyaddress \"" + chainName.ToString() + "_address\" ( minconf )\n" + "\nReturns the total amount received by the given " + chainName.ToString() + " address in transactions with at least minconf confirmations.\n" "\nArguments:\n" - "1. \"" + strprintf("%s",komodo_chainname()) + "_address\" (string, required) The " + strprintf("%s",komodo_chainname()) + " address for transactions.\n" + "1. \"" + chainName.ToString() + "_address\" (string, required) The " + chainName.ToString() + " address for transactions.\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "\nResult:\n" - "amount (numeric) The total amount in " + strprintf("%s",komodo_chainname()) + " received at this address.\n" + "amount (numeric) The total amount in " + chainName.ToString() + " received at this address.\n" "\nExamples:\n" "\nThe amount from transactions with at least 1 confirmation\n" + HelpExampleCli("getreceivedbyaddress", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"") + @@ -1014,7 +922,7 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp, const CPubKey& "1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "\nResult:\n" - "amount (numeric) The total amount in " + strprintf("%s",komodo_chainname()) + " received for this account.\n" + "amount (numeric) The total amount in " + chainName.ToString() + " received for this account.\n" "\nExamples:\n" "\nAmount received by the default account with at least 1 confirmation\n" + HelpExampleCli("getreceivedbyaccount", "\"\"") + @@ -1113,7 +1021,7 @@ UniValue cleanwallettransactions(const UniValue& params, bool fHelp, const CPubK "1. \"txid\" (string, optional) The transaction id to keep.\n" "\nResult:\n" "{\n" - " \"total_transactions\" : n, (numeric) Transactions in wallet of " + strprintf("%s",komodo_chainname()) + "\n" + " \"total_transactions\" : n, (numeric) Transactions in wallet of " + chainName.ToString() + "\n" " \"remaining_transactions\" : n, (numeric) Transactions in wallet after clean.\n" " \"removed_transactions\" : n, (numeric) The number of transactions removed.\n" "}\n" @@ -1216,7 +1124,7 @@ UniValue getbalance(const UniValue& params, bool fHelp, const CPubKey& mypk) "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n" "\nResult:\n" - "amount (numeric) The total amount in " + strprintf("%s",komodo_chainname()) + " received for this account.\n" + "amount (numeric) The total amount in " + chainName.ToString() + " received for this account.\n" "\nExamples:\n" "\nThe total amount in the wallet\n" + HelpExampleCli("getbalance", "") + @@ -1312,15 +1220,15 @@ UniValue movecmd(const UniValue& params, bool fHelp, const CPubKey& mypk) "\nArguments:\n" "1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "2. \"toaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" - "3. amount (numeric) Quantity of " + strprintf("%s",komodo_chainname()) + " to move between accounts.\n" + "3. amount (numeric) Quantity of " + chainName.ToString() + " to move between accounts.\n" "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n" "\nResult:\n" "true|false (boolean) true if successful.\n" "\nExamples:\n" - "\nMove 0.01 " + strprintf("%s",komodo_chainname()) + " from the default account to the account named tabby\n" + "\nMove 0.01 " + chainName.ToString() + " from the default account to the account named tabby\n" + HelpExampleCli("move", "\"\" \"tabby\" 0.01") + - "\nMove 0.01 " + strprintf("%s",komodo_chainname()) + " timotei to akiko with a comment and funds have 6 confirmations\n" + "\nMove 0.01 " + chainName.ToString() + " timotei to akiko with a comment and funds have 6 confirmations\n" + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") + "\nAs a json rpc call\n" + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"") @@ -1382,14 +1290,14 @@ UniValue sendfrom(const UniValue& params, bool fHelp, const CPubKey& mypk) if (fHelp || params.size() < 3 || params.size() > 6) throw runtime_error( - "sendfrom \"fromaccount\" \"to" + strprintf("%s",komodo_chainname()) + "address\" amount ( minconf \"comment\" \"comment-to\" )\n" - "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a " + strprintf("%s",komodo_chainname()) + " address.\n" + "sendfrom \"fromaccount\" \"to" + chainName.ToString() + "address\" amount ( minconf \"comment\" \"comment-to\" )\n" + "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a " + chainName.ToString() + " address.\n" "The amount is a real and is rounded to the nearest 0.00000001." + HelpRequiringPassphrase() + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" - "2. \"to" + strprintf("%s",komodo_chainname()) + "address\" (string, required) The " + strprintf("%s",komodo_chainname()) + " address to send funds to.\n" - "3. amount (numeric, required) The amount in " + strprintf("%s",komodo_chainname()) + " (transaction fee is added on top).\n" + "2. \"to" + chainName.ToString() + "address\" (string, required) The " + chainName.ToString() + " address to send funds to.\n" + "3. amount (numeric, required) The amount in " + chainName.ToString() + " (transaction fee is added on top).\n" "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" @@ -1399,7 +1307,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp, const CPubKey& mypk) "\nResult:\n" "\"transactionid\" (string) The transaction id.\n" "\nExamples:\n" - "\nSend 0.01 " + strprintf("%s",komodo_chainname()) + " from the default account to the address, must have at least 1 confirmation\n" + "\nSend 0.01 " + chainName.ToString() + " from the default account to the address, must have at least 1 confirmation\n" + HelpExampleCli("sendfrom", "\"\" \"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\" 0.01") + "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n" + HelpExampleCli("sendfrom", "\"tabby\" \"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\" 0.01 6 \"donation\" \"seans outpost\"") + @@ -1457,14 +1365,14 @@ UniValue sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) "1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "2. \"amounts\" (string, required) A json object with addresses and amounts\n" " {\n" - " \"address\":amount (numeric) The " + strprintf("%s",komodo_chainname()) + " address is the key, the numeric amount in " + strprintf("%s",komodo_chainname()) + " is the value\n" + " \"address\":amount (numeric) The " + chainName.ToString() + " address is the key, the numeric amount in " + chainName.ToString() + " is the value\n" " ,...\n" " }\n" "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n" "4. \"comment\" (string, optional) A comment\n" "5. subtractfeefromamount (string, optional) A json array with addresses.\n" " The fee will be equally deducted from the amount of each selected address.\n" - " Those recipients will receive less " + strprintf("%s",komodo_chainname()) + " than you enter in their corresponding amount field.\n" + " Those recipients will receive less " + chainName.ToString() + " than you enter in their corresponding amount field.\n" " If no addresses are specified here, the sender pays the fee.\n" " [\n" " \"address\" (string) Subtract fee from this address\n" @@ -1572,20 +1480,20 @@ UniValue addmultisigaddress(const UniValue& params, bool fHelp, const CPubKey& m { string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n" "\nAdd a nrequired-to-sign multisignature address to the wallet.\n" - "Each key is a " + strprintf("%s",komodo_chainname()) + " address or hex-encoded public key.\n" + "Each key is a " + chainName.ToString() + " address or hex-encoded public key.\n" "If 'account' is specified (DEPRECATED), assign address to that account.\n" "\nArguments:\n" "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n" - "2. \"keysobject\" (string, required) A json array of " + strprintf("%s",komodo_chainname()) + " addresses or hex-encoded public keys\n" + "2. \"keysobject\" (string, required) A json array of " + chainName.ToString() + " addresses or hex-encoded public keys\n" " [\n" - " \"address\" (string) " + strprintf("%s",komodo_chainname()) + " address or hex-encoded public key\n" + " \"address\" (string) " + chainName.ToString() + " address or hex-encoded public key\n" " ...,\n" " ]\n" "3. \"account\" (string, optional) DEPRECATED. If provided, MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "\nResult:\n" - "\"" + strprintf("%s",komodo_chainname()) + "_address\" (string) A " + strprintf("%s",komodo_chainname()) + " address associated with the keys.\n" + "\"" + chainName.ToString() + "_address\" (string) A " + chainName.ToString() + " address associated with the keys.\n" "\nExamples:\n" "\nAdd a multisig address from 2 addresses\n" @@ -1777,7 +1685,7 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp, const CPubKey " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n" " \"address\" : \"receivingaddress\", (string) The receiving address\n" " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n" - " \"amount\" : x.xxx, (numeric) The total amount in " + strprintf("%s",komodo_chainname()) + " received by the address\n" + " \"amount\" : x.xxx, (numeric) The total amount in " + chainName.ToString() + " received by the address\n" " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n" " }\n" " ,...\n" @@ -1959,17 +1867,17 @@ UniValue listtransactions(const UniValue& params, bool fHelp, const CPubKey& myp " {\n" " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n" " It will be \"\" for the default account.\n" - " \"address\":\"" + strprintf("%s",komodo_chainname()) + "_address\", (string) The " + strprintf("%s",komodo_chainname()) + " address of the transaction. Not present for \n" + " \"address\":\"" + chainName.ToString() + "_address\", (string) The " + chainName.ToString() + " address of the transaction. Not present for \n" " move transactions (category = move).\n" " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n" " transaction between accounts, and not associated with an address,\n" " transaction id or block. 'send' and 'receive' transactions are \n" " associated with an address, transaction id and block details\n" - " \"amount\": x.xxx, (numeric) The amount in " + strprintf("%s",komodo_chainname()) + ". This is negative for the 'send' category, and for the\n" + " \"amount\": x.xxx, (numeric) The amount in " + chainName.ToString() + ". This is negative for the 'send' category, and for the\n" " 'move' category for moves outbound. It is positive for the 'receive' category,\n" " and for the 'move' category for inbound funds.\n" " \"vout\" : n, (numeric) the vout value\n" - " \"fee\": x.xxx, (numeric) The amount of the fee in " + strprintf("%s",komodo_chainname()) + ". This is negative and only available for the \n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + chainName.ToString() + ". This is negative and only available for the \n" " 'send' category of transactions.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n" " 'receive' category of transactions.\n" @@ -2163,12 +2071,12 @@ UniValue listsinceblock(const UniValue& params, bool fHelp, const CPubKey& mypk) "{\n" " \"transactions\": [\n" " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n" - " \"address\":\"" + strprintf("%s",komodo_chainname()) + "_address\", (string) The " + strprintf("%s",komodo_chainname()) + " address of the transaction. Not present for move transactions (category = move).\n" + " \"address\":\"" + chainName.ToString() + "_address\", (string) The " + chainName.ToString() + " address of the transaction. Not present for move transactions (category = move).\n" " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n" - " \"amount\": x.xxx, (numeric) The amount in " + strprintf("%s",komodo_chainname()) + ". This is negative for the 'send' category, and for the 'move' category for moves \n" + " \"amount\": x.xxx, (numeric) The amount in " + chainName.ToString() + ". This is negative for the 'send' category, and for the 'move' category for moves \n" " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n" " \"vout\" : n, (numeric) the vout value\n" - " \"fee\": x.xxx, (numeric) The amount of the fee in " + strprintf("%s",komodo_chainname()) + ". This is negative and only available for the 'send' category of transactions.\n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + chainName.ToString() + ". This is negative and only available for the 'send' category of transactions.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n" @@ -2251,7 +2159,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp, const CPubKey& mypk) "2. \"includeWatchonly\" (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n" "\nResult:\n" "{\n" - " \"amount\" : x.xxx, (numeric) The transaction amount in " + strprintf("%s",komodo_chainname()) + "\n" + " \"amount\" : x.xxx, (numeric) The transaction amount in " + chainName.ToString() + "\n" " \"confirmations\" : n, (numeric) The number of confirmations\n" " \"blockhash\" : \"hash\", (string) The block hash\n" " \"blockindex\" : xx, (numeric) The block index\n" @@ -2262,9 +2170,9 @@ UniValue gettransaction(const UniValue& params, bool fHelp, const CPubKey& mypk) " \"details\" : [\n" " {\n" " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n" - " \"address\" : \"" + strprintf("%s",komodo_chainname()) + "_address\", (string) The " + strprintf("%s",komodo_chainname()) + " address involved in the transaction\n" + " \"address\" : \"" + chainName.ToString() + "_address\", (string) The " + chainName.ToString() + " address involved in the transaction\n" " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n" - " \"amount\" : x.xxx (numeric) The amount in " + strprintf("%s",komodo_chainname()) + "\n" + " \"amount\" : x.xxx (numeric) The amount in " + chainName.ToString() + "\n" " \"vout\" : n, (numeric) the vout value\n" " }\n" " ,...\n" @@ -2422,7 +2330,7 @@ UniValue walletpassphrase(const UniValue& params, bool fHelp, const CPubKey& myp throw runtime_error( "walletpassphrase \"passphrase\" timeout\n" "\nStores the wallet decryption key in memory for 'timeout' seconds.\n" - "This is needed prior to performing transactions related to private keys such as sending " + strprintf("%s",komodo_chainname()) + "\n" + "This is needed prior to performing transactions related to private keys such as sending " + chainName.ToString() + "\n" "\nArguments:\n" "1. \"passphrase\" (string, required) The wallet passphrase\n" "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n" @@ -2567,7 +2475,7 @@ UniValue encryptwallet(const UniValue& params, bool fHelp, const CPubKey& mypk) return NullUniValue; string enableArg = "developerencryptwallet"; - int32_t flag = (komodo_acpublic(0) || ASSETCHAINS_SYMBOL[0] == 0); + int32_t flag = (komodo_acpublic(0) || chainName.isKMD() ); auto fEnableWalletEncryption = fExperimentalMode && GetBoolArg("-" + enableArg, flag); std::string strWalletEncryptionDisabledMsg = ""; @@ -2590,10 +2498,10 @@ UniValue encryptwallet(const UniValue& params, bool fHelp, const CPubKey& mypk) "\nExamples:\n" "\nEncrypt you wallet\n" + HelpExampleCli("encryptwallet", "\"my pass phrase\"") + - "\nNow set the passphrase to use the wallet, such as for signing or sending " + strprintf("%s",komodo_chainname()) + "\n" + "\nNow set the passphrase to use the wallet, such as for signing or sending " + chainName.ToString() + "\n" + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") + "\nNow we can so something like sign\n" - + HelpExampleCli("signmessage", "\"" + strprintf("%s",komodo_chainname()) + "_address\" \"test message\"") + + + HelpExampleCli("signmessage", "\"" + chainName.ToString() + "_address\" \"test message\"") + "\nNow lock the wallet again by removing the passphrase\n" + HelpExampleCli("walletlock", "") + "\nAs a json rpc call\n" @@ -2641,7 +2549,7 @@ UniValue lockunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) "lockunspent unlock [{\"txid\":\"txid\",\"vout\":n},...]\n" "\nUpdates list of temporarily unspendable outputs.\n" "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n" - "A locked transaction output will not be chosen by automatic coin selection, when spending " + strprintf("%s",komodo_chainname()) + ".\n" + "A locked transaction output will not be chosen by automatic coin selection, when spending " + chainName.ToString() + ".\n" "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n" "is always cleared (by virtue of process exit) when a node stops or fails.\n" "Also see the listunspent call\n" @@ -2774,7 +2682,7 @@ UniValue settxfee(const UniValue& params, bool fHelp, const CPubKey& mypk) "settxfee amount\n" "\nSet the transaction fee per kB.\n" "\nArguments:\n" - "1. amount (numeric, required) The transaction fee in " + strprintf("%s",komodo_chainname()) + "/kB rounded to the nearest 0.00000001\n" + "1. amount (numeric, required) The transaction fee in " + chainName.ToString() + "/kB rounded to the nearest 0.00000001\n" "\nResult\n" "true|false (boolean) Returns true if successful\n" "\nExamples:\n" @@ -2803,9 +2711,9 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) "\nResult:\n" "{\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + strprintf("%s",komodo_chainname()) + "\n" - " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + strprintf("%s",komodo_chainname()) + "\n" - " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + strprintf("%s",komodo_chainname()) + "\n" + " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + chainName.ToString() + "\n" + " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + chainName.ToString() + "\n" + " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + chainName.ToString() + "\n" " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" @@ -2862,8 +2770,6 @@ UniValue resendwallettransactions(const UniValue& params, bool fHelp, const CPub return result; } -extern uint32_t komodo_segid32(char *coinaddr); - UniValue listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (!EnsureWalletIsAvailable(fHelp)) @@ -2880,9 +2786,9 @@ UniValue listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) "\nArguments:\n" "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n" "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" - "3. \"addresses\" (string) A json array of " + strprintf("%s",komodo_chainname()) + " addresses to filter\n" + "3. \"addresses\" (string) A json array of " + chainName.ToString() + " addresses to filter\n" " [\n" - " \"address\" (string) " + strprintf("%s",komodo_chainname()) + " address\n" + " \"address\" (string) " + chainName.ToString() + " address\n" " ,...\n" " ]\n" "\nResult\n" @@ -3002,12 +2908,18 @@ UniValue listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) return results; } +/**** + * @note also sets globals KOMODO_INTERESTSUM and KOMODO_WALLETBALANCE used for the getinfo RPC call + * @returns amount of accrued interest in this wallet + */ uint64_t komodo_interestsum() { #ifdef ENABLE_WALLET - if ( ASSETCHAINS_SYMBOL[0] == 0 && GetBoolArg("-disablewallet", false) == 0 && KOMODO_NSPV_FULLNODE ) + if ( chainName.isKMD() && GetBoolArg("-disablewallet", false) == 0 && KOMODO_NSPV_FULLNODE ) { - uint64_t interest,sum = 0; int32_t txheight; uint32_t locktime; + uint64_t interest,sum = 0; + int32_t txheight; + uint32_t locktime; vector vecOutputs; assert(pwalletMain != NULL); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -3022,7 +2934,6 @@ uint64_t komodo_interestsum() if ( pindex != 0 && (tipindex= chainActive.Tip()) != 0 ) { interest = komodo_accrued_interest(&txheight,&locktime,out.tx->GetHash(),out.i,0,nValue,(int32_t)tipindex->nHeight); - //interest = komodo_interest(pindex->nHeight,nValue,out.tx->nLockTime,tipindex->nTime); sum += interest; } } @@ -3768,7 +3679,7 @@ UniValue z_getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk "1. \"type\" (string, optional, default=\"" + defaultType + "\") The type of address. One of [\"" + ADDR_TYPE_SPROUT + "\", \"" + ADDR_TYPE_SAPLING + "\"].\n" "\nResult:\n" - "\"" + strprintf("%s",komodo_chainname()) + "_address\" (string) The new shielded address.\n" + "\"" + chainName.ToString() + "_address\" (string) The new shielded address.\n" "\nExamples:\n" + HelpExampleCli("z_getnewaddress", "") + HelpExampleCli("z_getnewaddress", ADDR_TYPE_SAPLING) @@ -4524,8 +4435,6 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) LOCK2(cs_main, pwalletMain->cs_wallet); - //THROW_IF_SYNCING(KOMODO_INSYNC); - // Check that the from address is valid. auto fromaddress = params[0].get_str(); bool fromTaddr = false; @@ -4609,7 +4518,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) if ( fromSprout || toSprout ) throw JSONRPCError(RPC_INVALID_PARAMETER,"Sprout usage has expired"); } - if ( toSapling && ASSETCHAINS_SYMBOL[0] == 0 ) + if ( toSapling && chainName.isKMD() ) throw JSONRPCError(RPC_INVALID_PARAMETER,"Sprout usage will expire soon"); // If we are sending from a shielded address, all recipient @@ -4836,8 +4745,6 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp, const CPubKey& myp LOCK2(cs_main, pwalletMain->cs_wallet); - //THROW_IF_SYNCING(KOMODO_INSYNC); - // Validate the from address auto fromaddress = params[0].get_str(); bool isFromWildcard = fromaddress == "*"; @@ -5098,8 +5005,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp LOCK2(cs_main, pwalletMain->cs_wallet); - //THROW_IF_SYNCING(KOMODO_INSYNC); - bool useAnyUTXO = false; bool useAnySprout = false; bool useAnySapling = false; @@ -5507,7 +5412,6 @@ UniValue z_listoperationids(const UniValue& params, bool fHelp, const CPubKey& m #include "script/sign.h" -extern std::string NOTARY_PUBKEY; /** * @brief Search for 10k sat. P2PK notary utxos and make proof tx (txNew) from it for further include in block. @@ -5598,10 +5502,8 @@ int32_t komodo_notaryvin(CMutableTransaction &txNew, uint8_t *notarypub33, const #include "../cc/CCchannels.h" #include "../cc/CCOracles.h" #include "../cc/CCGateways.h" -#include "../cc/CCPrices.h" #include "../cc/CCHeir.h" #include "../cc/CCPayments.h" -#include "../cc/CCPegs.h" int32_t ensure_CCrequirements(uint8_t evalcode) { @@ -5900,7 +5802,6 @@ UniValue cclib(const UniValue& params, bool fHelp, const CPubKey& mypk) } else // VSTR assumed jsonstr = (char *)params[2].get_str().c_str(); - //fprintf(stderr,"params.(%s %s %s)\n",params[0].get_str().c_str(),params[1].get_str().c_str(),jsonstr); } } cp = CCinit(&C,evalcode); @@ -6037,43 +5938,6 @@ UniValue oraclesaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) return(CCaddress(cp,(char *)"Oracles",pubkey)); } -UniValue pricesaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C,*assetscp,C2; std::vector pubkey; CPubKey pk,planpk,pricespk; char myaddr[64],houseaddr[64],exposureaddr[64]; - cp = CCinit(&C,EVAL_PRICES); - assetscp = CCinit(&C2,EVAL_PRICES); - if ( fHelp || params.size() > 1 ) - throw runtime_error("pricesaddress [pubkey]\n"); - if ( ensure_CCrequirements(cp->evalcode) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - if ( params.size() == 1 ) - pubkey = ParseHex(params[0].get_str().c_str()); - result = CCaddress(cp,(char *)"Prices",pubkey); - if (mypk.IsValid()) pk=mypk; - else pk = pubkey2pk(Mypubkey()); - pricespk = GetUnspendable(cp,0); - GetCCaddress(assetscp,myaddr,pk); - GetCCaddress1of2(assetscp,houseaddr,pricespk,planpk); - GetCCaddress1of2(assetscp,exposureaddr,pricespk,pricespk); - result.push_back(Pair("myaddr",myaddr)); // for holding my asssets - result.push_back(Pair("houseaddr",houseaddr)); // globally accessible house assets - result.push_back(Pair("exposureaddr",exposureaddr)); // tracking of exposure - return(result); -} - -UniValue pegsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; std::vector pubkey; - cp = CCinit(&C,EVAL_PEGS); - if ( fHelp || params.size() > 1 ) - throw runtime_error("pegssaddress [pubkey]\n"); - if ( ensure_CCrequirements(cp->evalcode) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - if ( params.size() == 1 ) - pubkey = ParseHex(params[0].get_str().c_str()); - return(CCaddress(cp,(char *)"Pegs",pubkey)); -} - UniValue paymentsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { struct CCcontract_info *cp,C; std::vector pubkey; @@ -7097,65 +6961,6 @@ UniValue faucetget(const UniValue& params, bool fHelp, const CPubKey& mypk) return(result); } -uint32_t pricesGetParam(UniValue param) { - uint32_t filter = 0; - if (STR_TOLOWER(param.get_str()) == "all") - filter = 0; - else if (STR_TOLOWER(param.get_str()) == "open") - filter = 1; - else if (STR_TOLOWER(param.get_str()) == "closed") - filter = 2; - else - throw runtime_error("incorrect parameter\n"); - return filter; -} - -UniValue priceslist(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if ( fHelp || params.size() != 0 && params.size() != 1) - throw runtime_error("priceslist [all|open|closed]\n"); - if ( ensure_CCrequirements(EVAL_PRICES) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - uint32_t filter = 0; - if (params.size() == 1) - filter = pricesGetParam(params[0]); - - CPubKey emptypk; - - return(PricesList(filter, emptypk)); -} - -UniValue mypriceslist(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (fHelp || params.size() != 0 && params.size() != 1) - throw runtime_error("mypriceslist [all|open|closed]\n"); - if (ensure_CCrequirements(EVAL_PRICES) < 0) - throw runtime_error(CC_REQUIREMENTS_MSG); - - uint32_t filter = 0; - if (params.size() == 1) - filter = pricesGetParam(params[0]); - CPubKey pk; - if (mypk.IsValid()) pk=mypk; - else pk = pubkey2pk(Mypubkey()); - - return(PricesList(filter, pk)); -} - -UniValue pricesinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint256 bettxid; int32_t height; - if ( fHelp || params.size() != 1 && params.size() != 2) - throw runtime_error("pricesinfo bettxid [height]\n"); - if ( ensure_CCrequirements(EVAL_PRICES) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - bettxid = Parseuint256((char *)params[0].get_str().c_str()); - height = 0; - if (params.size() == 2) - height = atoi(params[1].get_str().c_str()); - return(PricesInfo(bettxid, height)); -} - UniValue dicefund(const UniValue& params, bool fHelp, const CPubKey& mypk) { UniValue result(UniValue::VOBJ); int64_t funds,minbet,maxbet,maxodds,timeoutblocks; std::string hex; char *name; @@ -8025,192 +7830,6 @@ UniValue heirlist(const UniValue& params, bool fHelp, const CPubKey& mypk) return (HeirList()); } -UniValue pegscreate(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); int32_t i; std::vector txids; - uint8_t N; uint256 txid; int64_t amount; - - if ( fHelp || params.size()<3) - throw runtime_error("pegscreate amount N bindtxid1 [bindtxid2 ...]\n"); - if ( ensure_CCrequirements(EVAL_PEGS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - Lock2NSPV(mypk); - amount = atof((char *)params[0].get_str().c_str()) * COIN + 0.00000000499999; - N = atoi((char *)params[1].get_str().c_str()); - if ( params.size() < N+1 ) - { - Unlock2NSPV(mypk); - throw runtime_error("not enough parameters for N pegscreate\n"); - } - for (i=0; i 0 ) - { - result.push_back(Pair("result", "success")); - } - Unlock2NSPV(mypk); - return(result); -} - -UniValue pegsfund(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); uint256 pegstxid,tokenid; int64_t amount; - - - if ( fHelp || params.size()!=3) - throw runtime_error("pegsfund pegstxid tokenid amount\n"); - if ( ensure_CCrequirements(EVAL_PEGS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - Lock2NSPV(mypk); - pegstxid = Parseuint256(params[0].get_str().c_str()); - tokenid = Parseuint256(params[1].get_str().c_str()); - amount = atof((char *)params[2].get_str().c_str()) * COIN + 0.00000000499999; - result = PegsFund(mypk,0,pegstxid,tokenid,amount); - if ( result[JSON_HEXTX].getValStr().size() > 0 ) - { - result.push_back(Pair("result", "success")); - } - Unlock2NSPV(mypk); - return(result); -} - -UniValue pegsget(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); uint256 pegstxid,tokenid; int64_t amount; - - if ( fHelp || params.size()!=3) - throw runtime_error("pegsget pegstxid tokenid amount\n"); - if ( ensure_CCrequirements(EVAL_PEGS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - Lock2NSPV(mypk); - pegstxid = Parseuint256(params[0].get_str().c_str()); - tokenid = Parseuint256(params[1].get_str().c_str()); - amount = atof((char *)params[2].get_str().c_str()) * COIN + 0.00000000499999; - result = PegsGet(mypk,0,pegstxid,tokenid,amount); - if ( result[JSON_HEXTX].getValStr().size() > 0 ) - { - result.push_back(Pair("result", "success")); - } - Unlock2NSPV(mypk); - return(result); -} - -UniValue pegsredeem(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); uint256 pegstxid,tokenid; int64_t amount; - - if ( fHelp || params.size()!=2) - throw runtime_error("pegsredeem pegstxid tokenid\n"); - if ( ensure_CCrequirements(EVAL_PEGS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - Lock2NSPV(mypk); - pegstxid = Parseuint256(params[0].get_str().c_str()); - tokenid = Parseuint256(params[1].get_str().c_str()); - result = PegsRedeem(mypk,0,pegstxid,tokenid); - if ( result[JSON_HEXTX].getValStr().size() > 0 ) - { - result.push_back(Pair("result", "success")); - } - Unlock2NSPV(mypk); - return(result); -} - -UniValue pegsliquidate(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); uint256 pegstxid,tokenid,accounttxid; - - if ( fHelp || params.size()!=3) - throw runtime_error("pegsliquidate pegstxid tokenid accounttxid\n"); - if ( ensure_CCrequirements(EVAL_PEGS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - Lock2NSPV(mypk); - pegstxid = Parseuint256(params[0].get_str().c_str()); - tokenid = Parseuint256(params[1].get_str().c_str()); - accounttxid = Parseuint256(params[2].get_str().c_str()); - result = PegsLiquidate(mypk,0,pegstxid,tokenid,accounttxid); - if ( result[JSON_HEXTX].getValStr().size() > 0 ) - { - result.push_back(Pair("result", "success")); - } - Unlock2NSPV(mypk); - return(result); -} - -UniValue pegsexchange(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); uint256 pegstxid,tokenid,accounttxid; int64_t amount; - - if ( fHelp || params.size()!=3) - throw runtime_error("pegsexchange pegstxid tokenid amount\n"); - if ( ensure_CCrequirements(EVAL_PEGS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - Lock2NSPV(mypk); - pegstxid = Parseuint256(params[0].get_str().c_str()); - tokenid = Parseuint256(params[1].get_str().c_str()); - amount = atof((char *)params[2].get_str().c_str()) * COIN + 0.00000000499999; - result = PegsExchange(mypk,0,pegstxid,tokenid,amount); - if ( result[JSON_HEXTX].getValStr().size() > 0 ) - { - result.push_back(Pair("result", "success")); - } - Unlock2NSPV(mypk); - return(result); -} - -UniValue pegsaccounthistory(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint256 pegstxid; - - if ( fHelp || params.size() != 1 ) - throw runtime_error("pegsaccounthistory pegstxid\n"); - if ( ensure_CCrequirements(EVAL_GATEWAYS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - pegstxid = Parseuint256((char *)params[0].get_str().c_str()); - return(PegsAccountHistory(mypk,pegstxid)); -} - -UniValue pegsaccountinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint256 pegstxid; - - if ( fHelp || params.size() != 1 ) - throw runtime_error("pegsaccountinfo pegstxid\n"); - if ( ensure_CCrequirements(EVAL_GATEWAYS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - pegstxid = Parseuint256((char *)params[0].get_str().c_str()); - return(PegsAccountInfo(mypk,pegstxid)); -} - -UniValue pegsworstaccounts(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint256 pegstxid; - - if ( fHelp || params.size() != 1 ) - throw runtime_error("pegsworstaccounts pegstxid\n"); - if ( ensure_CCrequirements(EVAL_GATEWAYS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - pegstxid = Parseuint256((char *)params[0].get_str().c_str()); - return(PegsWorstAccounts(pegstxid)); -} - -UniValue pegsinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint256 pegstxid; - - if ( fHelp || params.size() != 1 ) - throw runtime_error("pegsinfo pegstxid\n"); - if ( ensure_CCrequirements(EVAL_GATEWAYS) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - pegstxid = Parseuint256((char *)params[0].get_str().c_str()); - return(PegsInfo(pegstxid)); -} - extern UniValue dumpprivkey(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdump.cpp extern UniValue convertpassphrase(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue importprivkey(const UniValue& params, bool fHelp, const CPubKey& mypk); diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index 7739e94a..8dc0e404 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -23,5 +23,18 @@ class CRPCTable; void RegisterWalletRPCCommands(CRPCTable &tableRPC); +uint64_t komodo_interestsum(); +int32_t ensure_CCrequirements(uint8_t evalcode); +/** + * @brief Search for 10k sat. P2PK notary utxos and make proof tx (txNew) from it for further include in block. + * opretIn should be empty script before december hardfork, and contains prepared opret script after. + * + * @param txNew - out: signed notary proof tx + * @param notarypub33 - notary node compressed pubkey to search 10k sat. P2PK utxos in the wallet (wallet should be unlocked) + * @param opretIn - after nDecemberHardforkHeight, prepared in advance opret script, before nDecemberHardforkHeight should be empty script + * @param nLockTimeIn - nLockTime that will be set for notary proof tx in-case of after nDecemberHardforkHeight + * @return int32_t - signature length of vin[0] in resulted notary proof tx, actually > 0 if txNew is correct, and 0 in-case of any error + */ +int32_t komodo_notaryvin(CMutableTransaction &txNew, uint8_t *notarypub33, const CScript &opretIn, uint32_t nLockTimeIn); #endif //BITCOIN_WALLET_RPCWALLET_H diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index fe2445ce..320a9d68 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -39,6 +39,11 @@ #include "coins.h" #include "zcash/zip32.h" #include "cc/CCinclude.h" +#include "komodo_utils.h" +#include "komodo_bitcoind.h" +#include "komodo_notary.h" +#include "komodo_interest.h" +#include "komodo_globals.h" #include @@ -66,10 +71,10 @@ const char * DEFAULT_WALLET_DAT = "wallet.dat"; bool fWalletRbf = DEFAULT_WALLET_RBF; -CBlockIndex *komodo_chainactive(int32_t height); -extern std::string DONATION_PUBKEY; -int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); -int tx_height( const uint256 &hash ); +// TODO: remove +//CBlockIndex *komodo_chainactive(int32_t height); +//extern std::string DONATION_PUBKEY; +//int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); /** * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) @@ -786,12 +791,12 @@ set CWallet::GetConflicts(const uint256& txid) const void CWallet::Flush(bool shutdown) { - bitdb.Flush(shutdown); + bitdb->Flush(shutdown); } bool CWallet::Verify(const string& walletFile, string& warningString, string& errorString) { - if (!bitdb.Open(GetDataDir())) + if (!bitdb->Open(GetDataDir())) { // try moving the database env out of the way boost::filesystem::path pathDatabase = GetDataDir() / "database"; @@ -804,7 +809,7 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er } // try again - if (!bitdb.Open(GetDataDir())) { + if (!bitdb->Open(GetDataDir())) { // if it still fails, it probably means we can't even create the database env string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir()); errorString += msg; @@ -815,13 +820,13 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er if (GetBoolArg("-salvagewallet", false)) { // Recover readable keypairs: - if (!CWalletDB::Recover(bitdb, walletFile, true)) + if (!CWalletDB::Recover(*bitdb, walletFile, true)) return false; } if (boost::filesystem::exists(GetDataDir() / walletFile)) { - CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover); + CDBEnv::VerifyResult r = bitdb->Verify(walletFile, CWalletDB::Recover); if (r == CDBEnv::RECOVER_OK) { warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!" @@ -1153,9 +1158,7 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex, template bool DecrementNoteWitnesses(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize) { - extern int32_t KOMODO_REWIND; - - for (auto& item : noteDataMap) { + for (auto& item : noteDataMap) { auto* nd = &(item.second); // Only decrement witnesses that are not above the current height if (nd->witnessHeight <= indexHeight) { @@ -3308,8 +3311,6 @@ CAmount CWallet::GetAvailableBalance(const CCoinControl* coinControl) const /** * populate vCoins with vector of available COutputs. */ -uint64_t komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue, bool fIncludeCoinBase) const { @@ -3349,7 +3350,7 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const if ( !IS_MODE_EXCHANGEWALLET ) { uint32_t locktime; int32_t txheight; CBlockIndex *tipindex; - if ( ASSETCHAINS_SYMBOL[0] == 0 && chainActive.Tip() != 0 && chainActive.Tip()->nHeight >= 60000 ) + if ( chainName.isKMD() && chainActive.Tip() != 0 && chainActive.Tip()->nHeight >= 60000 ) { if ( pcoin->vout[i].nValue >= 10*COIN ) { @@ -3357,7 +3358,9 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const { komodo_accrued_interest(&txheight,&locktime,wtxid,i,0,pcoin->vout[i].nValue,(int32_t)tipindex->nHeight); interest = komodo_interestnew(txheight,pcoin->vout[i].nValue,locktime,tipindex->nTime); - } else interest = 0; + } + else + interest = 0; if ( interest != 0 ) { ptr = (uint64_t *)&pcoin->vout[i].interest; @@ -3699,6 +3702,14 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set vecSend; @@ -3743,6 +3754,17 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC return true; } +/***** + * @brief create a transaction + * @param vecSend who to send to + * @param wtxNew wallet transaction + * @param reservekey + * @param nFeeRet + * @param nChangePosRet + * @param strFailReason + * @param coinControl + * @param sign true to sign inputs + */ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign) { @@ -3770,7 +3792,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt int nextBlockHeight = chainActive.Height() + 1; CMutableTransaction txNew = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextBlockHeight); - if (IS_MODE_EXCHANGEWALLET && ASSETCHAINS_SYMBOL[0] == 0) + if (IS_MODE_EXCHANGEWALLET && chainName.isKMD()) txNew.nLockTime = 0; else { @@ -3891,7 +3913,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt //a chance at a free transaction. //But mempool inputs might still be in the mempool, so their age stays 0 //LogPrintf("nCredit %.8f interest %.8f\n",(double)nCredit/COIN,(double)pcoin.first->vout[pcoin.second].interest/COIN); - if ( !IS_MODE_EXCHANGEWALLET && ASSETCHAINS_SYMBOL[0] == 0 ) + if ( !IS_MODE_EXCHANGEWALLET && chainName.isKMD() ) { interest2 += pcoin.first->vout[pcoin.second].interest; //LogPrintf("%.8f ",(double)pcoin.first->vout[pcoin.second].interest/COIN); @@ -3901,7 +3923,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt age += 1; dPriority += (double)nCredit * age; } - if ( ASSETCHAINS_SYMBOL[0] == 0 && DONATION_PUBKEY.size() == 66 && interest2 > 5000 ) + if ( chainName.isKMD() && DONATION_PUBKEY.size() == 66 && interest2 > 5000 ) { CScript scriptDonation = CScript() << ParseHex(DONATION_PUBKEY) << OP_CHECKSIG; CTxOut newTxOut(interest2,scriptDonation); @@ -3938,7 +3960,6 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt // Reserve a new key pair from key pool CPubKey vchPubKey; - extern int32_t USE_EXTERNAL_PUBKEY; extern std::string NOTARY_PUBKEY; if ( USE_EXTERNAL_PUBKEY == 0 ) { bool ret; @@ -4003,7 +4024,6 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); { - LOCK(cs_main); if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { limit = 0; } @@ -4180,28 +4200,12 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge } */ -//void komodo_prefetch(FILE *fp); - DBErrors CWallet::LoadWallet(bool& fFirstRunRet) { if (!fFileBacked) return DB_LOAD_OK; fFirstRunRet = false; - /* - if ( 0 ) // doesnt help - { - LogPrintf("loading wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL)); - FILE *fp; - if ( (fp= fopen(strWalletFile.c_str(),"rb")) != 0 ) - { - komodo_prefetch(fp); - fclose(fp); - } - } - */ - //LogPrintf("prefetched wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL)); DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this); - //LogPrintf("loaded wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL)); if (nLoadWalletRet == DB_NEED_REWRITE) { if (CDB::Rewrite(strWalletFile, "\x04pool")) @@ -5030,15 +5034,13 @@ int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const int CMerkleTx::GetBlocksToMaturity() const { - if ( ASSETCHAINS_SYMBOL[0] == 0 ) - COINBASE_MATURITY = _COINBASE_MATURITY; if (!IsCoinBase()) return 0; int32_t depth = GetDepthInMainChain(); int32_t ut = UnlockTime(0); int32_t toMaturity = (ut - chainActive.Height()) < 0 ? 0 : ut - chainActive.Height(); //LogPrintf("depth.%i, unlockTime.%i, toMaturity.%i\n", depth, ut, toMaturity); - ut = (COINBASE_MATURITY - depth) < 0 ? 0 : COINBASE_MATURITY - depth; + ut = (Params().CoinbaseMaturity() - depth) < 0 ? 0 : Params().CoinbaseMaturity() - depth; return(ut < toMaturity ? toMaturity : ut); } diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 03c6c150..d2acb65c 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -31,6 +31,7 @@ #include "wallet/wallet.h" #include "zcash/Proof.hpp" #include "komodo_defs.h" +#include "komodo_bitcoind.h" #include #include @@ -41,7 +42,6 @@ using namespace std; static uint64_t nAccountingEntryNumber = 0; static list deadTxns; -extern CBlockIndex *komodo_blockindex(uint256 hash); // // CWalletDB @@ -1166,13 +1166,13 @@ void ThreadFlushWalletDB(const string& strFile) if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2) { - TRY_LOCK(bitdb.cs_db,lockDb); + TRY_LOCK(bitdb->cs_db,lockDb); if (lockDb) { // Don't do this if any databases are in use int nRefCount = 0; - map::iterator mi = bitdb.mapFileUseCount.begin(); - while (mi != bitdb.mapFileUseCount.end()) + map::iterator mi = bitdb->mapFileUseCount.begin(); + while (mi != bitdb->mapFileUseCount.end()) { nRefCount += (*mi).second; mi++; @@ -1181,18 +1181,18 @@ void ThreadFlushWalletDB(const string& strFile) if (nRefCount == 0) { boost::this_thread::interruption_point(); - map::iterator mi = bitdb.mapFileUseCount.find(strFile); - if (mi != bitdb.mapFileUseCount.end()) + map::iterator mi = bitdb->mapFileUseCount.find(strFile); + if (mi != bitdb->mapFileUseCount.end()) { LogPrint("db", "Flushing wallet.dat\n"); nLastFlushed = nWalletDBUpdated; int64_t nStart = GetTimeMillis(); // Flush wallet.dat so it's self contained - bitdb.CloseDb(strFile); - bitdb.CheckpointLSN(strFile); + bitdb->CloseDb(strFile); + bitdb->CheckpointLSN(strFile); - bitdb.mapFileUseCount.erase(mi++); + bitdb->mapFileUseCount.erase(mi++); LogPrint("db", "Flushed wallet.dat %dms\n", GetTimeMillis() - nStart); } } @@ -1208,13 +1208,13 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) while (true) { { - LOCK(bitdb.cs_db); - if (!bitdb.mapFileUseCount.count(wallet.strWalletFile) || bitdb.mapFileUseCount[wallet.strWalletFile] == 0) + LOCK(bitdb->cs_db); + if (!bitdb->mapFileUseCount.count(wallet.strWalletFile) || bitdb->mapFileUseCount[wallet.strWalletFile] == 0) { // Flush log data to the dat file - bitdb.CloseDb(wallet.strWalletFile); - bitdb.CheckpointLSN(wallet.strWalletFile); - bitdb.mapFileUseCount.erase(wallet.strWalletFile); + bitdb->CloseDb(wallet.strWalletFile); + bitdb->CheckpointLSN(wallet.strWalletFile); + bitdb->mapFileUseCount.erase(wallet.strWalletFile); // Copy wallet.dat boost::filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile; diff --git a/src/zcash/CreateJoinSplit.cpp b/src/zcash/CreateJoinSplit.cpp index 06b76bb9..9a4e4568 100644 --- a/src/zcash/CreateJoinSplit.cpp +++ b/src/zcash/CreateJoinSplit.cpp @@ -8,7 +8,6 @@ #include "libsnark/common/profiling.hpp" #include "komodo_defs.h" -char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; uint16_t BITCOIND_RPCPORT = 7771; uint32_t ASSETCHAINS_CC = 0; diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 238ec4b7..5ffe35a9 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -53,7 +53,7 @@ void pre_wallet_load() UnregisterValidationInterface(pwalletMain); delete pwalletMain; pwalletMain = NULL; - bitdb.Reset(); + bitdb->Reset(); RegisterNodeSignals(GetNodeSignals()); LogPrintf("%s: done\n", __func__); } From 8a5c4deebdd4291efb3a2553b7a5e65e525deed6 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 9 Sep 2022 02:51:46 +0200 Subject: [PATCH 08/27] remove REQUIRES(cs_main) thread safety attribute from CChain methods https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#requires-requires-shared --- src/chain.h | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/chain.h b/src/chain.h index ff0136b3..43993445 100644 --- a/src/chain.h +++ b/src/chain.h @@ -490,46 +490,45 @@ class CDiskBlockIndex : public CBlockIndex class CChain { protected: std::vector vChain; - CBlockIndex *at(int nHeight) const REQUIRES(cs_main) - { + CBlockIndex *at(int nHeight) const { if (nHeight < 0 || nHeight >= (int)vChain.size()) return NULL; return vChain[nHeight]; } public: /** Returns the index entry for the genesis block of this chain, or NULL if none. */ - CBlockIndex *Genesis() const REQUIRES(cs_main) { + CBlockIndex *Genesis() const { AssertLockHeld(cs_main); return vChain.size() > 0 ? vChain[0] : NULL; } /** Returns the index entry for the tip of this chain, or NULL if none. */ - CBlockIndex *Tip() const REQUIRES(cs_main) { + CBlockIndex *Tip() const { AssertLockHeld(cs_main); return vChain.size() > 0 ? vChain[vChain.size() - 1] : nullptr; } /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */ - CBlockIndex *operator[](int nHeight) const REQUIRES(cs_main) { + CBlockIndex *operator[](int nHeight) const { AssertLockHeld(cs_main); return at(nHeight); } /** Compare two chains efficiently. */ - friend bool operator==(const CChain &a, const CChain &b) REQUIRES(cs_main) { + friend bool operator==(const CChain &a, const CChain &b) { AssertLockHeld(cs_main); return a.Height() == b.Height() && a.Tip() == b.Tip(); } /** Efficiently check whether a block is present in this chain. */ - bool Contains(const CBlockIndex *pindex) const REQUIRES(cs_main) { + bool Contains(const CBlockIndex *pindex) const { AssertLockHeld(cs_main); return (*this)[pindex->nHeight] == pindex; } /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */ - CBlockIndex *Next(const CBlockIndex *pindex) const REQUIRES(cs_main) { + CBlockIndex *Next(const CBlockIndex *pindex) const { AssertLockHeld(cs_main); if (Contains(pindex)) return (*this)[pindex->nHeight + 1]; @@ -538,19 +537,19 @@ class CChain { } /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */ - int Height() const REQUIRES(cs_main) { + int Height() const { AssertLockHeld(cs_main); return vChain.size() - 1; } /** Set/initialize a chain with a given tip. */ - void SetTip(CBlockIndex *pindex) REQUIRES(cs_main); + void SetTip(CBlockIndex *pindex); /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */ - CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const REQUIRES(cs_main); + CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const; /** Find the last common block between this chain and a block index entry. */ - const CBlockIndex *FindFork(const CBlockIndex *pindex) const REQUIRES(cs_main); + const CBlockIndex *FindFork(const CBlockIndex *pindex) const; }; #endif // BITCOIN_CHAIN_H From 58fd905d963d07a163e9149dcfa2799d6eee30e9 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 9 Sep 2022 04:23:49 +0200 Subject: [PATCH 09/27] fix build, correct syntax and other errors after applying #559 changes --- src/Makefile.am | 6 +----- src/bitcoind.cpp | 3 +-- src/init.cpp | 6 +++--- src/komodo.cpp | 16 ++++++++-------- src/komodo_extern_globals.h | 4 ++-- src/komodo_gateway.cpp | 2 +- src/komodo_utils.cpp | 4 ++-- src/main.cpp | 18 ++++++++++-------- src/miner.cpp | 4 ++-- src/qt/komodo.cpp | 17 +++++++---------- src/qt/komodooceangui.cpp | 2 +- src/qt/optionsmodel.cpp | 2 +- src/txmempool.cpp | 2 +- src/util.cpp | 3 +++ 14 files changed, 43 insertions(+), 46 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 85bf26a3..719fafa9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -293,8 +293,6 @@ libbitcoin_server_a_SOURCES = \ cc/fsm.cpp \ cc/heir.cpp \ cc/oracles.cpp \ - cc/prices.cpp \ - cc/pegs.cpp \ cc/payments.cpp \ cc/gateways.cpp \ cc/channels.cpp \ @@ -304,7 +302,6 @@ libbitcoin_server_a_SOURCES = \ checkpoints.cpp \ fs.cpp \ crosschain.cpp \ - crosschain_authority.cpp \ deprecation.cpp \ httprpc.cpp \ httpserver.cpp \ @@ -465,11 +462,10 @@ libbitcoin_common_a_SOURCES = \ komodo_events.cpp \ komodo_gateway.cpp \ komodo_globals.cpp \ + komodo_hardfork.cpp \ komodo_interest.cpp \ - komodo_jumblr.cpp \ komodo_kv.cpp \ komodo_notary.cpp \ - komodo_pax.cpp \ komodo_utils.cpp \ netbase.cpp \ metrics.cpp \ diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 15a10853..d26beafb 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -63,6 +63,7 @@ static bool fDaemon; +int32_t komodo_longestchain(); void WaitForShutdown(boost::thread_group* threadGroup) { int32_t i,height; CBlockIndex *pindex; bool fShutdown = ShutdownRequested(); const uint256 zeroid; @@ -73,8 +74,6 @@ void WaitForShutdown(boost::thread_group* threadGroup) StartShutdown(); } - if ( ASSETCHAINS_CBOPRET != 0 ) - komodo_pricesinit(); while (!fShutdown) { /* TODO: move to ThreadUpdateKomodoInternals */ diff --git a/src/init.cpp b/src/init.cpp index 605e2bee..5537693b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -232,7 +232,7 @@ void Shutdown() /// Be sure that anything that writes files or flushes caches only does this if the respective /// module was initialized. static char shutoffstr[128]; - sprintf(shutoffstr,"%s-shutoff",ASSETCHAINS_SYMBOL); + sprintf(shutoffstr,"%s-shutoff",chainName.symbol().c_str()); RenameThread(shutoffstr); mempool.AddTransactionsUpdated(1); @@ -1663,7 +1663,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (fRequestShutdown) break; - if (!LoadBlockIndex()) { + if (!LoadBlockIndex(fReindex)) { strLoadError = _("Error loading block database"); break; } @@ -1706,7 +1706,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (!fReindex) { uiInterface.InitMessage(_("Rewinding blocks if needed...")); - if (!RewindBlockIndex(chainparams, clearWitnessCaches)) { + if (!RewindBlockIndex(chainparams)) { strLoadError = _("Unable to rewind the database to a pre-upgrade state. You will need to redownload the blockchain"); break; } diff --git a/src/komodo.cpp b/src/komodo.cpp index 47199b99..bfbd16b4 100644 --- a/src/komodo.cpp +++ b/src/komodo.cpp @@ -336,7 +336,7 @@ int32_t komodo_validate_chain(uint256 srchash,int32_t notarized_height) { if ( last_rewind != 0 ) { - LogPrintf(%s FORK detected. notarized.%d %s not in this chain! last notarization %d -> rewindtarget.%d\n", + LogPrintf("%s FORK detected. notarized.%d %s not in this chain! last notarization %d -> rewindtarget.%d\n", chainName.symbol().c_str(),notarized_height,srchash.ToString().c_str(), sp->LastNotarizedHeight(),rewindtarget); } @@ -359,13 +359,13 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar { if ( i == 0 && j == 0 && memcmp(NOTARY_PUBKEY33,scriptbuf+1,33) == 0 && IS_KOMODO_NOTARY ) { - LogPrintf(%s KOMODO_LASTMINED.%d -> %d\n",chainName.symbol().c_str(),KOMODO_LASTMINED,height); + LogPrintf("%s KOMODO_LASTMINED.%d -> %d\n",chainName.symbol().c_str(),KOMODO_LASTMINED,height); prevKOMODO_LASTMINED = KOMODO_LASTMINED; KOMODO_LASTMINED = height; } decode_hex(crypto777,33,CRYPTO777_PUBSECPSTR); /*for (k=0; k<33; k++) - LogPrintf(%02x",crypto777[k]); + LogPrintf("%02x",crypto777[k]); LogPrintf(" crypto777 "); for (k=0; k 0 ) { for (k=0; k 2 ) { diff --git a/src/komodo_extern_globals.h b/src/komodo_extern_globals.h index 774340a5..13795a8d 100644 --- a/src/komodo_extern_globals.h +++ b/src/komodo_extern_globals.h @@ -76,8 +76,8 @@ extern uint64_t ASSETCHAINS_PEGSCCPARAMS[3]; extern uint64_t ASSETCHAINS_TIMEUNLOCKFROM; extern uint64_t ASSETCHAINS_TIMEUNLOCKTO; -//extern std::mutex komodo_mutex; -extern pthread_mutex_t komodo_mutex; +extern std::mutex komodo_mutex; +//extern pthread_mutex_t komodo_mutex; extern pthread_mutex_t KOMODO_CC_mutex; /** diff --git a/src/komodo_gateway.cpp b/src/komodo_gateway.cpp index 8cf7ebb9..3310c63f 100644 --- a/src/komodo_gateway.cpp +++ b/src/komodo_gateway.cpp @@ -253,7 +253,7 @@ void komodo_stateind_set(struct komodo_state *sp,uint32_t *inds,int32_t n,uint8_ offset = (tmp >> 8); fpos = prevpos100 + offset; if ( lastfpos >= datalen || (filedata[lastfpos] != func && func != 0) ) - LogPrintf(i.%d/n.%d lastfpos.%ld >= datalen.%ld or [%d] != func.%d\n",i,n,lastfpos,datalen,filedata[lastfpos],func); + LogPrintf("i.%d/n.%d lastfpos.%ld >= datalen.%ld or [%d] != func.%d\n",i,n,lastfpos,datalen,filedata[lastfpos],func); else if ( iter == 0 ) { switch ( func ) diff --git a/src/komodo_utils.cpp b/src/komodo_utils.cpp index bb28b222..456fedd2 100644 --- a/src/komodo_utils.cpp +++ b/src/komodo_utils.cpp @@ -1239,8 +1239,8 @@ uint32_t komodo_assetmagic(const char *symbol,uint64_t supply,uint8_t *extraptr, vcalc_sha256(0,hash.bytes,extraptr,extralen); crc0 = hash.uints[0]; for (int32_t i=0; inHeight+1, chainActive.Tip()->GetMedianTimePast() + 777,0) < 0 ) + && komodo_validate_interest(tx,chainActive.Tip()->nHeight+1, chainActive.Tip()->GetMedianTimePast() + 777) < 0 ) { return error("%s: komodo_validate_interest failed txid.%s", __func__, tx.GetHash().ToString()); } @@ -1856,7 +1857,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (pool.mapNextTx.count(outpoint)) { // Disable replacement feature for now - return state.Invalid(false, REJECT_CONFLICT, "txn-mempool-conflict"); + return state.Invalid(false, REJECT_INVALID, "txn-mempool-conflict"); } } BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { @@ -2795,7 +2796,7 @@ namespace Consensus { // Ensure that coinbases are matured, no DoS as retry may work later if (nSpendHeight - coins->nHeight < ::Params().CoinbaseMaturity()) { return state.Invalid( - error("CheckInputs(): tried to spend coinbase at depth %d/%d", nSpendHeight - coins->nHeight, (int32_t)COINBASE_MATURITY), + error("CheckInputs(): tried to spend coinbase at depth %d/%d", nSpendHeight - coins->nHeight, (int32_t)::Params().CoinbaseMaturity()), REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); } @@ -6422,7 +6423,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth * @param params the chain parameters * @returns true on success */ -bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches) +bool RewindBlockIndex(const CChainParams& params) { LOCK(cs_main); @@ -6603,19 +6604,20 @@ void UnloadBlockIndex() * Load block index * @returns true on success */ -bool LoadBlockIndex() +bool LoadBlockIndex(bool reindex) { // Load block index from databases - KOMODO_LOADINGBLOCKS = 1; - if (!fReindex && !LoadBlockIndexDB()) + KOMODO_LOADINGBLOCKS = true; + if (!reindex && !LoadBlockIndexDB()) { - KOMODO_LOADINGBLOCKS = 0; + KOMODO_LOADINGBLOCKS = false; return false; } LogPrintf("finished loading blocks %s\n",chainName.symbol().c_str()); return true; } + /** * Initialize a new block tree database + block data on disk * @returns true on success diff --git a/src/miner.cpp b/src/miner.cpp index b9ef946d..07f01ca4 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -64,7 +64,7 @@ #include "sodium.h" #include "notaries_staked.h" -//#include "komodo_notary.h" +#include "komodo_notary.h" #include "komodo_bitcoind.h" #include "komodo_extern_globals.h" @@ -333,7 +333,7 @@ CBlockTemplate* CreateNewBlock(const CPubKey _pk,const CScript& _scriptPubKeyIn, LogPrint("hfnet","%s[%d]: ht.%ld\n", __func__, __LINE__, nHeight); } - if (chainName.isKMD() && komodo_validate_interest(tx, nHeight, cmptime, 0) < 0) + if (chainName.isKMD() && komodo_validate_interest(tx, nHeight, cmptime) < 0) { LogPrintf("%s: komodo_validate_interest failure txid.%s nHeight.%d nTime.%u vs locktime.%u (cmptime.%lu)\n", __func__, tx.GetHash().ToString(), nHeight, (uint32_t)pblock->nTime, (uint32_t)tx.nLockTime, cmptime); continue; diff --git a/src/qt/komodo.cpp b/src/qt/komodo.cpp index 6561e4da..4d1b02d2 100644 --- a/src/qt/komodo.cpp +++ b/src/qt/komodo.cpp @@ -7,13 +7,13 @@ #endif #include "komodooceangui.h" -#include "komodo_defs.h" -#define KOMODO_ASSETCHAIN_MAXLEN 65 -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; -extern uint32_t ASSETCHAIN_INIT; -extern std::string NOTARY_PUBKEY; -CBlockIndex *komodo_chainactive(int32_t height); +#include "komodo.h" +#include "komodo_bitcoind.h" +#include "komodo_defs.h" +#include "komodo_gateway.h" +#include "komodo_globals.h" +#include "rpc/net.h" //#include "chainparams.h" #include "clientmodel.h" @@ -348,9 +348,6 @@ void KomodoCore::shutdown() StartShutdown(); } - if ( ASSETCHAINS_CBOPRET != 0 ) - komodo_pricesinit(); - while (!fShutdown) { /* TODO: move to ThreadUpdateKomodoInternals */ @@ -715,7 +712,7 @@ int main(int argc, char *argv[]) chainparams_commandline(); LogPrintf("call komodo_args.(%s) NOTARY_PUBKEY.(%s)\n",argv[0],NOTARY_PUBKEY.c_str()); - LogPrintf("initialized %s\n",ASSETCHAINS_SYMBOL); + LogPrintf("initialized %s\n",chainName.symbol().c_str()); /// 5. Now that settings and translations are available, ask user for data directory diff --git a/src/qt/komodooceangui.cpp b/src/qt/komodooceangui.cpp index 0dd17809..c28d7d2a 100644 --- a/src/qt/komodooceangui.cpp +++ b/src/qt/komodooceangui.cpp @@ -132,7 +132,7 @@ KomodoOceanGUI::KomodoOceanGUI(const PlatformStyle *_platformStyle, const Networ move(QApplication::desktop()->availableGeometry().center() - frameGeometry().center()); } - QString windowTitle = "[" + QString(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL) + "] "; + QString windowTitle = "[" + QString(chainName.ToString().c_str()) + "] "; windowTitle += tr(PACKAGE_NAME) + " - "; #ifdef ENABLE_WALLET enableWallet = WalletModel::isWalletEnabled(); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 3f3545ec..963eaae7 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -77,7 +77,7 @@ void OptionsModel::Init(bool resetSettings) nDisplayUnit = settings.value("nDisplayUnit").toInt(); std::string defaultStrThirdPartyTxUrls = "https://kmdexplorer.io/tx/%s|https://kmd.explorer.dexstats.info/tx/%s"; - std::string strAssetchainName = std::string(ASSETCHAINS_SYMBOL); + std::string strAssetchainName = std::string(chainName.symbol().c_str()); std::transform(strAssetchainName.begin(), strAssetchainName.end(), strAssetchainName.begin(), [](unsigned char c){ return std::tolower(c); }); if (!strAssetchainName.empty()) { diff --git a/src/txmempool.cpp b/src/txmempool.cpp index e5c1e900..82a53388 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -516,7 +516,7 @@ void CTxMemPool::removeExpired(unsigned int nBlockHeight) bool fInterestNotValidated = chainName.isKMD() && tipindex != 0 - && komodo_validate_interest(tx,tipindex->nHeight+1,tipindex->GetMedianTimePast() + 777,0) < 0; + && komodo_validate_interest(tx,tipindex->nHeight+1,tipindex->GetMedianTimePast() + 777) < 0; if (IsExpiredTx(tx, nBlockHeight) || fInterestNotValidated) { if (fInterestNotValidated && tipindex != 0) diff --git a/src/util.cpp b/src/util.cpp index 1669b28e..5733b863 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -536,6 +536,9 @@ void PrintExceptionContinue(const std::exception* pex, const char* pszThread) strMiscWarning = message; } + +namespace fs = boost::filesystem; + /** * @brief get the OS-specific default application data directory * @note Windows: be "C:\Users\[username]\AppData\Roaming" From 04e44f23f712e094e840da0bad4786e871460898 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 9 Sep 2022 04:41:57 +0200 Subject: [PATCH 10/27] komodo_gateway.cpp: move log into debug.log, instead of console --- src/komodo_gateway.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/komodo_gateway.cpp b/src/komodo_gateway.cpp index 3310c63f..a8b16ecf 100644 --- a/src/komodo_gateway.cpp +++ b/src/komodo_gateway.cpp @@ -334,7 +334,7 @@ void *OS_loadfile(const char *fname,uint8_t **bufp,long *lenp,long *allocsizep) { fclose(fp); *lenp = 0; - printf("OS_loadfile null size.(%s)\n",fname); + LogPrintf("OS_loadfile null size.(%s)\n",fname); return(0); } if ( filesize > buflen ) @@ -344,17 +344,17 @@ void *OS_loadfile(const char *fname,uint8_t **bufp,long *lenp,long *allocsizep) } rewind(fp); if ( buf == 0 ) - printf("Null buf ???\n"); + LogPrintf("Null buf ???\n"); else { if ( fread(buf,1,(long)filesize,fp) != (unsigned long)filesize ) - printf("error reading filesize.%ld\n",(long)filesize); + LogPrintf("error reading filesize.%ld\n",(long)filesize); buf[filesize] = 0; } fclose(fp); *lenp = filesize; - //printf("loaded.(%s)\n",buf); - } //else printf("OS_loadfile couldnt load.(%s)\n",fname); + //LogPrintf("loaded.(%s)\n",buf); + } //else LogPrintf("OS_loadfile couldnt load.(%s)\n",fname); return(buf); } @@ -388,7 +388,7 @@ long komodo_stateind_validate(struct komodo_state *sp,const std::string& indfnam if ( (inds= OS_fileptr(&fsize,indfname.c_str())) != 0 ) { long lastfpos = 0; - fprintf(stderr,"inds.%p validate %s fsize.%ld datalen.%ld n.%d lastfpos.%ld\n",inds,indfname.c_str(),fsize,datalen,(int32_t)(fsize / sizeof(uint32_t)),lastfpos); + LogPrintf("inds.%p validate %s fsize.%ld datalen.%ld n.%d lastfpos.%ld\n",inds,indfname.c_str(),fsize,datalen,(int32_t)(fsize / sizeof(uint32_t)),lastfpos); if ( (fsize % sizeof(uint32_t)) == 0 ) { int32_t n = (int32_t)(fsize / sizeof(uint32_t)); @@ -407,7 +407,7 @@ long komodo_stateind_validate(struct komodo_state *sp,const std::string& indfnam fpos = prevpos100 + offset; if ( lastfpos >= datalen || filedata[lastfpos] != func ) { - printf("validate.%d error (%u %d) prev100 %u -> fpos.%ld datalen.%ld [%d] (%c) vs (%c) lastfpos.%ld\n",i,offset,func,prevpos100,fpos,datalen,lastfpos < datalen ? filedata[lastfpos] : -1,func,filedata[lastfpos],lastfpos); + LogPrintf("validate.%d error (%u %d) prev100 %u -> fpos.%ld datalen.%ld [%d] (%c) vs (%c) lastfpos.%ld\n",i,offset,func,prevpos100,fpos,datalen,lastfpos < datalen ? filedata[lastfpos] : -1,func,filedata[lastfpos],lastfpos); return -1; } } @@ -421,10 +421,10 @@ long komodo_stateind_validate(struct komodo_state *sp,const std::string& indfnam return fpos; } else - printf("wrong filesize %s %ld\n",indfname.c_str(),fsize); + LogPrintf("wrong filesize %s %ld\n",indfname.c_str(),fsize); } free(inds); - fprintf(stderr,"indvalidate return -1\n"); + LogPrintf("indvalidate return -1\n"); return -1; } @@ -434,7 +434,7 @@ long komodo_indfile_update(FILE *indfp,uint32_t *prevpos100p,long lastfpos,long { uint32_t tmp = ((uint32_t)(newfpos - *prevpos100p) << 8) | (func & 0xff); if ( ftell(indfp)/sizeof(uint32_t) != *indcounterp ) - printf("indfp fpos %ld -> ind.%ld vs counter.%u\n",ftell(indfp),ftell(indfp)/sizeof(uint32_t),*indcounterp); + LogPrintf("indfp fpos %ld -> ind.%ld vs counter.%u\n",ftell(indfp),ftell(indfp)/sizeof(uint32_t),*indcounterp); fwrite(&tmp,1,sizeof(tmp),indfp), (*indcounterp)++; if ( (*indcounterp % 100) == 0 ) { @@ -472,7 +472,7 @@ bool komodo_faststateinit(komodo_state *sp,const char *fname,char *symbol,char * if ( indfp != nullptr ) fwrite(&prevpos100,1,sizeof(prevpos100),indfp), indcounter++; - fprintf(stderr,"processing %s %ldKB, validated.%d\n",fname,datalen/1024,-1); + LogPrintf("processing %s %ldKB, validated.%d\n",fname,datalen/1024,-1); int32_t func; while (!ShutdownRequested() && (func= komodo_parsestatefiledata(sp,filedata,&fpos,datalen,symbol,dest)) >= 0) { @@ -483,11 +483,11 @@ bool komodo_faststateinit(komodo_state *sp,const char *fname,char *symbol,char * { fclose(indfp); if ( (fpos= komodo_stateind_validate(0,indfname,filedata,datalen,&prevpos100,&indcounter,symbol,dest)) < 0 ) - printf("unexpected komodostate.ind validate failure %s datalen.%ld\n",indfname.c_str(),datalen); + LogPrintf("unexpected komodostate.ind validate failure %s datalen.%ld\n",indfname.c_str(),datalen); else - printf("%s validated fpos.%ld\n",indfname.c_str(),fpos); + LogPrintf("%s validated fpos.%ld\n",indfname.c_str(),fpos); } - fprintf(stderr,"took %d seconds to process %s %ldKB\n",(int32_t)(time(NULL)-starttime),fname,datalen/1024); + LogPrintf("took %d seconds to process %s %ldKB\n",(int32_t)(time(NULL)-starttime),fname,datalen/1024); free(filedata); return true; } From 6acc6a4e31b59d8bbc717bbc93f0e97d88f9d0c7 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 9 Sep 2022 13:46:46 +0200 Subject: [PATCH 11/27] komodo_hardfork: avoid build error with CXXFLAGS='-g -O0' Issue: if we will try to build KomodoOcean with CXXFLAGS='-g -O0' we will get the following error during linkage: usr/bin/ld: libbitcoin_util.a(libbitcoin_util_a-util.o): in function `__static_initialization_and_destruction_0(int, int)': /home/decker/KomodoOcean/src/komodo_hardfork.h:19: undefined reference to `nStakedDecemberHardforkTimestamp' /usr/bin/ld: /home/decker/KomodoOcean/src/komodo_hardfork.h:19: undefined reference to `nS4Timestamp' /usr/bin/ld: /home/decker/KomodoOcean/src/komodo_hardfork.h:19: undefined reference to `nS5Timestamp' /usr/bin/ld: /home/decker/KomodoOcean/src/komodo_hardfork.h:19: undefined reference to `nS6Timestamp' /usr/bin/ld: /home/decker/KomodoOcean/src/komodo_hardfork.h:20: undefined reference to `nDecemberHardforkHeight' /usr/bin/ld: /home/decker/KomodoOcean/src/komodo_hardfork.h:20: undefined reference to `nS4HardforkHeight' /usr/bin/ld: /home/decker/KomodoOcean/src/komodo_hardfork.h:20: undefined reference to `nS5HardforkHeight' /usr/bin/ld: /home/decker/KomodoOcean/src/komodo_hardfork.h:20: undefined reference to `nS6HardforkHeight' So, we need to include komodo_hardfork.cpp into libbitcoin_util_a_SOURCES or delete include of komodo_hardfork.h from komodo_globals.h. --- src/komodo_globals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/komodo_globals.h b/src/komodo_globals.h index c285121b..967761e2 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -15,7 +15,7 @@ #pragma once #include #include "komodo_defs.h" -#include "komodo_hardfork.h" +//#include "komodo_hardfork.h" #include "komodo_structs.h" #define KOMODO_ELECTION_GAP 2000 //((ASSETCHAINS_SYMBOL[0] == 0) ? 2000 : 100) From 7f93ad80142134885df41ba5d6482f1ef1e5e949 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 9 Sep 2022 14:40:16 +0200 Subject: [PATCH 12/27] qt/komodo.cpp -> qt/komodoapp.cpp to avoid conflict with names in gdb --- src/Makefile.qt.include | 6 +++--- src/qt/{komodo.cpp => komodoapp.cpp} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/qt/{komodo.cpp => komodoapp.cpp} (99%) diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index b644e790..4a8c765b 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -179,7 +179,7 @@ KOMODO_MM = qt/macdockiconhandler.mm # qt/macnotificationhandler.mm QT_MOC = \ - qt/komodo.moc \ + qt/komodoapp.moc \ qt/komodoamountfield.moc \ qt/callback.moc \ qt/intro.moc \ @@ -438,7 +438,7 @@ qt_komodo_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(KOMODO_QT_INCLUDES) $(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) qt_komodo_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) -qt_komodo_qt_SOURCES = qt/komodo.cpp +qt_komodo_qt_SOURCES = qt/komodoapp.cpp if TARGET_DARWIN qt_komodo_qt_SOURCES += $(KOMODO_MM) endif @@ -526,7 +526,7 @@ $(srcdir)/qt/komodostrings.cpp: $(libkomodo_server_a_SOURCES) $(libkomodo_wallet @test -n $(XGETTEXT) || echo "xgettext is required for updating translations" $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" COPYRIGHT_HOLDERS_SUBSTITUTION="$(COPYRIGHT_HOLDERS_SUBSTITUTION)" $(PYTHON) ../share/qt/extract_strings_qt.py $^ -translate: $(srcdir)/qt/komodostrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(KOMODO_QT_BASE_CPP) qt/komodo.cpp $(KOMODO_QT_WINDOWS_CPP) $(KOMODO_QT_WALLET_CPP) $(KOMODO_QT_H) $(KOMODO_MM) +translate: $(srcdir)/qt/komodostrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(KOMODO_QT_BASE_CPP) qt/komodoapp.cpp $(KOMODO_QT_WINDOWS_CPP) $(KOMODO_QT_WALLET_CPP) $(KOMODO_QT_H) $(KOMODO_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts $(srcdir)/qt/locale/komodo_en.ts diff --git a/src/qt/komodo.cpp b/src/qt/komodoapp.cpp similarity index 99% rename from src/qt/komodo.cpp rename to src/qt/komodoapp.cpp index 4d1b02d2..7b73b41e 100644 --- a/src/qt/komodo.cpp +++ b/src/qt/komodoapp.cpp @@ -274,7 +274,7 @@ public Q_SLOTS: void startThread(); }; -#include "komodo.moc" +#include "komodoapp.moc" KomodoCore::KomodoCore(): QObject() From 32f43bbb9d68360e486a6346a82f2fd3c70165c2 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 9 Sep 2022 18:36:07 +0200 Subject: [PATCH 13/27] fix tests build (--enable-tests=yes) --- src/Makefile.ktest.include | 3 +-- src/test-komodo/test_events.cpp | 14 +++++++------- src/test-komodo/test_haraka_removal.cpp | 2 +- src/test-komodo/testutils.cpp | 6 +++--- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/Makefile.ktest.include b/src/Makefile.ktest.include index f665d786..0d8a185d 100644 --- a/src/Makefile.ktest.include +++ b/src/Makefile.ktest.include @@ -19,8 +19,7 @@ komodo_test_SOURCES = \ test-komodo/test_netbase_tests.cpp \ test-komodo/test_events.cpp \ test-komodo/test_hex.cpp \ - test-komodo/test_haraka_removal.cpp \ - test-komodo/test_miner.cpp + test-komodo/test_haraka_removal.cpp komodo_test_CPPFLAGS = $(komodod_CPPFLAGS) diff --git a/src/test-komodo/test_events.cpp b/src/test-komodo/test_events.cpp index d2879e1c..c3438511 100644 --- a/src/test-komodo/test_events.cpp +++ b/src/test-komodo/test_events.cpp @@ -3,11 +3,10 @@ #include #include #include -#include - -int32_t komodo_faststateinit(struct komodo_state *sp,char *fname,char *symbol,char *dest); -struct komodo_state *komodo_stateptrget(char *base); -extern int32_t KOMODO_EXTERNAL_NOTARIES; +#include "komodo.h" +#include "komodo_structs.h" +#include "komodo_gateway.h" +#include "komodo_extern_globals.h" namespace TestEvents { @@ -158,7 +157,8 @@ TEST(TestEvents, komodo_faststateinit_test) SetupEnvironment(); char symbol[] = "TST"; - strcpy(ASSETCHAINS_SYMBOL, symbol); + + chainName = assetchain("TST"); KOMODO_EXTERNAL_NOTARIES = 1; boost::filesystem::path temp = boost::filesystem::unique_path(); @@ -570,7 +570,7 @@ TEST(TestEvents, komodo_faststateinit_test_kmd) // Nothing should be added to events if this is the komodo chain char symbol[] = "KMD"; - ASSETCHAINS_SYMBOL[0] = 0; + chainName = assetchain(); KOMODO_EXTERNAL_NOTARIES = 0; boost::filesystem::path temp = boost::filesystem::unique_path(); diff --git a/src/test-komodo/test_haraka_removal.cpp b/src/test-komodo/test_haraka_removal.cpp index 3fd66be8..77074dd3 100644 --- a/src/test-komodo/test_haraka_removal.cpp +++ b/src/test-komodo/test_haraka_removal.cpp @@ -65,7 +65,7 @@ namespace TestHarakaRemoval { //#define PRG_VALUES_BEFORE_PR 1 TEST(TestHarakaRemoval, test_block_prg) { - EXPECT_EQ(ASSETCHAINS_SYMBOL[0], 0); + chainName = assetchain(); // EXPECT_EQ(ASSETCHAINS_SYMBOL[0], 0); // ASSETCHAINS_TIMEUNLOCKFROM = GetArg("-ac_timeunlockfrom", 0) -> 129600 ASSETCHAINS_TIMEUNLOCKFROM = 129600; diff --git a/src/test-komodo/testutils.cpp b/src/test-komodo/testutils.cpp index c17de8bb..eb1178c2 100644 --- a/src/test-komodo/testutils.cpp +++ b/src/test-komodo/testutils.cpp @@ -44,7 +44,7 @@ void setupChain() NOTARY_PUBKEY = notaryPubkey; USE_EXTERNAL_PUBKEY = 1; mapArgs["-mineraddress"] = "bogus"; - COINBASE_MATURITY = 1; + ::Params().SetCoinbaseMaturity(1); // Global mock time nMockTime = GetTime(); @@ -54,8 +54,8 @@ void setupChain() // Init blockchain ClearDatadirCache(); auto pathTemp = GetTempPath() / strprintf("test_komodo_%li_%i", GetTime(), GetRand(100000)); - if (ASSETCHAINS_SYMBOL[0]) - pathTemp = pathTemp / strprintf("_%s", ASSETCHAINS_SYMBOL); + if (!chainName.isKMD()) + pathTemp = pathTemp / strprintf("_%s", chainName.symbol().c_str()); boost::filesystem::create_directories(pathTemp); mapArgs["-datadir"] = pathTemp.string(); pblocktree = new CBlockTreeDB(1 << 20, true); From 16b5f5cd18334ad5958add414d59cb787a54054c Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 9 Sep 2022 19:11:36 +0200 Subject: [PATCH 14/27] report about komodostate parse error in messagebox, instead of console --- src/komodo.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/komodo.cpp b/src/komodo.cpp index bfbd16b4..6a1b4ee3 100644 --- a/src/komodo.cpp +++ b/src/komodo.cpp @@ -115,7 +115,8 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char { LogPrintf("Error occurred in parsestatefile: %s\n", pe.what()); LogPrintf("komodostate file is invalid. Komodod will be stopped. Please remove komodostate and komodostate.ind files and start the daemon"); - std::cerr << std::endl << " Error in komodostate file: unknown event " << (char)func << ", exiting. Please remove komodostate and komodostate.ind files and start the daemon" << std::endl << std::endl; + // std::cerr << std::endl << " Error in komodostate file: unknown event " << (char)func << ", exiting. Please remove komodostate and komodostate.ind files and start the daemon" << std::endl << std::endl; + uiInterface.ThreadSafeMessageBox(_("Please remove komodostate and komodostate.ind files and restart"), "", CClientUIInterface::MSG_ERROR); StartShutdown(); func = -1; } @@ -191,7 +192,8 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long { LogPrintf("Unable to parse state file data. Error: %s\n", pe.what()); LogPrintf("komodostate file is invalid. Komodod will be stopped. Please remove komodostate and komodostate.ind files and start the daemon"); - std::cerr << std::endl << " Error in komodostate file: unknown event " << (char)func << ", exiting. Please remove komodostate and komodostate.ind files and start the daemon" << std::endl << std::endl; + // std::cerr << std::endl << " Error in komodostate file: unknown event " << (char)func << ", exiting. Please remove komodostate and komodostate.ind files and start the daemon" << std::endl << std::endl; + uiInterface.ThreadSafeMessageBox(_("Please remove komodostate and komodostate.ind files and restart"), "", CClientUIInterface::MSG_ERROR); StartShutdown(); func = -1; } From 8ca979469035ffb91986c64513907953bed96ce0 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 9 Sep 2022 21:06:04 +0200 Subject: [PATCH 15/27] Qt: fix komodo units display, disable interest display for ACs --- src/qt/komodounits.cpp | 9 +++------ src/qt/overviewpage.cpp | 4 +--- src/qt/walletmodel.cpp | 8 +++----- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/qt/komodounits.cpp b/src/qt/komodounits.cpp index ccc20257..725e6634 100644 --- a/src/qt/komodounits.cpp +++ b/src/qt/komodounits.cpp @@ -9,9 +9,6 @@ #include -#define KOMODO_ASSETCHAIN_MAXLEN 65 -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; - KomodoUnits::KomodoUnits(QObject *parent): QAbstractListModel(parent), unitlist(availableUnits()) @@ -44,9 +41,9 @@ QString KomodoUnits::name(int unit) { switch(unit) { - case KMD: return QString(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL); - case mKMD: return QString("m")+QString(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL); - case uKMD: return QString::fromUtf8("μ")+QString(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL); + case KMD: return QString(chainName.ToString().c_str()); + case mKMD: return QString("m")+QString(chainName.ToString().c_str()); + case uKMD: return QString::fromUtf8("μ")+QString(chainName.ToString().c_str()); default: return QString("???"); } } diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index f8abbc7a..c0d30b3a 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -24,8 +24,6 @@ #define DECORATION_SIZE 54 #define NUM_ITEMS 5 -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; - class TxViewDelegate : public QAbstractItemDelegate { Q_OBJECT @@ -211,7 +209,7 @@ void OverviewPage::setBalance(const CAmount& balance, const CAmount& unconfirmed // for the non-mining users bool showImmature = immatureBalance != 0; bool showWatchOnlyImmature = watchImmatureBalance != 0; - bool showInterest = (ASSETCHAINS_SYMBOL[0] == 0); + bool showInterest = chainName.isKMD(); // for symmetry reasons also show immature label when the watch-only one is shown ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 56b48f0f..f97c8e7c 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -51,8 +51,6 @@ extern CAmount getBalanceZaddr(std::string address, int minDepth = 1, bool ignor extern CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1, bool ignoreUnspendable=true); extern uint64_t komodo_interestsum(); -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; - // JSDescription size depends on the transaction version #define V3_JS_DESCRIPTION_SIZE (GetSerializeSize(JSDescription(), SER_NETWORK, (OVERWINTER_TX_VERSION | (1 << 31)))) // Here we define the maximum number of zaddr outputs that can be included in a transaction. @@ -122,7 +120,7 @@ CAmount WalletModel::getPrivateBalance() const CAmount WalletModel::getInterestBalance() const { - return (ASSETCHAINS_SYMBOL[0] == 0) ? komodo_interestsum() : 0; + return (chainName.isKMD()) ? komodo_interestsum() : 0; } bool WalletModel::haveWatchOnly() const @@ -187,7 +185,7 @@ void WalletModel::checkBalanceChanged() CAmount newWatchUnconfBalance = 0; CAmount newWatchImmatureBalance = 0; CAmount newprivateBalance = getBalanceZaddr("", 1, true); - CAmount newinterestBalance = (ASSETCHAINS_SYMBOL[0] == 0) ? komodo_interestsum() : 0; + CAmount newinterestBalance = (chainName.isKMD()) ? komodo_interestsum() : 0; if (haveWatchOnly()) { newWatchOnlyBalance = getWatchBalance(); @@ -445,7 +443,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareZTransaction(WalletModelZTransa if ( fromSprout || toSprout ) return SproutUsageExpired; } - if ( toSapling && ASSETCHAINS_SYMBOL[0] == 0 ) + if ( toSapling && chainName.isKMD() ) return SproutUsageWillExpireSoon; // If we are sending from a shielded address, all recipient From 30c14f2946680e75dab5e464b4e5be00f25257b7 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Tue, 13 Sep 2022 01:23:41 +0200 Subject: [PATCH 16/27] configure libgmp on Linux with --with-pic=yes to avoid the following errors: /usr/bin/ld: depends/x86_64-unknown-linux-gnu/lib/libgmp.a(invert_limb.o): warning: relocation against `__gmpn_invert_limb_table' in read-only section `.text' /usr/bin/ld: warning: creating DT_TEXTREL in a PIE when build with 11.2.0 (Ubuntu 22.04.1 LTS, etc.) --- depends/packages/libgmp.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/libgmp.mk b/depends/packages/libgmp.mk index c6b5569d..ee2476ff 100644 --- a/depends/packages/libgmp.mk +++ b/depends/packages/libgmp.mk @@ -22,7 +22,7 @@ $(package)_download_path=https://ftp.gnu.org/gnu/gmp $(package)_file_name=gmp-$($(package)_version).tar.bz2 $(package)_sha256_hash=a8109865f2893f1373b0a8ed5ff7429de8db696fc451b1036bd7bdf95bbeffd6 $(package)_dependencies= -$(package)_config_opts=--enable-cxx --disable-shared +$(package)_config_opts=--enable-cxx --disable-shared --with-pic endif define $(package)_config_cmds From d9e89027333fe652b85df66a1fb439c55cff8f7f Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Tue, 13 Sep 2022 01:30:31 +0200 Subject: [PATCH 17/27] remove unused sources from repo (after #559) --- src/komodo_globals.h | 1 - src/komodo_pax.cpp | 686 ---------------------------------- src/komodo_pax.h | 88 ----- src/komodo_port.c | 871 ------------------------------------------- 4 files changed, 1646 deletions(-) delete mode 100644 src/komodo_pax.cpp delete mode 100644 src/komodo_pax.h delete mode 100644 src/komodo_port.c diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 967761e2..eb170d8b 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -35,7 +35,6 @@ extern bool IS_KOMODO_DEALERNODE; extern int32_t KOMODO_MININGTHREADS; extern int32_t STAKED_NOTARY_ID; extern int32_t USE_EXTERNAL_PUBKEY; -extern int32_t KOMODO_PAX; extern int32_t KOMODO_REWIND; extern int32_t STAKED_ERA; extern int32_t KOMODO_CONNECTING; diff --git a/src/komodo_pax.cpp b/src/komodo_pax.cpp deleted file mode 100644 index 40f4b6de..00000000 --- a/src/komodo_pax.cpp +++ /dev/null @@ -1,686 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ -#include "komodo_pax.h" -#include "komodo_globals.h" -#include "komodo_utils.h" // iguana_rwnum -#include "komodo.h" // KOMODO_PAXMAX - -uint32_t *PVALS; -int32_t NUM_PRICES; - -uint64_t M1SUPPLY[] = { 3317900000000, 6991604000000, 667780000000000, 1616854000000, 331000000000, 861909000000, 584629000000, 46530000000, // major currencies - 45434000000000, 16827000000000, 3473357229000, 306435000000, 27139000000000, 2150641000000, 347724099000, 1469583000000, 749543000000, 1826110000000, 2400434000000, 1123925000000, 3125276000000, 13975000000000, 317657000000, 759706000000000, 354902000000, 2797061000000, 162189000000, 163745000000, 1712000000000, 39093000000, 1135490000000000, 80317000000, - 100000000 }; - -#define MIND 1000 -uint32_t MINDENOMS[] = { MIND, MIND, 100*MIND, MIND, MIND, MIND, MIND, MIND, // major currencies - 10*MIND, 100*MIND, 10*MIND, MIND, 100*MIND, 10*MIND, MIND, 10*MIND, MIND, 10*MIND, 10*MIND, 10*MIND, 10*MIND, 100*MIND, MIND, 1000*MIND, MIND, 10*MIND, MIND, MIND, 10*MIND, MIND, 10000*MIND, 10*MIND, // end of currencies -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_maxallowed(int32_t baseid) -{ - uint64_t mult,val = COIN * (uint64_t)10000; - if ( baseid < 0 || baseid >= 32 ) - return(0); - if ( baseid < 10 ) - val *= 4; - mult = MINDENOMS[baseid] / MIND; - return(mult * val); -} - -uint64_t komodo_paxvol(uint64_t volume,uint64_t price) -{ - if ( volume < 10000000000 ) - return((volume * price) / 1000000000); - else if ( volume < (uint64_t)10 * 10000000000 ) - return((volume * (price / 10)) / 100000000); - else if ( volume < (uint64_t)100 * 10000000000 ) - return(((volume / 10) * (price / 10)) / 10000000); - else if ( volume < (uint64_t)1000 * 10000000000 ) - return(((volume / 10) * (price / 100)) / 1000000); - else if ( volume < (uint64_t)10000 * 10000000000 ) - return(((volume / 100) * (price / 100)) / 100000); - else if ( volume < (uint64_t)100000 * 10000000000 ) - return(((volume / 100) * (price / 1000)) / 10000); - else if ( volume < (uint64_t)1000000 * 10000000000 ) - return(((volume / 1000) * (price / 1000)) / 1000); - else if ( volume < (uint64_t)10000000 * 10000000000 ) - return(((volume / 1000) * (price / 10000)) / 100); - else return(((volume / 10000) * (price / 10000)) / 10); -} - -void pax_rank(uint64_t *ranked,uint32_t *pvals) -{ - int32_t i; uint64_t vals[32],sum = 0; - for (i=0; i<32; i++) - { - vals[i] = komodo_paxvol(M1SUPPLY[i] / MINDENOMS[i],pvals[i]); - sum += vals[i]; - } - for (i=0; i<32; i++) - { - ranked[i] = (vals[i] * 1000000000) / sum; - //LogPrintf("%.6f ",(double)ranked[i]/1000000000.); - } - //LogPrintf("sum %llu\n",(long long)sum); -}; - -#define BTCFACTOR_HEIGHT 466266 - -double PAX_BTCUSD(int32_t height,uint32_t btcusd) -{ - double btcfactor,BTCUSD; - if ( height >= BTCFACTOR_HEIGHT ) - btcfactor = 100000.; - else btcfactor = 1000.; - BTCUSD = ((double)btcusd / (1000000000. / btcfactor)); - if ( height >= BTCFACTOR_HEIGHT && height < 500000 && BTCUSD > 20000 && btcfactor == 100000. ) - BTCUSD /= 100; - return(BTCUSD); -} - -int32_t dpow_readprices(int32_t height,uint8_t *data,uint32_t *timestampp,double *KMDBTCp,double *BTCUSDp,double *CNYUSDp,uint32_t *pvals) -{ - uint32_t kmdbtc,btcusd,cnyusd; int32_t i,n,nonz,len = 0; - if ( data[0] == 'P' && data[5] == 35 ) - data++; - len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)timestampp); - len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&n); - if ( n != 35 ) - { - LogPrintf("dpow_readprices illegal n.%d\n",n); - return(-1); - } - len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&kmdbtc); // /= 1000 - len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&btcusd); // *= 1000 - len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&cnyusd); - *KMDBTCp = ((double)kmdbtc / (1000000000. * 1000.)); - *BTCUSDp = PAX_BTCUSD(height,btcusd); - *CNYUSDp = ((double)cnyusd / 1000000000.); - for (i=nonz=0; i sizeof(crc32) ) - { - if ( (retval= (int32_t)fread(data,1,fsize,fp)) == fsize ) - { - len = iguana_rwnum(0,data,sizeof(crc32),(void *)&crc32); - check = calc_crc32(0,data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32))); - if ( check == crc32 ) - { - double KMDBTC,BTCUSD,CNYUSD; uint32_t pvals[128]; - if ( dpow_readprices(height,&data[len],×tamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals) > 0 ) - { - if ( 0 && lastcrc != crc32 ) - { - for (i=0; i<32; i++) - LogPrintf("%u ",pvals[i]); - LogPrintf("t%u n.%d KMD %f BTC %f CNY %f (%f)\n",timestamp,n,KMDBTC,BTCUSD,CNYUSD,CNYUSD!=0?1./CNYUSD:0); - } - if ( timestamp > time(NULL)-600 ) - { - n = komodo_opreturnscript(opret,'P',data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32))); - if ( 0 && lastcrc != crc32 ) - { - for (i=0; i maxsize.%d or data[%d]\n",fsize,maxsize,(int32_t)sizeof(data)); - fclose(fp); - } //else LogPrintf("couldnt open %s\n",fname); - return(n); -} - -int32_t PAX_pubkey(int32_t rwflag,uint8_t *pubkey33,uint8_t *addrtypep,uint8_t rmd160[20],char fiat[4],uint8_t *shortflagp,int64_t *fiatoshisp) -{ - if ( rwflag != 0 ) - { - memset(pubkey33,0,33); - pubkey33[0] = 0x02 | (*shortflagp != 0); - memcpy(&pubkey33[1],fiat,3); - iguana_rwnum(rwflag,&pubkey33[4],sizeof(*fiatoshisp),(void *)fiatoshisp); - pubkey33[12] = *addrtypep; - memcpy(&pubkey33[13],rmd160,20); - } - else - { - *shortflagp = (pubkey33[0] == 0x03); - memcpy(fiat,&pubkey33[1],3); - fiat[3] = 0; - iguana_rwnum(rwflag,&pubkey33[4],sizeof(*fiatoshisp),(void *)fiatoshisp); - if ( *shortflagp != 0 ) - *fiatoshisp = -(*fiatoshisp); - *addrtypep = pubkey33[12]; - memcpy(rmd160,&pubkey33[13],20); - } - return(33); -} - -double PAX_val(uint32_t pval,int32_t baseid) -{ - //LogPrintf("PAX_val baseid.%d pval.%u\n",baseid,pval); - if ( baseid >= 0 && baseid < MAX_CURRENCIES ) - return(((double)pval / 1000000000.) / MINDENOMS[baseid]); - return(0.); -} - -void komodo_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals) -{ - int32_t i,nonz; uint32_t kmdbtc,btcusd,cnyusd; double KMDBTC,BTCUSD,CNYUSD; - if ( numpvals >= 35 ) - { - for (nonz=i=0; i<32; i++) - { - if ( pvals[i] != 0 ) - nonz++; - //LogPrintf("%u ",pvals[i]); - } - if ( nonz == 32 ) - { - kmdbtc = pvals[i++]; - btcusd = pvals[i++]; - cnyusd = pvals[i++]; - KMDBTC = ((double)kmdbtc / (1000000000. * 1000.)); - BTCUSD = PAX_BTCUSD(height,btcusd); - CNYUSD = ((double)cnyusd / 1000000000.); - std::lock_guard lock(komodo_mutex); - PVALS = (uint32_t *)realloc(PVALS,(NUM_PRICES+1) * sizeof(*PVALS) * 36); - PVALS[36 * NUM_PRICES] = height; - memcpy(&PVALS[36 * NUM_PRICES + 1],pvals,sizeof(*pvals) * 35); - NUM_PRICES++; - } - } -} - -uint64_t komodo_paxcorrelation(uint64_t *votes,int32_t numvotes,uint64_t seed) -{ - int32_t i,j,k,ind,zeroes,wt,nonz; int64_t delta; uint64_t lastprice,tolerance,den,densum,sum=0; - for (sum=i=zeroes=nonz=0; i> 2) ) - return(0); - sum /= nonz; - lastprice = sum; - for (i=0; i (numvotes >> 1) ) - break; - } - } - } - } - if ( wt > (numvotes >> 1) ) - { - ind = i; - for (densum=sum=j=0; j KOMODO_PAXMAX ) - { - LogPrintf("paxcalc overflow %.8f\n",dstr(basevolume)); - return(0); - } - if ( (pvalb= pvals[baseid]) != 0 ) - { - if ( relid == MAX_CURRENCIES ) - { - if ( height < 236000 ) - { - if ( kmdbtc == 0 ) - kmdbtc = pvals[MAX_CURRENCIES]; - if ( btcusd == 0 ) - btcusd = pvals[MAX_CURRENCIES + 1]; - } - else - { - if ( (kmdbtc= pvals[MAX_CURRENCIES]) == 0 ) - kmdbtc = refkmdbtc; - if ( (btcusd= pvals[MAX_CURRENCIES + 1]) == 0 ) - btcusd = refbtcusd; - } - if ( kmdbtc < 25000000 ) - kmdbtc = 25000000; - if ( pvals[USD] != 0 && kmdbtc != 0 && btcusd != 0 ) - { - baseusd = (((uint64_t)pvalb * 1000000000) / pvals[USD]); - usdvol = komodo_paxvol(basevolume,baseusd); - usdkmd = ((uint64_t)kmdbtc * 1000000000) / btcusd; - if ( height >= 236000-10 ) - { - BTCUSD = PAX_BTCUSD(height,btcusd); - if ( height < BTCFACTOR_HEIGHT || (height < 500000 && BTCUSD > 20000) ) - usdkmd = ((uint64_t)kmdbtc * btcusd) / 1000000000; - else usdkmd = ((uint64_t)kmdbtc * btcusd) / 10000000; - ///if ( height >= BTCFACTOR_HEIGHT && BTCUSD >= 43 ) - // usdkmd = ((uint64_t)kmdbtc * btcusd) / 10000000; - //else usdkmd = ((uint64_t)kmdbtc * btcusd) / 1000000000; - price = ((uint64_t)10000000000 * MINDENOMS[USD] / MINDENOMS[baseid]) / komodo_paxvol(usdvol,usdkmd); - //LogPrintf("ht.%d %.3f kmdbtc.%llu btcusd.%llu base -> USD %llu, usdkmd %llu usdvol %llu -> %llu\n",height,BTCUSD,(long long)kmdbtc,(long long)btcusd,(long long)baseusd,(long long)usdkmd,(long long)usdvol,(long long)(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100))); - //LogPrintf("usdkmd.%llu basevolume.%llu baseusd.%llu paxvol.%llu usdvol.%llu -> %llu %llu\n",(long long)usdkmd,(long long)basevolume,(long long)baseusd,(long long)komodo_paxvol(basevolume,baseusd),(long long)usdvol,(long long)(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100)),(long long)price); - //LogPrintf("usdkmd.%llu basevolume.%llu baseusd.%llu paxvol.%llu usdvol.%llu -> %llu\n",(long long)usdkmd,(long long)basevolume,(long long)baseusd,(long long)komodo_paxvol(basevolume,baseusd),(long long)usdvol,(long long)(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100))); - } else price = (MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100)); - return(price); - } //else LogPrintf("zero val in KMD conv %llu %llu %llu\n",(long long)pvals[USD],(long long)kmdbtc,(long long)btcusd); - } - else if ( baseid == relid ) - { - if ( baseid != MAX_CURRENCIES ) - { - pax_rank(ranked,pvals); - //LogPrintf("%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 ) - { - baserel = ((uint64_t)pvalb * 1000000000) / pvalr; - //LogPrintf("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)); - } - else LogPrintf("null pval for %s\n",CURRENCIES[relid]); - } else LogPrintf("null pval for %s\n",CURRENCIES[baseid]); - return(0); -} - -uint64_t _komodo_paxprice(uint64_t *kmdbtcp,uint64_t *btcusdp,int32_t height,char *base,char *rel,uint64_t basevolume,uint64_t kmdbtc,uint64_t btcusd) -{ - int32_t baseid=-1,relid=-1,i; uint32_t *ptr,*pvals; - if ( height > 10 ) - height -= 10; - if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 ) - { - for (i=NUM_PRICES-1; i>=0; i--) - { - ptr = &PVALS[36 * i]; - if ( *ptr < height ) - { - pvals = &ptr[1]; - if ( kmdbtcp != 0 && btcusdp != 0 ) - { - *kmdbtcp = pvals[MAX_CURRENCIES] / 539; - *btcusdp = pvals[MAX_CURRENCIES + 1] / 539; - } - if ( kmdbtc != 0 && btcusd != 0 ) - return(komodo_paxcalc(height,pvals,baseid,relid,basevolume,kmdbtc,btcusd)); - else return(0); - } - } - } //else LogPrintf("paxprice invalid base.%s %d, rel.%s %d\n",base,baseid,rel,relid); - return(0); -} - -int32_t komodo_kmdbtcusd(int32_t rwflag,uint64_t *kmdbtcp,uint64_t *btcusdp,int32_t height) -{ - static uint64_t *KMDBTCS,*BTCUSDS; static int32_t maxheight = 0; int32_t incr = 10000; - if ( height >= maxheight ) - { - //LogPrintf("height.%d maxheight.%d incr.%d\n",height,maxheight,incr); - if ( height >= maxheight+incr ) - incr = (height - (maxheight+incr) + 1000); - KMDBTCS = (uint64_t *)realloc(KMDBTCS,((incr + maxheight) * sizeof(*KMDBTCS))); - memset(&KMDBTCS[maxheight],0,(incr * sizeof(*KMDBTCS))); - BTCUSDS = (uint64_t *)realloc(BTCUSDS,((incr + maxheight) * sizeof(*BTCUSDS))); - memset(&BTCUSDS[maxheight],0,(incr * sizeof(*BTCUSDS))); - maxheight += incr; - } - if ( rwflag == 0 ) - { - *kmdbtcp = KMDBTCS[height]; - *btcusdp = BTCUSDS[height]; - } - else - { - KMDBTCS[height] = *kmdbtcp; - BTCUSDS[height] = *btcusdp; - } - if ( *kmdbtcp != 0 && *btcusdp != 0 ) - return(0); - else return(-1); -} - -uint64_t _komodo_paxpriceB(uint64_t seed,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,tolerance,den,densum,sum=0,votes[sizeof(Peggy_inds)/sizeof(*Peggy_inds)],btcusds[sizeof(Peggy_inds)/sizeof(*Peggy_inds)],kmdbtcs[sizeof(Peggy_inds)/sizeof(*Peggy_inds)],kmdbtc,btcusd; - if ( basevolume > KOMODO_PAXMAX ) - { - LogPrintf("komodo_paxprice overflow %.8f\n",dstr(basevolume)); - return(0); - } - if ( strcmp(base,"KMD") == 0 || strcmp(base,"kmd") == 0 ) - { - LogPrintf("kmd cannot be base currency\n"); - return(0); - } - numvotes = (int32_t)(sizeof(Peggy_inds)/sizeof(*Peggy_inds)); - memset(votes,0,sizeof(votes)); - //if ( komodo_kmdbtcusd(0,&kmdbtc,&btcusd,height) < 0 ) crashes when via passthru GUI use - { - memset(btcusds,0,sizeof(btcusds)); - memset(kmdbtcs,0,sizeof(kmdbtcs)); - for (i=0; i> 1) ) - { - return(0); - } - return(komodo_paxcorrelation(votes,numvotes,seed) * basevolume / 100000); -} - -uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint64_t basevolume) -{ - uint64_t baseusd,basekmd,usdkmd; int32_t baseid = komodo_baseid(base); - if ( height >= 236000 && strcmp(rel,"kmd") == 0 ) - { - usdkmd = _komodo_paxpriceB(seed,height,(char *)"USD",(char *)"KMD",SATOSHIDEN); - if ( strcmp("usd",base) == 0 ) - return(komodo_paxvol(basevolume,usdkmd) * 10); - baseusd = _komodo_paxpriceB(seed,height,base,(char *)"USD",SATOSHIDEN); - basekmd = (komodo_paxvol(basevolume,baseusd) * usdkmd) / 10000000; - //if ( strcmp("KMD",base) == 0 ) - // LogPrintf("baseusd.%llu usdkmd.%llu %llu\n",(long long)baseusd,(long long)usdkmd,(long long)basekmd); - return(basekmd); - } else return(_komodo_paxpriceB(seed,height,base,rel,basevolume)); -} - -uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume) -{ - int32_t i,nonz=0; int64_t diff; uint64_t price,seed,sum = 0; - if ( chainName.isKMD() && chainActive.Tip() != 0 && height > chainActive.Tip()->nHeight ) - { - if ( height < 100000000 ) - { - static uint32_t counter; - if ( counter++ < 3 ) - LogPrintf("komodo_paxprice height.%d vs tip.%d\n",height,chainActive.Tip()->nHeight); - } - return(0); - } - *seedp = komodo_seed(height); - { - std::lock_guard lock(komodo_mutex); - for (i=0; i<17; i++) - { - if ( (price= komodo_paxpriceB(*seedp,height-i,base,rel,basevolume)) != 0 ) - { - sum += price; - nonz++; - if ( 0 && i == 1 && nonz == 2 ) - { - diff = (((int64_t)price - (sum >> 1)) * 10000); - if ( diff < 0 ) - diff = -diff; - diff /= price; - LogPrintf("(%llu %llu %lld).%lld ",(long long)price,(long long)(sum>>1),(long long)(((int64_t)price - (sum >> 1)) * 10000),(long long)diff); - if ( diff < 33 ) - break; - } - else if ( 0 && i == 3 && nonz == 4 ) - { - diff = (((int64_t)price - (sum >> 2)) * 10000); - if ( diff < 0 ) - diff = -diff; - diff /= price; - LogPrintf("(%llu %llu %lld).%lld ",(long long)price,(long long)(sum>>2),(long long) (((int64_t)price - (sum >> 2)) * 10000),(long long)diff); - if ( diff < 20 ) - break; - } - } - if ( height < 165000 || height > 236000 ) - break; - } - } - if ( nonz != 0 ) - sum /= nonz; - //LogPrintf("-> %lld %s/%s i.%d ht.%d\n",(long long)sum,base,rel,i,height); - return(sum); -} - -void komodo_paxpricefeed(int32_t height,uint8_t *pricefeed,int32_t opretlen) -{ - double KMDBTC,BTCUSD,CNYUSD; uint32_t numpvals,timestamp,pvals[128]; uint256 zero; - numpvals = dpow_readprices(height,pricefeed,×tamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals); - memset(&zero,0,sizeof(zero)); - komodo_stateupdate(height,0,0,0,zero,pvals,numpvals,0,0,0,0,0,0,zero,0); - if ( 0 ) - { - int32_t i; - for (i=0; i -#include -#include -#include - -uint64_t ASSETCHAINS_COMMISSION; -uint32_t ASSETCHAINS_MAGIC = 2387029918; -uint8_t ASSETCHAINS_OVERRIDE_PUBKEY33[33]; - -struct sha256_vstate { uint64_t length; uint32_t state[8],curlen; uint8_t buf[64]; }; -struct rmd160_vstate { uint64_t length; uint8_t buf[64]; uint32_t curlen, state[5]; }; - -// following is ported from libtom - -#define STORE32L(x, y) \ -{ (y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \ -(y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); } - -#define LOAD32L(x, y) \ -{ x = (uint32_t)(((uint64_t)((y)[3] & 255)<<24) | \ -((uint32_t)((y)[2] & 255)<<16) | \ -((uint32_t)((y)[1] & 255)<<8) | \ -((uint32_t)((y)[0] & 255))); } - -#define STORE64L(x, y) \ -{ (y)[7] = (uint8_t)(((x)>>56)&255); (y)[6] = (uint8_t)(((x)>>48)&255); \ -(y)[5] = (uint8_t)(((x)>>40)&255); (y)[4] = (uint8_t)(((x)>>32)&255); \ -(y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \ -(y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); } - -#define LOAD64L(x, y) \ -{ x = (((uint64_t)((y)[7] & 255))<<56)|(((uint64_t)((y)[6] & 255))<<48)| \ -(((uint64_t)((y)[5] & 255))<<40)|(((uint64_t)((y)[4] & 255))<<32)| \ -(((uint64_t)((y)[3] & 255))<<24)|(((uint64_t)((y)[2] & 255))<<16)| \ -(((uint64_t)((y)[1] & 255))<<8)|(((uint64_t)((y)[0] & 255))); } - -#define STORE32H(x, y) \ -{ (y)[0] = (uint8_t)(((x)>>24)&255); (y)[1] = (uint8_t)(((x)>>16)&255); \ -(y)[2] = (uint8_t)(((x)>>8)&255); (y)[3] = (uint8_t)((x)&255); } - -#define LOAD32H(x, y) \ -{ x = (uint32_t)(((uint64_t)((y)[0] & 255)<<24) | \ -((uint32_t)((y)[1] & 255)<<16) | \ -((uint32_t)((y)[2] & 255)<<8) | \ -((uint32_t)((y)[3] & 255))); } - -#define STORE64H(x, y) \ -{ (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255); \ -(y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255); \ -(y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255); \ -(y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); } - -#define LOAD64H(x, y) \ -{ x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ -(((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ -(((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ -(((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } - -// Various logical functions -#define RORc(x, y) ( ((((uint32_t)(x)&0xFFFFFFFFUL)>>(uint32_t)((y)&31)) | ((uint32_t)(x)<<(uint32_t)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) -#define S(x, n) RORc((x),(n)) -#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) -#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) -#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) -#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) -#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) -#define MIN(x, y) ( ((x)<(y))?(x):(y) ) - -static inline int32_t sha256_vcompress(struct sha256_vstate * md,uint8_t *buf) -{ - uint32_t S[8],W[64],t0,t1,i; - for (i=0; i<8; i++) // copy state into S - S[i] = md->state[i]; - for (i=0; i<16; i++) // copy the state into 512-bits into W[0..15] - LOAD32H(W[i],buf + (4*i)); - for (i=16; i<64; i++) // fill W[16..63] - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - -#define RND(a,b,c,d,e,f,g,h,i,ki) \ -t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ -t1 = Sigma0(a) + Maj(a, b, c); \ -d += t0; \ -h = t0 + t1; - - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); -#undef RND - for (i=0; i<8; i++) // feedback - md->state[i] = md->state[i] + S[i]; - return(0); -} - -#undef RORc -#undef Ch -#undef Maj -#undef S -#undef R -#undef Sigma0 -#undef Sigma1 -#undef Gamma0 -#undef Gamma1 - -static inline void sha256_vinit(struct sha256_vstate * md) -{ - md->curlen = 0; - md->length = 0; - md->state[0] = 0x6A09E667UL; - md->state[1] = 0xBB67AE85UL; - md->state[2] = 0x3C6EF372UL; - md->state[3] = 0xA54FF53AUL; - md->state[4] = 0x510E527FUL; - md->state[5] = 0x9B05688CUL; - md->state[6] = 0x1F83D9ABUL; - md->state[7] = 0x5BE0CD19UL; -} - -static inline int32_t sha256_vprocess(struct sha256_vstate *md,const uint8_t *in,uint64_t inlen) -{ - uint64_t n; int32_t err; - if ( md->curlen > sizeof(md->buf) ) - return(-1); - while ( inlen > 0 ) - { - if ( md->curlen == 0 && inlen >= 64 ) - { - if ( (err= sha256_vcompress(md,(uint8_t *)in)) != 0 ) - return(err); - md->length += 64 * 8, in += 64, inlen -= 64; - } - else - { - n = MIN(inlen,64 - md->curlen); - memcpy(md->buf + md->curlen,in,(size_t)n); - md->curlen += n, in += n, inlen -= n; - if ( md->curlen == 64 ) - { - if ( (err= sha256_vcompress(md,md->buf)) != 0 ) - return(err); - md->length += 8*64; - md->curlen = 0; - } - } - } - return(0); -} - -static inline int32_t sha256_vdone(struct sha256_vstate *md,uint8_t *out) -{ - int32_t i; - if ( md->curlen >= sizeof(md->buf) ) - return(-1); - md->length += md->curlen * 8; // increase the length of the message - md->buf[md->curlen++] = (uint8_t)0x80; // append the '1' bit - // if len > 56 bytes we append zeros then compress. Then we can fall back to padding zeros and length encoding like normal. - if ( md->curlen > 56 ) - { - while ( md->curlen < 64 ) - md->buf[md->curlen++] = (uint8_t)0; - sha256_vcompress(md,md->buf); - md->curlen = 0; - } - while ( md->curlen < 56 ) // pad upto 56 bytes of zeroes - md->buf[md->curlen++] = (uint8_t)0; - STORE64H(md->length,md->buf+56); // store length - sha256_vcompress(md,md->buf); - for (i=0; i<8; i++) // copy output - STORE32H(md->state[i],out+(4*i)); - return(0); -} - -void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len) -{ - struct sha256_vstate md; - sha256_vinit(&md); - sha256_vprocess(&md,src,len); - sha256_vdone(&md,hash); -} - -bits256 bits256_doublesha256(char *deprecated,uint8_t *data,int32_t datalen) -{ - bits256 hash,hash2; int32_t i; - vcalc_sha256(0,hash.bytes,data,datalen); - vcalc_sha256(0,hash2.bytes,hash.bytes,sizeof(hash)); - for (i=0; i>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) - -/* the ten basic operations FF() through III() */ -#define FF(a, b, c, d, e, x, s) \ -(a) += F((b), (c), (d)) + (x);\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define GG(a, b, c, d, e, x, s) \ -(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define HH(a, b, c, d, e, x, s) \ -(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define II(a, b, c, d, e, x, s) \ -(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define JJ(a, b, c, d, e, x, s) \ -(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define FFF(a, b, c, d, e, x, s) \ -(a) += F((b), (c), (d)) + (x);\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define GGG(a, b, c, d, e, x, s) \ -(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define HHH(a, b, c, d, e, x, s) \ -(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define III(a, b, c, d, e, x, s) \ -(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define JJJ(a, b, c, d, e, x, s) \ -(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -static int32_t rmd160_vcompress(struct rmd160_vstate *md,uint8_t *buf) -{ - uint32_t aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16]; - int i; - - /* load words X */ - for (i = 0; i < 16; i++){ - LOAD32L(X[i], buf + (4 * i)); - } - - /* load state */ - aa = aaa = md->state[0]; - bb = bbb = md->state[1]; - cc = ccc = md->state[2]; - dd = ddd = md->state[3]; - ee = eee = md->state[4]; - - /* round 1 */ - FF(aa, bb, cc, dd, ee, X[ 0], 11); - FF(ee, aa, bb, cc, dd, X[ 1], 14); - FF(dd, ee, aa, bb, cc, X[ 2], 15); - FF(cc, dd, ee, aa, bb, X[ 3], 12); - FF(bb, cc, dd, ee, aa, X[ 4], 5); - FF(aa, bb, cc, dd, ee, X[ 5], 8); - FF(ee, aa, bb, cc, dd, X[ 6], 7); - FF(dd, ee, aa, bb, cc, X[ 7], 9); - FF(cc, dd, ee, aa, bb, X[ 8], 11); - FF(bb, cc, dd, ee, aa, X[ 9], 13); - FF(aa, bb, cc, dd, ee, X[10], 14); - FF(ee, aa, bb, cc, dd, X[11], 15); - FF(dd, ee, aa, bb, cc, X[12], 6); - FF(cc, dd, ee, aa, bb, X[13], 7); - FF(bb, cc, dd, ee, aa, X[14], 9); - FF(aa, bb, cc, dd, ee, X[15], 8); - - /* round 2 */ - GG(ee, aa, bb, cc, dd, X[ 7], 7); - GG(dd, ee, aa, bb, cc, X[ 4], 6); - GG(cc, dd, ee, aa, bb, X[13], 8); - GG(bb, cc, dd, ee, aa, X[ 1], 13); - GG(aa, bb, cc, dd, ee, X[10], 11); - GG(ee, aa, bb, cc, dd, X[ 6], 9); - GG(dd, ee, aa, bb, cc, X[15], 7); - GG(cc, dd, ee, aa, bb, X[ 3], 15); - GG(bb, cc, dd, ee, aa, X[12], 7); - GG(aa, bb, cc, dd, ee, X[ 0], 12); - GG(ee, aa, bb, cc, dd, X[ 9], 15); - GG(dd, ee, aa, bb, cc, X[ 5], 9); - GG(cc, dd, ee, aa, bb, X[ 2], 11); - GG(bb, cc, dd, ee, aa, X[14], 7); - GG(aa, bb, cc, dd, ee, X[11], 13); - GG(ee, aa, bb, cc, dd, X[ 8], 12); - - /* round 3 */ - HH(dd, ee, aa, bb, cc, X[ 3], 11); - HH(cc, dd, ee, aa, bb, X[10], 13); - HH(bb, cc, dd, ee, aa, X[14], 6); - HH(aa, bb, cc, dd, ee, X[ 4], 7); - HH(ee, aa, bb, cc, dd, X[ 9], 14); - HH(dd, ee, aa, bb, cc, X[15], 9); - HH(cc, dd, ee, aa, bb, X[ 8], 13); - HH(bb, cc, dd, ee, aa, X[ 1], 15); - HH(aa, bb, cc, dd, ee, X[ 2], 14); - HH(ee, aa, bb, cc, dd, X[ 7], 8); - HH(dd, ee, aa, bb, cc, X[ 0], 13); - HH(cc, dd, ee, aa, bb, X[ 6], 6); - HH(bb, cc, dd, ee, aa, X[13], 5); - HH(aa, bb, cc, dd, ee, X[11], 12); - HH(ee, aa, bb, cc, dd, X[ 5], 7); - HH(dd, ee, aa, bb, cc, X[12], 5); - - /* round 4 */ - II(cc, dd, ee, aa, bb, X[ 1], 11); - II(bb, cc, dd, ee, aa, X[ 9], 12); - II(aa, bb, cc, dd, ee, X[11], 14); - II(ee, aa, bb, cc, dd, X[10], 15); - II(dd, ee, aa, bb, cc, X[ 0], 14); - II(cc, dd, ee, aa, bb, X[ 8], 15); - II(bb, cc, dd, ee, aa, X[12], 9); - II(aa, bb, cc, dd, ee, X[ 4], 8); - II(ee, aa, bb, cc, dd, X[13], 9); - II(dd, ee, aa, bb, cc, X[ 3], 14); - II(cc, dd, ee, aa, bb, X[ 7], 5); - II(bb, cc, dd, ee, aa, X[15], 6); - II(aa, bb, cc, dd, ee, X[14], 8); - II(ee, aa, bb, cc, dd, X[ 5], 6); - II(dd, ee, aa, bb, cc, X[ 6], 5); - II(cc, dd, ee, aa, bb, X[ 2], 12); - - /* round 5 */ - JJ(bb, cc, dd, ee, aa, X[ 4], 9); - JJ(aa, bb, cc, dd, ee, X[ 0], 15); - JJ(ee, aa, bb, cc, dd, X[ 5], 5); - JJ(dd, ee, aa, bb, cc, X[ 9], 11); - JJ(cc, dd, ee, aa, bb, X[ 7], 6); - JJ(bb, cc, dd, ee, aa, X[12], 8); - JJ(aa, bb, cc, dd, ee, X[ 2], 13); - JJ(ee, aa, bb, cc, dd, X[10], 12); - JJ(dd, ee, aa, bb, cc, X[14], 5); - JJ(cc, dd, ee, aa, bb, X[ 1], 12); - JJ(bb, cc, dd, ee, aa, X[ 3], 13); - JJ(aa, bb, cc, dd, ee, X[ 8], 14); - JJ(ee, aa, bb, cc, dd, X[11], 11); - JJ(dd, ee, aa, bb, cc, X[ 6], 8); - JJ(cc, dd, ee, aa, bb, X[15], 5); - JJ(bb, cc, dd, ee, aa, X[13], 6); - - /* parallel round 1 */ - JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); - JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); - JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); - JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); - JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); - JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); - JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); - JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); - JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); - JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); - JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); - JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); - JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); - JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); - JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); - JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); - - /* parallel round 2 */ - III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); - III(ddd, eee, aaa, bbb, ccc, X[11], 13); - III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); - III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); - III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); - III(eee, aaa, bbb, ccc, ddd, X[13], 8); - III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); - III(ccc, ddd, eee, aaa, bbb, X[10], 11); - III(bbb, ccc, ddd, eee, aaa, X[14], 7); - III(aaa, bbb, ccc, ddd, eee, X[15], 7); - III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); - III(ddd, eee, aaa, bbb, ccc, X[12], 7); - III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); - III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); - III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); - III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); - - /* parallel round 3 */ - HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); - HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); - HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); - HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); - HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); - HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); - HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); - HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); - HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); - HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); - HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); - HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); - HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); - HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); - HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); - HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); - - /* parallel round 4 */ - GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); - GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); - GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); - GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); - GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); - GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); - GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); - GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); - GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); - GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); - GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); - GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); - GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); - GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); - GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); - GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); - - /* parallel round 5 */ - FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); - FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); - FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); - FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); - FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); - FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); - FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); - FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); - FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); - FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); - FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); - FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); - FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); - FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); - FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); - FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); - - /* combine results */ - ddd += cc + md->state[1]; /* final result for md->state[0] */ - md->state[1] = md->state[2] + dd + eee; - md->state[2] = md->state[3] + ee + aaa; - md->state[3] = md->state[4] + aa + bbb; - md->state[4] = md->state[0] + bb + ccc; - md->state[0] = ddd; - - return 0; -} - -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return 0 if successful - */ -int rmd160_vinit(struct rmd160_vstate * md) -{ - md->state[0] = 0x67452301UL; - md->state[1] = 0xefcdab89UL; - md->state[2] = 0x98badcfeUL; - md->state[3] = 0x10325476UL; - md->state[4] = 0xc3d2e1f0UL; - md->curlen = 0; - md->length = 0; - return 0; -} -#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ -int func_name (struct rmd160_vstate * md, const unsigned char *in, unsigned long inlen) \ -{ \ -unsigned long n; \ -int err; \ -if (md->curlen > sizeof(md->buf)) { \ -return -1; \ -} \ -while (inlen > 0) { \ -if (md->curlen == 0 && inlen >= block_size) { \ -if ((err = compress_name (md, (unsigned char *)in)) != 0) { \ -return err; \ -} \ -md->length += block_size * 8; \ -in += block_size; \ -inlen -= block_size; \ -} else { \ -n = MIN(inlen, (block_size - md->curlen)); \ -memcpy(md->buf + md->curlen, in, (size_t)n); \ -md->curlen += n; \ -in += n; \ -inlen -= n; \ -if (md->curlen == block_size) { \ -if ((err = compress_name (md, md->buf)) != 0) { \ -return err; \ -} \ -md->length += 8*block_size; \ -md->curlen = 0; \ -} \ -} \ -} \ -return 0; \ -} - -/** - Process a block of memory though the hash - @param md The hash state - @param in The data to hash - @param inlen The length of the data (octets) - @return 0 if successful - */ -HASH_PROCESS(rmd160_vprocess, rmd160_vcompress, rmd160, 64) - -/** - Terminate the hash to get the digest - @param md The hash state - @param out [out] The destination of the hash (20 bytes) - @return 0 if successful - */ -int rmd160_vdone(struct rmd160_vstate * md, unsigned char *out) -{ - int i; - if (md->curlen >= sizeof(md->buf)) { - return -1; - } - /* increase the length of the message */ - md->length += md->curlen * 8; - - /* append the '1' bit */ - md->buf[md->curlen++] = (unsigned char)0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md->curlen > 56) { - while (md->curlen < 64) { - md->buf[md->curlen++] = (unsigned char)0; - } - rmd160_vcompress(md, md->buf); - md->curlen = 0; - } - /* pad upto 56 bytes of zeroes */ - while (md->curlen < 56) { - md->buf[md->curlen++] = (unsigned char)0; - } - /* store length */ - STORE64L(md->length, md->buf+56); - rmd160_vcompress(md, md->buf); - /* copy output */ - for (i = 0; i < 5; i++) { - STORE32L(md->state[i], out+(4*i)); - } - return 0; -} - -void calc_rmd160(char deprecated[41],uint8_t buf[20],uint8_t *msg,int32_t len) -{ - struct rmd160_vstate md; - rmd160_vinit(&md); - rmd160_vprocess(&md,msg,len); - rmd160_vdone(&md, buf); -} -#undef F -#undef G -#undef H -#undef I -#undef J -#undef ROLc -#undef FF -#undef GG -#undef HH -#undef II -#undef JJ -#undef FFF -#undef GGG -#undef HHH -#undef III -#undef JJJ - -static const uint32_t crc32_tab[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -uint32_t calc_crc32(uint32_t crc,const void *buf,size_t size) -{ - const uint8_t *p; - - p = (const uint8_t *)buf; - crc = crc ^ ~0U; - - while (size--) - crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); - - return crc ^ ~0U; -} - -void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen) -{ - bits256 hash; - vcalc_sha256(0,hash.bytes,data,datalen); - calc_rmd160(0,rmd160,hash.bytes,sizeof(hash)); -} - -int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp) -{ - int32_t i; uint64_t x; - if ( rwflag == 0 ) - { - x = 0; - for (i=len-1; i>=0; i--) - { - x <<= 8; - x |= serialized[i]; - } - switch ( len ) - { - case 1: *(uint8_t *)endianedp = (uint8_t)x; break; - case 2: *(uint16_t *)endianedp = (uint16_t)x; break; - case 4: *(uint32_t *)endianedp = (uint32_t)x; break; - case 8: *(uint64_t *)endianedp = (uint64_t)x; break; - } - } - else - { - x = 0; - switch ( len ) - { - case 1: x = *(uint8_t *)endianedp; break; - case 2: x = *(uint16_t *)endianedp; break; - case 4: x = *(uint32_t *)endianedp; break; - case 8: x = *(uint64_t *)endianedp; break; - } - for (i=0; i>= 8) - serialized[i] = (uint8_t)(x & 0xff); - } - return(len); -} - -uint16_t komodo_assetport(uint32_t magic,int32_t extralen) -{ - if ( magic == 0x8de4eef9 ) - return(7770); - else if ( extralen == 0 ) - return(8000 + (magic % 7777)); - else return(16000 + (magic % 49500)); -} - -uint16_t komodo_calcport(char *name,uint64_t supply,uint64_t endsubsidy,uint64_t reward,uint64_t halving,uint64_t decay,uint64_t commission,uint8_t staked,int32_t cc) -{ - uint8_t extrabuf[4096],*extraptr=0; int32_t extralen=0; uint64_t val; - if ( halving != 0 && halving < 1440 ) - { - halving = 1440; - LogPrintf("halving must be at least 1440 blocks\n"); - } - if ( decay == 100000000 && endsubsidy == 0 ) - { - decay = 0; - LogPrintf("decay of 100000000 means linear and that needs endsubsidy\n"); - } - else if ( decay > 100000000 ) - { - decay = 0; - LogPrintf("decay cant be more than 100000000\n"); - } - if ( endsubsidy != 0 || reward != 0 || halving != 0 || decay != 0 || commission != 0 || cc != 0 || staked != 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 ) - { - //LogPrintf("end.%llu reward.%llu halving.%llu decay.%llu perc.%llu\n",(long long)endsubsidy,(long long)reward,(long long)halving,(long long)decay,(long long)commission); - extraptr = extrabuf; - memcpy(extraptr,ASSETCHAINS_OVERRIDE_PUBKEY33,33), extralen = 33; - extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(endsubsidy),(void *)&endsubsidy); - extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(reward),(void *)&reward); - extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(halving),(void *)&halving); - extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(decay),(void *)&decay); - val = commission | (((uint64_t)staked & 0xff) << 32) | (((uint64_t)cc & 0xffffff) << 40); - extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(val),(void *)&val); - } - return(komodo_port(name,supply,&ASSETCHAINS_MAGIC,extraptr,extralen)); -} - -int main(int argc, char * argv[]) -{ - uint16_t rpcport; int32_t i,j,offset=0,jsonflag=0,num = 1; uint64_t supply=10,commission=0,endsubsidy,reward,halving,decay; uint8_t *allocated=0,staked=0; uint32_t cc = 3; - endsubsidy = reward = halving = decay = 0; - if ( argc < 2 ) - { - // staked, commission and cc hardcoded - LogPrintf("%s name supply endsubsidy reward halving decay\n",argv[0]); - LogPrintf("%s -gen num name supply endsubsidy reward halving decay\n",argv[0]); - return(-1); - } - if ( strncmp(argv[1],"-gen",3) == 0 ) - { - num = atoi(argv[2]); - if ( strcmp(argv[1],"-genjson") == 0 ) - jsonflag = 1; - offset = 2; - allocated = calloc(1,1 << 16); - } - if ( argc > offset + 2 ) - supply = (long long)atof(argv[offset + 2]); - if ( argc > offset + 3 ) - endsubsidy = (long long)atof(argv[offset + 3]); - if ( argc > offset + 4 ) - reward = (long long)atof(argv[offset + 4]); - if ( argc > offset + 5 ) - halving = (long long)atof(argv[offset + 5]); - if ( argc > offset + 6 ) - decay = (long long)atof(argv[offset + 6]); - rpcport = 1 + komodo_calcport(argv[offset + 1],supply,endsubsidy,reward,halving,decay,commission,staked,cc); - LogPrintf("./komodod -ac_name=%s -ac_cc=%u -ac_supply=%llu -ac_end=%llu -ac_reward=%llu -ac_halving=%llu -ac_decay=%llu & # rpcport %u\n[",argv[offset + 1],cc,(long long)supply,(long long)endsubsidy,(long long)reward,(long long)halving,(long long)decay,rpcport); - if ( allocated != 0 ) - { - char name[64],newname[64]; - strcpy(name,argv[offset + 1]); - allocated[rpcport] = 1; - allocated[rpcport-1] = 1; - for (i=0; i Date: Tue, 13 Sep 2022 03:08:02 +0200 Subject: [PATCH 18/27] get rid of LibTomCrypt derived hash implementations --- src/Makefile.ktest.include | 3 +- src/komodo_utils.cpp | 636 +---------------------- src/test-komodo/test_oldhash_removal.cpp | 468 +++++++++++++++++ 3 files changed, 471 insertions(+), 636 deletions(-) create mode 100644 src/test-komodo/test_oldhash_removal.cpp diff --git a/src/Makefile.ktest.include b/src/Makefile.ktest.include index 0d8a185d..bbba1a42 100644 --- a/src/Makefile.ktest.include +++ b/src/Makefile.ktest.include @@ -19,7 +19,8 @@ komodo_test_SOURCES = \ test-komodo/test_netbase_tests.cpp \ test-komodo/test_events.cpp \ test-komodo/test_hex.cpp \ - test-komodo/test_haraka_removal.cpp + test-komodo/test_haraka_removal.cpp \ + test-komodo/test_oldhash_removal.cpp komodo_test_CPPFLAGS = $(komodod_CPPFLAGS) diff --git a/src/komodo_utils.cpp b/src/komodo_utils.cpp index 456fedd2..f79ab25d 100644 --- a/src/komodo_utils.cpp +++ b/src/komodo_utils.cpp @@ -22,249 +22,8 @@ #include "cc/CCinclude.h" -// todo remove -//struct komodo_state KOMODO_STATES[34]; -//int32_t ASSETCHAINS_CBMATURITY; -//uint64_t ASSETCHAINS_TIMEUNLOCKFROM = 0; -//uint64_t ASSETCHAINS_TIMEUNLOCKTO = 0; - -struct sha256_vstate { uint64_t length; uint32_t state[8],curlen; uint8_t buf[64]; }; - -// following is ported from libtom - -#define STORE32L(x, y) \ -{ (y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \ -(y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); } - -#define LOAD32L(x, y) \ -{ x = (uint32_t)(((uint64_t)((y)[3] & 255)<<24) | \ -((uint32_t)((y)[2] & 255)<<16) | \ -((uint32_t)((y)[1] & 255)<<8) | \ -((uint32_t)((y)[0] & 255))); } - -#define STORE64L(x, y) \ -{ (y)[7] = (uint8_t)(((x)>>56)&255); (y)[6] = (uint8_t)(((x)>>48)&255); \ -(y)[5] = (uint8_t)(((x)>>40)&255); (y)[4] = (uint8_t)(((x)>>32)&255); \ -(y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \ -(y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); } - -#define LOAD64L(x, y) \ -{ x = (((uint64_t)((y)[7] & 255))<<56)|(((uint64_t)((y)[6] & 255))<<48)| \ -(((uint64_t)((y)[5] & 255))<<40)|(((uint64_t)((y)[4] & 255))<<32)| \ -(((uint64_t)((y)[3] & 255))<<24)|(((uint64_t)((y)[2] & 255))<<16)| \ -(((uint64_t)((y)[1] & 255))<<8)|(((uint64_t)((y)[0] & 255))); } - -#define STORE32H(x, y) \ -{ (y)[0] = (uint8_t)(((x)>>24)&255); (y)[1] = (uint8_t)(((x)>>16)&255); \ -(y)[2] = (uint8_t)(((x)>>8)&255); (y)[3] = (uint8_t)((x)&255); } - -#define LOAD32H(x, y) \ -{ x = (uint32_t)(((uint64_t)((y)[0] & 255)<<24) | \ -((uint32_t)((y)[1] & 255)<<16) | \ -((uint32_t)((y)[2] & 255)<<8) | \ -((uint32_t)((y)[3] & 255))); } - -#define STORE64H(x, y) \ -{ (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255); \ -(y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255); \ -(y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255); \ -(y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); } - -#define LOAD64H(x, y) \ -{ x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ -(((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ -(((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ -(((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } - -// Various logical functions -#define RORc(x, y) ( ((((uint32_t)(x)&0xFFFFFFFFUL)>>(uint32_t)((y)&31)) | ((uint32_t)(x)<<(uint32_t)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) -#define S(x, n) RORc((x),(n)) -#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) -#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) -#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) -#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) -#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) -#define MIN(x, y) ( ((x)<(y))?(x):(y) ) - -static inline int32_t sha256_vcompress(struct sha256_vstate * md,uint8_t *buf) -{ - uint32_t S[8],W[64],t0,t1,i; - for (i=0; i<8; i++) // copy state into S - S[i] = md->state[i]; - for (i=0; i<16; i++) // copy the state into 512-bits into W[0..15] - LOAD32H(W[i],buf + (4*i)); - for (i=16; i<64; i++) // fill W[16..63] - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - -#define RND(a,b,c,d,e,f,g,h,i,ki) \ -t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ -t1 = Sigma0(a) + Maj(a, b, c); \ -d += t0; \ -h = t0 + t1; - - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); -#undef RND - for (i=0; i<8; i++) // feedback - md->state[i] = md->state[i] + S[i]; - return(0); -} - -#undef RORc -#undef Ch -#undef Maj -#undef S -#undef R -#undef Sigma0 -#undef Sigma1 -#undef Gamma0 -#undef Gamma1 - -static inline int32_t sha256_vdone(struct sha256_vstate *md,uint8_t *out) -{ - int32_t i; - if ( md->curlen >= sizeof(md->buf) ) - return(-1); - md->length += md->curlen * 8; // increase the length of the message - md->buf[md->curlen++] = (uint8_t)0x80; // append the '1' bit - // if len > 56 bytes we append zeros then compress. Then we can fall back to padding zeros and length encoding like normal. - if ( md->curlen > 56 ) - { - while ( md->curlen < 64 ) - md->buf[md->curlen++] = (uint8_t)0; - sha256_vcompress(md,md->buf); - md->curlen = 0; - } - while ( md->curlen < 56 ) // pad upto 56 bytes of zeroes - md->buf[md->curlen++] = (uint8_t)0; - STORE64H(md->length,md->buf+56); // store length - sha256_vcompress(md,md->buf); - for (i=0; i<8; i++) // copy output - STORE32H(md->state[i],out+(4*i)); - return(0); -} - -static inline int32_t sha256_vprocess(struct sha256_vstate *md,const uint8_t *in,uint64_t inlen) -{ - uint64_t n; int32_t err; - if ( md->curlen > sizeof(md->buf) ) - return(-1); - while ( inlen > 0 ) - { - if ( md->curlen == 0 && inlen >= 64 ) - { - if ( (err= sha256_vcompress(md,(uint8_t *)in)) != 0 ) - return(err); - md->length += 64 * 8, in += 64, inlen -= 64; - } - else - { - n = MIN(inlen,64 - md->curlen); - memcpy(md->buf + md->curlen,in,(size_t)n); - md->curlen += n, in += n, inlen -= n; - if ( md->curlen == 64 ) - { - if ( (err= sha256_vcompress(md,md->buf)) != 0 ) - return(err); - md->length += 8*64; - md->curlen = 0; - } - } - } - return(0); -} - -static inline void sha256_vinit(struct sha256_vstate * md) -{ - md->curlen = 0; - md->length = 0; - md->state[0] = 0x6A09E667UL; - md->state[1] = 0xBB67AE85UL; - md->state[2] = 0x3C6EF372UL; - md->state[3] = 0xA54FF53AUL; - md->state[4] = 0x510E527FUL; - md->state[5] = 0x9B05688CUL; - md->state[6] = 0x1F83D9ABUL; - md->state[7] = 0x5BE0CD19UL; -} - void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len) { - /* - struct sha256_vstate md; - sha256_vinit(&md); - sha256_vprocess(&md,src,len); - sha256_vdone(&md,hash); - */ - - // we will use CSHA256 class instead of above implementation, - // in case if daemon compiled with USE_ASM enabled it will use - // hardware (SSE4) implementation, otherwise standart - CSHA256().Write((const unsigned char *)src, len).Finalize(hash); } @@ -278,397 +37,6 @@ bits256 bits256_doublesha256(char *deprecated,uint8_t *data,int32_t datalen) return(hash); } -// rmd160: the five basic functions F(), G() and H() -#define F(x, y, z) ((x) ^ (y) ^ (z)) -#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define H(x, y, z) (((x) | ~(y)) ^ (z)) -#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define J(x, y, z) ((x) ^ ((y) | ~(z))) -#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) - -/* the ten basic operations FF() through III() */ -#define FF(a, b, c, d, e, x, s) \ -(a) += F((b), (c), (d)) + (x);\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define GG(a, b, c, d, e, x, s) \ -(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define HH(a, b, c, d, e, x, s) \ -(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define II(a, b, c, d, e, x, s) \ -(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define JJ(a, b, c, d, e, x, s) \ -(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define FFF(a, b, c, d, e, x, s) \ -(a) += F((b), (c), (d)) + (x);\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define GGG(a, b, c, d, e, x, s) \ -(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define HHH(a, b, c, d, e, x, s) \ -(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define III(a, b, c, d, e, x, s) \ -(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -#define JJJ(a, b, c, d, e, x, s) \ -(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ -(a) = ROLc((a), (s)) + (e);\ -(c) = ROLc((c), 10); - -static int32_t rmd160_vcompress(struct rmd160_vstate *md,uint8_t *buf) -{ - uint32_t aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16]; - int i; - - /* load words X */ - for (i = 0; i < 16; i++){ - LOAD32L(X[i], buf + (4 * i)); - } - - /* load state */ - aa = aaa = md->state[0]; - bb = bbb = md->state[1]; - cc = ccc = md->state[2]; - dd = ddd = md->state[3]; - ee = eee = md->state[4]; - - /* round 1 */ - FF(aa, bb, cc, dd, ee, X[ 0], 11); - FF(ee, aa, bb, cc, dd, X[ 1], 14); - FF(dd, ee, aa, bb, cc, X[ 2], 15); - FF(cc, dd, ee, aa, bb, X[ 3], 12); - FF(bb, cc, dd, ee, aa, X[ 4], 5); - FF(aa, bb, cc, dd, ee, X[ 5], 8); - FF(ee, aa, bb, cc, dd, X[ 6], 7); - FF(dd, ee, aa, bb, cc, X[ 7], 9); - FF(cc, dd, ee, aa, bb, X[ 8], 11); - FF(bb, cc, dd, ee, aa, X[ 9], 13); - FF(aa, bb, cc, dd, ee, X[10], 14); - FF(ee, aa, bb, cc, dd, X[11], 15); - FF(dd, ee, aa, bb, cc, X[12], 6); - FF(cc, dd, ee, aa, bb, X[13], 7); - FF(bb, cc, dd, ee, aa, X[14], 9); - FF(aa, bb, cc, dd, ee, X[15], 8); - - /* round 2 */ - GG(ee, aa, bb, cc, dd, X[ 7], 7); - GG(dd, ee, aa, bb, cc, X[ 4], 6); - GG(cc, dd, ee, aa, bb, X[13], 8); - GG(bb, cc, dd, ee, aa, X[ 1], 13); - GG(aa, bb, cc, dd, ee, X[10], 11); - GG(ee, aa, bb, cc, dd, X[ 6], 9); - GG(dd, ee, aa, bb, cc, X[15], 7); - GG(cc, dd, ee, aa, bb, X[ 3], 15); - GG(bb, cc, dd, ee, aa, X[12], 7); - GG(aa, bb, cc, dd, ee, X[ 0], 12); - GG(ee, aa, bb, cc, dd, X[ 9], 15); - GG(dd, ee, aa, bb, cc, X[ 5], 9); - GG(cc, dd, ee, aa, bb, X[ 2], 11); - GG(bb, cc, dd, ee, aa, X[14], 7); - GG(aa, bb, cc, dd, ee, X[11], 13); - GG(ee, aa, bb, cc, dd, X[ 8], 12); - - /* round 3 */ - HH(dd, ee, aa, bb, cc, X[ 3], 11); - HH(cc, dd, ee, aa, bb, X[10], 13); - HH(bb, cc, dd, ee, aa, X[14], 6); - HH(aa, bb, cc, dd, ee, X[ 4], 7); - HH(ee, aa, bb, cc, dd, X[ 9], 14); - HH(dd, ee, aa, bb, cc, X[15], 9); - HH(cc, dd, ee, aa, bb, X[ 8], 13); - HH(bb, cc, dd, ee, aa, X[ 1], 15); - HH(aa, bb, cc, dd, ee, X[ 2], 14); - HH(ee, aa, bb, cc, dd, X[ 7], 8); - HH(dd, ee, aa, bb, cc, X[ 0], 13); - HH(cc, dd, ee, aa, bb, X[ 6], 6); - HH(bb, cc, dd, ee, aa, X[13], 5); - HH(aa, bb, cc, dd, ee, X[11], 12); - HH(ee, aa, bb, cc, dd, X[ 5], 7); - HH(dd, ee, aa, bb, cc, X[12], 5); - - /* round 4 */ - II(cc, dd, ee, aa, bb, X[ 1], 11); - II(bb, cc, dd, ee, aa, X[ 9], 12); - II(aa, bb, cc, dd, ee, X[11], 14); - II(ee, aa, bb, cc, dd, X[10], 15); - II(dd, ee, aa, bb, cc, X[ 0], 14); - II(cc, dd, ee, aa, bb, X[ 8], 15); - II(bb, cc, dd, ee, aa, X[12], 9); - II(aa, bb, cc, dd, ee, X[ 4], 8); - II(ee, aa, bb, cc, dd, X[13], 9); - II(dd, ee, aa, bb, cc, X[ 3], 14); - II(cc, dd, ee, aa, bb, X[ 7], 5); - II(bb, cc, dd, ee, aa, X[15], 6); - II(aa, bb, cc, dd, ee, X[14], 8); - II(ee, aa, bb, cc, dd, X[ 5], 6); - II(dd, ee, aa, bb, cc, X[ 6], 5); - II(cc, dd, ee, aa, bb, X[ 2], 12); - - /* round 5 */ - JJ(bb, cc, dd, ee, aa, X[ 4], 9); - JJ(aa, bb, cc, dd, ee, X[ 0], 15); - JJ(ee, aa, bb, cc, dd, X[ 5], 5); - JJ(dd, ee, aa, bb, cc, X[ 9], 11); - JJ(cc, dd, ee, aa, bb, X[ 7], 6); - JJ(bb, cc, dd, ee, aa, X[12], 8); - JJ(aa, bb, cc, dd, ee, X[ 2], 13); - JJ(ee, aa, bb, cc, dd, X[10], 12); - JJ(dd, ee, aa, bb, cc, X[14], 5); - JJ(cc, dd, ee, aa, bb, X[ 1], 12); - JJ(bb, cc, dd, ee, aa, X[ 3], 13); - JJ(aa, bb, cc, dd, ee, X[ 8], 14); - JJ(ee, aa, bb, cc, dd, X[11], 11); - JJ(dd, ee, aa, bb, cc, X[ 6], 8); - JJ(cc, dd, ee, aa, bb, X[15], 5); - JJ(bb, cc, dd, ee, aa, X[13], 6); - - /* parallel round 1 */ - JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); - JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); - JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); - JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); - JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); - JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); - JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); - JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); - JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); - JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); - JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); - JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); - JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); - JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); - JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); - JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); - - /* parallel round 2 */ - III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); - III(ddd, eee, aaa, bbb, ccc, X[11], 13); - III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); - III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); - III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); - III(eee, aaa, bbb, ccc, ddd, X[13], 8); - III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); - III(ccc, ddd, eee, aaa, bbb, X[10], 11); - III(bbb, ccc, ddd, eee, aaa, X[14], 7); - III(aaa, bbb, ccc, ddd, eee, X[15], 7); - III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); - III(ddd, eee, aaa, bbb, ccc, X[12], 7); - III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); - III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); - III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); - III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); - - /* parallel round 3 */ - HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); - HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); - HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); - HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); - HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); - HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); - HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); - HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); - HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); - HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); - HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); - HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); - HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); - HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); - HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); - HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); - - /* parallel round 4 */ - GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); - GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); - GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); - GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); - GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); - GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); - GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); - GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); - GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); - GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); - GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); - GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); - GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); - GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); - GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); - GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); - - /* parallel round 5 */ - FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); - FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); - FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); - FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); - FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); - FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); - FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); - FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); - FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); - FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); - FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); - FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); - FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); - FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); - FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); - FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); - - /* combine results */ - ddd += cc + md->state[1]; /* final result for md->state[0] */ - md->state[1] = md->state[2] + dd + eee; - md->state[2] = md->state[3] + ee + aaa; - md->state[3] = md->state[4] + aa + bbb; - md->state[4] = md->state[0] + bb + ccc; - md->state[0] = ddd; - - return 0; -} - -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return 0 if successful - */ -int rmd160_vinit(struct rmd160_vstate * md) -{ - md->state[0] = 0x67452301UL; - md->state[1] = 0xefcdab89UL; - md->state[2] = 0x98badcfeUL; - md->state[3] = 0x10325476UL; - md->state[4] = 0xc3d2e1f0UL; - md->curlen = 0; - md->length = 0; - return 0; -} - -/** - Process a block of memory though the hash - @param md The hash state - @param in The data to hash - @param inlen The length of the data (octets) - @return 0 if successful - */ -int rmd160_vprocess (struct rmd160_vstate * md, const unsigned char *in, unsigned long inlen) -{ - unsigned long n; - int err; - if (md->curlen > sizeof(md->buf)) { - return -1; - } - while (inlen > 0) { - if (md->curlen == 0 && inlen >= 64) { - if ((err = rmd160_vcompress (md, (unsigned char *)in)) != 0) { - return err; - } - md->length += 64 * 8; - in += 64; - inlen -= 64; - } else { - n = MIN(inlen, (64 - md->curlen)); - memcpy(md->buf + md->curlen, in, (size_t)n); - md->curlen += n; - in += n; - inlen -= n; - if (md->curlen == 64) { - if ((err = rmd160_vcompress (md, md->buf)) != 0) { - return err; - } - md->length += 8*64; - md->curlen = 0; - } - } - } - return 0; -} - -/** - Terminate the hash to get the digest - @param md The hash state - @param out [out] The destination of the hash (20 bytes) - @return 0 if successful - */ -int rmd160_vdone(struct rmd160_vstate * md, unsigned char *out) -{ - int i; - if (md->curlen >= sizeof(md->buf)) { - return -1; - } - /* increase the length of the message */ - md->length += md->curlen * 8; - - /* append the '1' bit */ - md->buf[md->curlen++] = (unsigned char)0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md->curlen > 56) { - while (md->curlen < 64) { - md->buf[md->curlen++] = (unsigned char)0; - } - rmd160_vcompress(md, md->buf); - md->curlen = 0; - } - /* pad upto 56 bytes of zeroes */ - while (md->curlen < 56) { - md->buf[md->curlen++] = (unsigned char)0; - } - /* store length */ - STORE64L(md->length, md->buf+56); - rmd160_vcompress(md, md->buf); - /* copy output */ - for (i = 0; i < 5; i++) { - STORE32L(md->state[i], out+(4*i)); - } - return 0; -} - -void calc_rmd160(char deprecated[41],uint8_t buf[20],uint8_t *msg,int32_t len) -{ - struct rmd160_vstate md; - rmd160_vinit(&md); - rmd160_vprocess(&md,msg,len); - rmd160_vdone(&md, buf); -} -#undef F -#undef G -#undef H -#undef I -#undef J -#undef ROLc -#undef FF -#undef GG -#undef HH -#undef II -#undef JJ -#undef FFF -#undef GGG -#undef HHH -#undef III -#undef JJJ - static const uint32_t crc32_tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, @@ -730,9 +98,7 @@ uint32_t calc_crc32(uint32_t crc,const void *buf,size_t size) void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen) { - bits256 hash; - vcalc_sha256(0,hash.bytes,data,datalen); - calc_rmd160(0,rmd160,hash.bytes,sizeof(hash)); + CHash160().Write((const unsigned char *)data, datalen).Finalize(rmd160); // SHA-256 + RIPEMD-160 } int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],const char *coinaddr) diff --git a/src/test-komodo/test_oldhash_removal.cpp b/src/test-komodo/test_oldhash_removal.cpp new file mode 100644 index 00000000..624419f5 --- /dev/null +++ b/src/test-komodo/test_oldhash_removal.cpp @@ -0,0 +1,468 @@ +#include +#include "komodo_utils.h" +#include +#include "hash.h" +#include "random.h" + +namespace TestOldHashRemoval { + + /* old rmd160 implementation derived from LibTomCrypt */ + + #define MIN(x, y) ( ((x)<(y))?(x):(y) ) + + #define STORE32L(x, y) \ + { (y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \ + (y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); } + + #define LOAD32L(x, y) \ + { x = (uint32_t)(((uint64_t)((y)[3] & 255)<<24) | \ + ((uint32_t)((y)[2] & 255)<<16) | \ + ((uint32_t)((y)[1] & 255)<<8) | \ + ((uint32_t)((y)[0] & 255))); } + + #define STORE64L(x, y) \ + { (y)[7] = (uint8_t)(((x)>>56)&255); (y)[6] = (uint8_t)(((x)>>48)&255); \ + (y)[5] = (uint8_t)(((x)>>40)&255); (y)[4] = (uint8_t)(((x)>>32)&255); \ + (y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \ + (y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); } + + // rmd160: the five basic functions F(), G() and H() + #define F(x, y, z) ((x) ^ (y) ^ (z)) + #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) + #define H(x, y, z) (((x) | ~(y)) ^ (z)) + #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) + #define J(x, y, z) ((x) ^ ((y) | ~(z))) + #define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) + + /* the ten basic operations FF() through III() */ + #define FF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + #define GG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + #define HH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + #define II(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + #define JJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + #define FFF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + #define GGG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + #define HHH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + #define III(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + #define JJJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + static int32_t rmd160_vcompress(struct rmd160_vstate *md,uint8_t *buf) + { + uint32_t aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = aaa = md->state[0]; + bb = bbb = md->state[1]; + cc = ccc = md->state[2]; + dd = ddd = md->state[3]; + ee = eee = md->state[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + /* combine results */ + ddd += cc + md->state[1]; /* final result for md->state[0] */ + md->state[1] = md->state[2] + dd + eee; + md->state[2] = md->state[3] + ee + aaa; + md->state[3] = md->state[4] + aa + bbb; + md->state[4] = md->state[0] + bb + ccc; + md->state[0] = ddd; + + return 0; + } + + /** + Initialize the hash state + @param md The hash state you wish to initialize + @return 0 if successful + */ + int rmd160_vinit(struct rmd160_vstate * md) + { + md->state[0] = 0x67452301UL; + md->state[1] = 0xefcdab89UL; + md->state[2] = 0x98badcfeUL; + md->state[3] = 0x10325476UL; + md->state[4] = 0xc3d2e1f0UL; + md->curlen = 0; + md->length = 0; + return 0; + } + + /** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return 0 if successful + */ + int rmd160_vprocess (struct rmd160_vstate * md, const unsigned char *in, unsigned long inlen) + { + unsigned long n; + int err; + if (md->curlen > sizeof(md->buf)) { + return -1; + } + while (inlen > 0) { + if (md->curlen == 0 && inlen >= 64) { + if ((err = rmd160_vcompress (md, (unsigned char *)in)) != 0) { + return err; + } + md->length += 64 * 8; + in += 64; + inlen -= 64; + } else { + n = MIN(inlen, (64 - md->curlen)); + memcpy(md->buf + md->curlen, in, (size_t)n); + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == 64) { + if ((err = rmd160_vcompress (md, md->buf)) != 0) { + return err; + } + md->length += 8*64; + md->curlen = 0; + } + } + } + return 0; + } + + /** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (20 bytes) + @return 0 if successful + */ + int rmd160_vdone(struct rmd160_vstate * md, unsigned char *out) + { + int i; + if (md->curlen >= sizeof(md->buf)) { + return -1; + } + /* increase the length of the message */ + md->length += md->curlen * 8; + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->curlen > 56) { + while (md->curlen < 64) { + md->buf[md->curlen++] = (unsigned char)0; + } + rmd160_vcompress(md, md->buf); + md->curlen = 0; + } + /* pad upto 56 bytes of zeroes */ + while (md->curlen < 56) { + md->buf[md->curlen++] = (unsigned char)0; + } + /* store length */ + STORE64L(md->length, md->buf+56); + rmd160_vcompress(md, md->buf); + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32L(md->state[i], out+(4*i)); + } + return 0; + } + + void calc_rmd160(char deprecated[41],uint8_t buf[20],uint8_t *msg,int32_t len) + { + struct rmd160_vstate md; + TestOldHashRemoval::rmd160_vinit(&md); + TestOldHashRemoval::rmd160_vprocess(&md, msg, len); + TestOldHashRemoval::rmd160_vdone(&md, buf); + } + + #undef F + #undef G + #undef H + #undef I + #undef J + #undef ROLc + #undef FF + #undef GG + #undef HH + #undef II + #undef JJ + #undef FFF + #undef GGG + #undef HHH + #undef III + #undef JJJ + + void calc_rmd160_sha256_new(uint8_t rmd160[20],uint8_t *data,int32_t datalen) { + CHash160().Write((const unsigned char *)data, datalen).Finalize(rmd160); // SHA-256 + RIPEMD-160 + } + + TEST(TestOldHashRemoval, calc_rmd160) + { + /* test vectors from http://gobittest.appspot.com/Address */ + + uint8_t sha256_hash_1[] = { + 0x60, 0x0f, 0xfe, 0x42, 0x2b, 0x4e, 0x00, 0x73, 0x1a, 0x59, 0x55, 0x7a, 0x5c, 0xca, 0x46, 0xcc, 0x18, 0x39, 0x44, 0x19, 0x10, 0x06, 0x32, 0x4a, 0x44, 0x7b, 0xdb, 0x2d, 0x98, 0xd4, 0xb4, 0x08 }; + uint8_t rmd160_hash_1[] = { + 0x1, 0x9, 0x66, 0x77, 0x60, 0x6, 0x95, 0x3d, 0x55, 0x67, 0x43, 0x9e, 0x5e, 0x39, 0xf8, 0x6a, 0xd, 0x27, 0x3b, 0xee }; + + uint8_t rmd160[20]; + bits256 hash; + + memset(hash.bytes, 0, sizeof(hash)); + memset(rmd160, 0, sizeof(rmd160)); + + memcpy(hash.bytes, sha256_hash_1, sizeof(hash)); + calc_rmd160(0, rmd160, hash.bytes, sizeof(hash)); + EXPECT_EQ(memcmp(rmd160, rmd160_hash_1, sizeof(rmd160)), 0); + + // echo "0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6" | sed 's/../0x&,/g' | tr '[:upper:]' '[:lower:]' + uint8_t public_ecsda[] = { + 0x04, 0x50, 0x86, 0x3a, 0xd6, 0x4a, 0x87, 0xae, 0x8a, 0x2f, 0xe8, 0x3c, 0x1a, 0xf1, 0xa8, 0x40, 0x3c, 0xb5, 0x3f, 0x53, 0xe4, 0x86, 0xd8, 0x51, 0x1d, 0xad, 0x8a, 0x04, 0x88, 0x7e, 0x5b, 0x23, 0x52, 0x2c, 0xd4, 0x70, 0x24, 0x34, 0x53, 0xa2, 0x99, 0xfa, 0x9e, 0x77, 0x23, 0x77, 0x16, 0x10, 0x3a, 0xbc, 0x11, 0xa1, 0xdf, 0x38, 0x85, 0x5e, 0xd6, 0xf2, 0xee, 0x18, 0x7e, 0x9c, 0x58, 0x2b, 0xa6 }; + + memset(rmd160, 0, sizeof(rmd160)); + calc_rmd160_sha256(rmd160,public_ecsda,sizeof(public_ecsda)); + EXPECT_EQ(memcmp(rmd160, rmd160_hash_1, sizeof(rmd160)), 0); + + memset(rmd160, 0, sizeof(rmd160)); + calc_rmd160_sha256_new(rmd160,public_ecsda,sizeof(public_ecsda)); + EXPECT_EQ(memcmp(rmd160, rmd160_hash_1, sizeof(rmd160)), 0); + + for (size_t idx = 0; idx < 64; idx++) { + uint8_t pubkey[33]; + uint8_t rmd160_l[20], rmd160_r[20]; + memset(pubkey, 0, sizeof(pubkey)); + GetRandBytes(pubkey, sizeof(pubkey)); + calc_rmd160_sha256(rmd160_l,pubkey,sizeof(pubkey)); + calc_rmd160_sha256_new(rmd160_r,pubkey,sizeof(pubkey)); + EXPECT_EQ(memcmp(rmd160_l, rmd160_r, 20), 0); + } + + } + +} // namespace TestOldHashRemoval From 74ba7f4961c65247f84d8b6684c0ddd1094e98db Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Tue, 13 Sep 2022 03:33:54 +0200 Subject: [PATCH 19/27] remove cryptoconditions-config.h.in generated by autoheader --- .../src/cryptoconditions-config.h.in | 176 ------------------ 1 file changed, 176 deletions(-) delete mode 100644 src/cryptoconditions/src/cryptoconditions-config.h.in diff --git a/src/cryptoconditions/src/cryptoconditions-config.h.in b/src/cryptoconditions/src/cryptoconditions-config.h.in deleted file mode 100644 index 72f0d216..00000000 --- a/src/cryptoconditions/src/cryptoconditions-config.h.in +++ /dev/null @@ -1,176 +0,0 @@ -/* src/cryptoconditions-config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP - systems. This function is required for `alloca.c' support on those systems. - */ -#undef CRAY_STACKSEG_END - -/* Define to 1 if using `alloca.c'. */ -#undef C_ALLOCA - -/* Define to 1 if you have `alloca', as a function or macro. */ -#undef HAVE_ALLOCA - -/* Define to 1 if you have and it should be used (not on Ultrix). - */ -#undef HAVE_ALLOCA_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_ARPA_INET_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_FLOAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIMITS_H - -/* Define to 1 if you have the `localeconv' function. */ -#undef HAVE_LOCALECONV - -/* Define to 1 if you have the header file. */ -#undef HAVE_LOCALE_H - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#undef HAVE_MALLOC - -/* Define to 1 if you have the header file. */ -#undef HAVE_MALLOC_H - -/* Define to 1 if you have the `memchr' function. */ -#undef HAVE_MEMCHR - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `memset' function. */ -#undef HAVE_MEMSET - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETINET_IN_H - -/* Define to 1 if the system has the type `ptrdiff_t'. */ -#undef HAVE_PTRDIFF_T - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDDEF_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if the system has the type `_Bool'. */ -#undef HAVE__BOOL - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#undef LT_OBJDIR - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at runtime. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -#undef STACK_DIRECTION - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Version number of package */ -#undef VERSION - -/* Define for Solaris 2.5.1 so the uint32_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -#undef _UINT32_T - -/* Define for Solaris 2.5.1 so the uint64_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -#undef _UINT64_T - -/* Define for Solaris 2.5.1 so the uint8_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -#undef _UINT8_T - -/* Define to the type of a signed integer type of width exactly 16 bits if - such a type exists and the standard includes do not define it. */ -#undef int16_t - -/* Define to the type of a signed integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -#undef int32_t - -/* Define to the type of a signed integer type of width exactly 8 bits if such - a type exists and the standard includes do not define it. */ -#undef int8_t - -/* Define to rpl_malloc if the replacement function should be used. */ -#undef malloc - -/* Define to `unsigned int' if does not define. */ -#undef size_t - -/* Define to `int' if does not define. */ -#undef ssize_t - -/* Define to the type of an unsigned integer type of width exactly 16 bits if - such a type exists and the standard includes do not define it. */ -#undef uint16_t - -/* Define to the type of an unsigned integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -#undef uint32_t - -/* Define to the type of an unsigned integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -#undef uint64_t - -/* Define to the type of an unsigned integer type of width exactly 8 bits if - such a type exists and the standard includes do not define it. */ -#undef uint8_t From dd6f484329d9013b026082c44b1b9ba6c3fd3333 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Thu, 15 Sep 2022 02:10:04 +0200 Subject: [PATCH 20/27] fix function(s) invokations after inaccurate merge branches --- src/bitcoind.cpp | 4 +++- src/komodo_bitcoind.cpp | 9 +++++++-- src/main.cpp | 4 ++-- src/miner.cpp | 4 ++-- src/txmempool.cpp | 2 +- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index d26beafb..75105565 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -66,7 +66,9 @@ static bool fDaemon; int32_t komodo_longestchain(); void WaitForShutdown(boost::thread_group* threadGroup) { - int32_t i,height; CBlockIndex *pindex; bool fShutdown = ShutdownRequested(); const uint256 zeroid; + int32_t i,height; CBlockIndex *pindex; bool fShutdown = ShutdownRequested(); + static const uint256 zeroid; //!< null uint256 constant + // Tell the main threads to shutdown. if (komodo_currentheight()>KOMODO_EARLYTXID_HEIGHT && KOMODO_EARLYTXID!=zeroid && ((height=tx_height(KOMODO_EARLYTXID))==0 || height>KOMODO_EARLYTXID_HEIGHT)) { diff --git a/src/komodo_bitcoind.cpp b/src/komodo_bitcoind.cpp index bb43e79b..2d5424aa 100644 --- a/src/komodo_bitcoind.cpp +++ b/src/komodo_bitcoind.cpp @@ -466,7 +466,9 @@ void komodo_reconsiderblock(uint256 blockhash) int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t NOTARIZED_HEIGHT,uint256 NOTARIZED_HASH,uint256 NOTARIZED_DESTTXID) { - char params[256],*jsonstr,*hexstr; uint8_t *script,_script[8192]; int32_t n,len,retval = -1; cJSON *json,*txjson,*vouts,*vout,*skey; + char params[256]; + char *jsonstr = nullptr; + char *hexstr; uint8_t *script,_script[8192]; int32_t n,len,retval = -1; cJSON *json,*txjson,*vouts,*vout,*skey; script = _script; sprintf(params,"[\"%s\", 1]",NOTARIZED_DESTTXID.ToString().c_str()); if ( strcmp(symbol, chainName.ToString().c_str()) != 0 ) @@ -1155,7 +1157,10 @@ uint64_t komodo_commission(const CBlock *pblock,int32_t height) didinit = true; } - int32_t i,j,n=0,txn_count; int64_t nSubsidy; uint64_t commission,total = 0; + int32_t i,j,n=0,txn_count; int64_t nSubsidy; + uint64_t commission = 0; + uint64_t total = 0; + if ( ASSETCHAINS_FOUNDERS != 0 ) { nSubsidy = GetBlockSubsidy(height,Params().GetConsensus()); diff --git a/src/main.cpp b/src/main.cpp index e7c06ecf..0bf993b6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1800,7 +1800,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } auto verifier = libzcash::ProofVerifier::Strict(); if ( chainName.isKMD() && chainActive.Tip() != nullptr - && komodo_validate_interest(tx,chainActive.Tip()->nHeight+1, chainActive.Tip()->GetMedianTimePast() + 777) < 0 ) + && !komodo_validate_interest(tx,chainActive.Tip()->nHeight+1, chainActive.Tip()->GetMedianTimePast() + 777)) { return error("%s: komodo_validate_interest failed txid.%s", __func__, tx.GetHash().ToString()); } @@ -5421,7 +5421,7 @@ bool ContextualCheckBlock(int32_t slowflag,const CBlock& block, CValidationState const CTransaction& tx = block.vtx[i]; // Interest validation - if (komodo_validate_interest(tx, txheight, cmptime) < 0) + if (!komodo_validate_interest(tx, txheight, cmptime)) { LogPrintf("validate intrest failed for txnum.%i tx.%s\n", i, tx.ToString()); return error("%s: komodo_validate_interest failed", __func__); diff --git a/src/miner.cpp b/src/miner.cpp index 07f01ca4..53db0b4e 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -270,7 +270,7 @@ CBlockTemplate* CreateNewBlock(const CPubKey _pk,const CScript& _scriptPubKeyIn, { // too fast or stuck, this addresses the too fast issue, while moving // forward as quickly as possible - for (int i; i < 100; i++) + for (int i = 0; i < 100; i++) { proposedTime = GetTime(); if (proposedTime == nMedianTimePast) @@ -333,7 +333,7 @@ CBlockTemplate* CreateNewBlock(const CPubKey _pk,const CScript& _scriptPubKeyIn, LogPrint("hfnet","%s[%d]: ht.%ld\n", __func__, __LINE__, nHeight); } - if (chainName.isKMD() && komodo_validate_interest(tx, nHeight, cmptime) < 0) + if (chainName.isKMD() && !komodo_validate_interest(tx, nHeight, cmptime)) { LogPrintf("%s: komodo_validate_interest failure txid.%s nHeight.%d nTime.%u vs locktime.%u (cmptime.%lu)\n", __func__, tx.GetHash().ToString(), nHeight, (uint32_t)pblock->nTime, (uint32_t)tx.nLockTime, cmptime); continue; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 82a53388..88760969 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -516,7 +516,7 @@ void CTxMemPool::removeExpired(unsigned int nBlockHeight) bool fInterestNotValidated = chainName.isKMD() && tipindex != 0 - && komodo_validate_interest(tx,tipindex->nHeight+1,tipindex->GetMedianTimePast() + 777) < 0; + && !komodo_validate_interest(tx,tipindex->nHeight+1,tipindex->GetMedianTimePast() + 777); if (IsExpiredTx(tx, nBlockHeight) || fInterestNotValidated) { if (fInterestNotValidated && tipindex != 0) From 3269d5b72e067a06f1d89aee035549a8e7620704 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Thu, 15 Sep 2022 02:54:41 +0200 Subject: [PATCH 21/27] fix treating std as a label, name it's a variable of std::string type --- src/bitcoin-cli.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 31e0979c..8f613f92 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -97,7 +97,7 @@ static int AppInitRPC(int argc, char* argv[]) // Parameters // ParseParameters(argc, argv); - std:string name = GetArg("-ac_name",""); + std::string name = GetArg("-ac_name",""); if ( !name.empty() ) chainName = assetchain(name); From ba3a0592d548a27501bb2e942915e17ac6ee5536 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 16 Sep 2022 15:04:02 +0200 Subject: [PATCH 22/27] more pegs, hush, marmara code removed backport of https://github.com/dimxy/komodo/pull/129 to our codebase. --- src/cc/CCinclude.h | 1 - src/cc/CCtokens.cpp | 4 -- src/cc/import.cpp | 12 +---- src/cc/oracles.cpp | 4 +- src/coins.cpp | 8 +--- src/importcoin.cpp | 85 +----------------------------------- src/importcoin.h | 41 ----------------- src/komodo_bitcoind.cpp | 36 --------------- src/komodo_extern_globals.h | 1 - src/komodo_globals.cpp | 2 +- src/komodo_globals.h | 1 - src/komodo_utils.cpp | 9 ---- src/main.cpp | 27 +++--------- src/miner.cpp | 7 --- src/primitives/transaction.h | 5 --- src/rpc/crosschain.cpp | 8 ---- src/rpc/server.cpp | 5 +-- src/tui/README.md | 8 +--- src/tui/tui_marmara.py | 68 ----------------------------- src/txmempool.cpp | 5 +-- 20 files changed, 17 insertions(+), 320 deletions(-) delete mode 100755 src/tui/tui_marmara.py diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index e06abe66..4e7e3f18 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -98,7 +98,6 @@ enum opretid : uint8_t { OPRETID_CHANNELSDATA = 0x14, //!< channels contract data id OPRETID_HEIRDATA = 0x15, //!< heir contract data id OPRETID_ROGUEGAMEDATA = 0x16, //!< rogue contract data id - OPRETID_PEGSDATA = 0x17, //!< pegs contract data id /*! \cond INTERNAL */ // non cc contract data: diff --git a/src/cc/CCtokens.cpp b/src/cc/CCtokens.cpp index 1266f9cd..0207e575 100644 --- a/src/cc/CCtokens.cpp +++ b/src/cc/CCtokens.cpp @@ -402,15 +402,11 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys /*<--not used, always true struct CCcontract_info *cpEvalCode1,CEvalCode1; cpEvalCode1 = CCinit(&CEvalCode1,evalCode1); CPubKey pk=GetUnspendable(cpEvalCode1,0); - testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode1, tx.vout[v].nValue, voutPubkeys[0], pk), std::string("dual-eval1 pegscc cc1of2 pk[0] globalccpk")) ); - if (voutPubkeys.size() == 2) testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode1, tx.vout[v].nValue, voutPubkeys[1], pk), std::string("dual-eval1 pegscc cc1of2 pk[1] globalccpk")) ); if (evalCode2!=0) { struct CCcontract_info *cpEvalCode2,CEvalCode2; cpEvalCode2 = CCinit(&CEvalCode2,evalCode2); CPubKey pk=GetUnspendable(cpEvalCode2,0); - testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode2, tx.vout[v].nValue, voutPubkeys[0], pk), std::string("dual-eval2 pegscc cc1of2 pk[0] globalccpk")) ); - if (voutPubkeys.size() == 2) testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode2, tx.vout[v].nValue, voutPubkeys[1], pk), std::string("dual-eval2 pegscc cc1of2 pk[1] globalccpk")) ); } // maybe it is single-eval or dual/three-eval token change? diff --git a/src/cc/import.cpp b/src/cc/import.cpp index 58b64a70..5038ed57 100644 --- a/src/cc/import.cpp +++ b/src/cc/import.cpp @@ -624,9 +624,6 @@ bool Eval::ImportCoin(const std::vector params, const CTransaction &imp LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "Validating import tx..., txid=" << importTx.GetHash().GetHex() << std::endl); - if ( chainName.isSymbol("CFEKDIMXY6") && chainActive.Height() <= 44693) - return true; - if (importTx.vout.size() < 2) return Invalid("too-few-vouts"); @@ -635,7 +632,7 @@ bool Eval::ImportCoin(const std::vector params, const CTransaction &imp return Invalid("invalid-params"); // Control all aspects of this transaction // It should not be at all malleable - if (ASSETCHAINS_SELFIMPORT!="PEGSCC" && MakeImportCoinTransaction(proof, burnTx, payouts, importTx.nExpiryHeight).GetHash() != importTx.GetHash()) // ExistsImportTombstone prevents from duplication + if (MakeImportCoinTransaction(proof, burnTx, payouts, importTx.nExpiryHeight).GetHash() != importTx.GetHash()) // ExistsImportTombstone prevents from duplication return Invalid("non-canonical"); // burn params @@ -693,13 +690,6 @@ bool Eval::ImportCoin(const std::vector params, const CTransaction &imp else if ( UnmarshalBurnTx(burnTx,srcaddr,receipt)==0 || CheckCODAimport(importTx,burnTx,payouts,srcaddr,receipt) < 0 ) return Invalid("CODA-import-failure"); } - else if ( targetSymbol == "PEGSCC" ) - { - if ( ASSETCHAINS_SELFIMPORT != "PEGSCC" ) - return Invalid("PEGSCC-import-when-not PEGSCC"); - // else if ( CheckPUBKEYimport(merkleBranchProof,rawproof,burnTx,payouts) < 0 ) - // return Invalid("PEGSCC-import-failure"); - } else if ( targetSymbol == "PUBKEY" ) { if ( ASSETCHAINS_SELFIMPORT != "PUBKEY" ) diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp index 1db6e531..63396b26 100644 --- a/src/cc/oracles.cpp +++ b/src/cc/oracles.cpp @@ -1125,7 +1125,7 @@ UniValue OracleDataSamples(uint256 reforacletxid,char* batonaddr,int32_t num) } } else - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex()); + CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex()); } else CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex()); @@ -1200,7 +1200,7 @@ UniValue OracleInfo(uint256 origtxid) result.push_back(Pair("registered",a)); } else - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex()); + CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex()); } else CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex()); diff --git a/src/coins.cpp b/src/coins.cpp index ee052218..22764f10 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -599,11 +599,6 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t &interestp,const CTr return 0; for (unsigned int i = 0; i < tx.vin.size(); i++) { - if (tx.IsPegsImport() && i==0) - { - nResult = GetCoinImportValue(tx); - continue; - } value = GetOutputFor(tx.vin[i]).nValue; nResult += value; #ifdef KOMODO_ENABLE_INTEREST @@ -676,7 +671,6 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const { if (!tx.IsMint()) { for (unsigned int i = 0; i < tx.vin.size(); i++) { - if (tx.IsPegsImport() && i==0) continue; const COutPoint &prevout = tx.vin[i].prevout; const CCoins* coins = AccessCoins(prevout.hash); if (!coins || !coins->IsAvailable(prevout.n)) { @@ -698,7 +692,7 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const // use the maximum priority for all (partially or fully) shielded transactions. // (Note that coinbase transactions cannot contain JoinSplits, or Sapling shielded Spends or Outputs.) - if (tx.vjoinsplit.size() > 0 || tx.vShieldedSpend.size() > 0 || tx.vShieldedOutput.size() > 0 || tx.IsCoinImport() || tx.IsPegsImport()) { + if (tx.vjoinsplit.size() > 0 || tx.vShieldedSpend.size() > 0 || tx.vShieldedOutput.size() > 0 || tx.IsCoinImport()) { return MAX_PRIORITY; } diff --git a/src/importcoin.cpp b/src/importcoin.cpp index e55551f2..93ccba82 100644 --- a/src/importcoin.cpp +++ b/src/importcoin.cpp @@ -81,25 +81,6 @@ CTransaction MakeImportCoinTransaction(const ImportProof proof, const CTransacti return CTransaction(mtx); } -/***** - * @brief makes import tx that includes spending markers to track account state - * @param proof - * @param burnTx - * @param payouts - * @param nExpiryHeighOverride - * @returns the transaction - */ -CTransaction MakePegsImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, - const std::vector payouts, uint32_t nExpiryHeightOverride) -{ - CMutableTransaction mtx=MakeImportCoinTransaction(proof,burnTx,payouts); - // for spending markers in import tx - to track account state - uint256 accounttxid = burnTx.vin[0].prevout.hash; - mtx.vin.push_back(CTxIn(accounttxid,0,CScript())); - mtx.vin.push_back(CTxIn(accounttxid,1,CScript())); - return (mtx); -} - /****** * @brief make a burn output * @param value the amount @@ -189,38 +170,6 @@ CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string& tar return CTxOut(value, CScript() << OP_RETURN << opret); } -/****** - * @brief make a burn output - * @param value the amount - * @param targetCCid the ccid - * @param targetSymbol - * @param payouts the outputs - * @param rawproof the proof in binary form - * @param pegstxid - * @param tokenid - * @param srcpub - * @param amount - * @param account - * @returns the txout - */ -CTxOut MakeBurnOutput(CAmount value,uint32_t targetCCid, const std::string& targetSymbol, - const std::vector payouts,std::vector rawproof,uint256 pegstxid, - uint256 tokenid,CPubKey srcpub,int64_t amount, std::pair account) -{ - std::vector opret; - opret = E_MARSHAL(ss << (uint8_t)EVAL_IMPORTCOIN; - ss << VARINT(targetCCid); - ss << targetSymbol; - ss << SerializeHash(payouts); - ss << rawproof; - ss << pegstxid; - ss << tokenid; - ss << srcpub; - ss << amount; - ss << account); - return CTxOut(value, CScript() << OP_RETURN << opret); -} - /**** * @brief break a serialized import tx into its components * @param[in] importTx the transaction @@ -235,7 +184,7 @@ bool UnmarshalImportTx(const CTransaction importTx, ImportProof &proof, CTransac if (importTx.vout.size() < 1) return false; - if ((!importTx.IsPegsImport() && importTx.vin.size() != 1) || importTx.vin[0].scriptSig != (CScript() << E_MARSHAL(ss << EVAL_IMPORTCOIN))) { + if ((importTx.vin.size() != 1) || importTx.vin[0].scriptSig != (CScript() << E_MARSHAL(ss << EVAL_IMPORTCOIN))) { LOGSTREAM("importcoin", CCLOG_INFO, stream << "UnmarshalImportTx() incorrect import tx vin" << std::endl); return false; } @@ -412,38 +361,6 @@ bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &bindtxid, ss >> amount)); } -/**** - * @brief break a serialized burn tx into its components - * @param[in] burnTx the transaction - * @param[out] pegstxid - * @param[out] tokenid - * @param[out] srcpub - * @param[out] amount - * @param[out] account - * @returns true on success - */ -bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &pegstxid,uint256 &tokenid,CPubKey &srcpub, - int64_t &amount,std::pair &account) -{ - std::vector burnOpret,rawproof; bool isEof=true; - uint32_t targetCCid; uint256 payoutsHash; std::string targetSymbol; - uint8_t evalCode; - - - if (burnTx.vout.size() == 0) return false; - GetOpReturnData(burnTx.vout.back().scriptPubKey, burnOpret); - return (E_UNMARSHAL(burnOpret, ss >> evalCode; - ss >> VARINT(targetCCid); - ss >> targetSymbol; - ss >> payoutsHash; - ss >> rawproof; - ss >> pegstxid; - ss >> tokenid; - ss >> srcpub; - ss >> amount; - ss >> account)); -} - /****** * @brief get the value of the transaction * @param tx the transaction diff --git a/src/importcoin.h b/src/importcoin.h index 14c7f412..fed69b45 100644 --- a/src/importcoin.h +++ b/src/importcoin.h @@ -139,16 +139,6 @@ CAmount GetCoinImportValue(const CTransaction &tx); */ CTransaction MakeImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector payouts, uint32_t nExpiryHeightOverride = 0); -/***** - * @brief makes import tx for pegs cc - * @param proof the proof - * @param burnTx the inputs - * @param payouts the outputs - * @param nExpiryHeighOverride if an actual height (!= 0) makes a tx for validating int import tx - * @returns the transaction including spending markers for pegs CC - */ -CTransaction MakePegsImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector payouts, uint32_t nExpiryHeightOverride = 0); - /****** * @brief make a burn output * @param value the amount @@ -199,24 +189,6 @@ CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string& tar const std::vector payouts,std::vector rawproof, const std::string& srcaddr, const std::string& receipt); -/****** - * @brief make a burn output - * @param value the amount - * @param targetCCid the ccid - * @param targetSymbol - * @param payouts the outputs - * @param rawproof the proof in binary form - * @param pegstxid - * @param tokenid - * @param srcpub - * @param amount - * @param account - * @returns the txout - */ -CTxOut MakeBurnOutput(CAmount value,uint32_t targetCCid,const std::string& targetSymbol, - const std::vector payouts,std::vector rawproof,uint256 pegstxid, - uint256 tokenid,CPubKey srcpub,int64_t amount,std::pair account); - /**** * @brief break a serialized burn tx into its components * @param[in] burnTx the transaction @@ -256,19 +228,6 @@ bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &bindtxid,std::vector &txids,uint256& burntxid,int32_t &height,int32_t &burnvout, std::string &rawburntx,CPubKey &destpub, int64_t &amount); -/**** - * @brief break a serialized burn tx into its components - * @param[in] burnTx the transaction - * @param[out] pegstxid - * @param[out] tokenid - * @param[out] srcpub - * @param[out] amount - * @param[out] account - * @returns true on success - */ -bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &pegstxid,uint256 &tokenid,CPubKey &srcpub, - int64_t &amount,std::pair &account); - /**** * @brief break a serialized import tx into its components * @param[in] importTx the transaction diff --git a/src/komodo_bitcoind.cpp b/src/komodo_bitcoind.cpp index 2d5424aa..fe96f1f4 100644 --- a/src/komodo_bitcoind.cpp +++ b/src/komodo_bitcoind.cpp @@ -1147,16 +1147,10 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); uint64_t komodo_commission(const CBlock *pblock,int32_t height) { - static bool didinit = false,ishush3 = false; // LABS fungible chains, cannot have any block reward! if ( is_STAKED(chainName.symbol()) == 2 ) return(0); - if (!didinit) { - ishush3 = chainName.SymbolStartsWith("HUSH3"); - didinit = true; - } - int32_t i,j,n=0,txn_count; int64_t nSubsidy; uint64_t commission = 0; uint64_t total = 0; @@ -1167,36 +1161,6 @@ uint64_t komodo_commission(const CBlock *pblock,int32_t height) //LogPrintf("ht.%d nSubsidy %.8f prod %llu\n",height,(double)nSubsidy/COIN,(long long)(nSubsidy * ASSETCHAINS_COMMISSION)); commission = ((nSubsidy * ASSETCHAINS_COMMISSION) / COIN); - if (ishush3) { - int32_t starting_commission = 125000000, HALVING1 = 340000, INTERVAL = 840000, TRANSITION = 129, BR_END = 5422111; - // HUSH supply curve cannot be exactly represented via KMD AC CLI args, so we do it ourselves. - // You specify the BR, and the FR % gets added so 10% of 12.5 is 1.25 - // but to tell the AC params, I need to say "11% of 11.25" is 1.25 - // 11% ie. 1/9th cannot be exactly represented and so the FR has tiny amounts of error unless done manually - // Transition period of 128 blocks has BR=FR=0 - if (height < TRANSITION) { - commission = 0; - } else if (height < HALVING1) { - commission = starting_commission; - } else if (height < HALVING1+1*INTERVAL) { - commission = starting_commission / 2; - } else if (height < HALVING1+2*INTERVAL) { - commission = starting_commission / 4; - } else if (height < HALVING1+3*INTERVAL) { - commission = starting_commission / 8; - } else if (height < HALVING1+4*INTERVAL) { - commission = starting_commission / 16; - } else if (height < HALVING1+5*INTERVAL) { - commission = starting_commission / 32; - } else if (height < HALVING1+6*INTERVAL) { // Block 5380000 - // Block reward will go to zero between 7th+8th halvings, ac_end may need adjusting - commission = starting_commission / 64; - } else if (height < HALVING1+7*INTERVAL) { - // Block reward will be zero before this is ever reached - commission = starting_commission / 128; // Block 6220000 - } - } - if ( ASSETCHAINS_FOUNDERS > 1 ) { if ( (height % ASSETCHAINS_FOUNDERS) == 0 ) diff --git a/src/komodo_extern_globals.h b/src/komodo_extern_globals.h index 13795a8d..772b6544 100644 --- a/src/komodo_extern_globals.h +++ b/src/komodo_extern_globals.h @@ -72,7 +72,6 @@ extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1]; extern uint64_t ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1]; extern uint64_t ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS+1]; extern uint64_t ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS+1]; -extern uint64_t ASSETCHAINS_PEGSCCPARAMS[3]; extern uint64_t ASSETCHAINS_TIMEUNLOCKFROM; extern uint64_t ASSETCHAINS_TIMEUNLOCKTO; diff --git a/src/komodo_globals.cpp b/src/komodo_globals.cpp index c1764add..b7b75e82 100644 --- a/src/komodo_globals.cpp +++ b/src/komodo_globals.cpp @@ -58,7 +58,7 @@ uint64_t ASSETCHAINS_TIMELOCKGTE = _ASSETCHAINS_TIMELOCKOFF; uint64_t ASSETCHAINS_TIMEUNLOCKFROM = 0, ASSETCHAINS_TIMEUNLOCKTO = 0; uint64_t ASSETCHAINS_LASTERA = 1; -uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_PEGSCCPARAMS[3]; +uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS+1]; uint8_t ASSETCHAINS_CCDISABLES[256]; std::vector ASSETCHAINS_PRICES,ASSETCHAINS_STOCKS; diff --git a/src/komodo_globals.h b/src/komodo_globals.h index eb170d8b..49d9e2fa 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -100,7 +100,6 @@ extern uint64_t ASSETCHAINS_TIMELOCKGTE; // set by -ac_timelockgte or consensus extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1]; // can be set by -ac_end, array of heights indexed by era extern uint64_t ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1]; // can be set by -ac_halving extern uint64_t ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS+1]; // can be set by -ac_decay -extern uint64_t ASSETCHAINS_PEGSCCPARAMS[3]; // set by -ac_pegsccparams, used in pegs.cpp extern uint64_t KOMODO_INTERESTSUM; // calculated value, returned in getinfo() RPC call extern uint64_t KOMODO_WALLETBALANCE; // pwalletmain->GetBalance(), returned in getinfo() RPC call extern int64_t ASSETCHAINS_GENESISTXVAL; // used in calculating money supply diff --git a/src/komodo_utils.cpp b/src/komodo_utils.cpp index f79ab25d..f1967ae4 100644 --- a/src/komodo_utils.cpp +++ b/src/komodo_utils.cpp @@ -1287,15 +1287,6 @@ void komodo_args(char *argv0) StartShutdown(); } } - else if ( ASSETCHAINS_SELFIMPORT == "PEGSCC") - { - Split(GetArg("-ac_pegsccparams",""), sizeof(ASSETCHAINS_PEGSCCPARAMS)/sizeof(*ASSETCHAINS_PEGSCCPARAMS), ASSETCHAINS_PEGSCCPARAMS, 0); - if (ASSETCHAINS_ENDSUBSIDY[0]!=1 || ASSETCHAINS_COMMISSION!=0) - { - LogPrintf("when using import for pegsCC these must be set: -ac_end=1 -ac_perc=0\n"); - StartShutdown(); - } - } // else it can be gateway coin else if (!ASSETCHAINS_SELFIMPORT.empty() && (ASSETCHAINS_ENDSUBSIDY[0]!=1 || ASSETCHAINS_SUPPLY>0 || ASSETCHAINS_COMMISSION!=0)) { diff --git a/src/main.cpp b/src/main.cpp index 0bf993b6..878fff93 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -728,7 +728,6 @@ bool komodo_dailysnapshot(int32_t height) for (unsigned int j = tx.vin.size(); j-- > 0;) { uint256 blockhash; CTransaction txin; - if (tx.IsPegsImport() && j==0) continue; if ( !tx.IsCoinImport() && !tx.IsCoinBase() && myGetTransaction(tx.vin[j].prevout.hash,txin,blockhash) ) { int vout = tx.vin[j].prevout.n; @@ -1027,7 +1026,6 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, for (unsigned int i = 0; i < tx.vin.size(); i++) { - if (tx.IsPegsImport() && i==0) continue; const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]); vector > vSolutions; @@ -1105,7 +1103,6 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in unsigned int nSigOps = 0; for (unsigned int i = 0; i < tx.vin.size(); i++) { - if (tx.IsPegsImport() && i==0) continue; const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]); if (prevout.scriptPubKey.IsPayToScriptHash()) nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig); @@ -1892,7 +1889,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return state.Invalid(false, REJECT_DUPLICATE, "already have coins"); } - if (tx.IsCoinImport() || tx.IsPegsImport()) + if (tx.IsCoinImport()) { // Inverse of normal case; if input exists, it's been spent if (ExistsImportTombstone(tx, view)) @@ -1966,7 +1963,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Keep track of transactions that spend a coinbase, which we re-scan // during reorgs to ensure COINBASE_MATURITY is still met. bool fSpendsCoinbase = false; - if (!tx.IsCoinImport() && !tx.IsPegsImport()) { + if (!tx.IsCoinImport()) { BOOST_FOREACH(const CTxIn &txin, tx.vin) { const CCoins *coins = view.AccessCoins(txin.prevout.hash); if (coins->IsCoinBase()) { @@ -2008,7 +2005,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Continuously rate-limit free (really, very-low-fee) transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to // be annoying or make others' transactions take longer to confirm. - if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize) && !tx.IsCoinImport() && !tx.IsPegsImport()) + if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize) && !tx.IsCoinImport()) { static CCriticalSection csFreeLimiter; static double dFreeCount; @@ -2032,7 +2029,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa dFreeCount += nSize; } - if (!tx.IsCoinImport() && !tx.IsPegsImport() && fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19) + if (!tx.IsCoinImport() && fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19) { string errmsg = strprintf("absurdly high fees %s, %d > %d", hash.ToString(), @@ -2704,7 +2701,6 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund { txundo.vprevout.reserve(tx.vin.size()); BOOST_FOREACH(const CTxIn &txin, tx.vin) { - if (tx.IsPegsImport() && txin.prevout.n==10e8) continue; CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash); unsigned nPos = txin.prevout.n; @@ -2728,7 +2724,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs // Unorthodox state - if (tx.IsCoinImport() || tx.IsPegsImport()) { + if (tx.IsCoinImport()) { // add a tombstone for the burnTx AddImportTombstone(tx, inputs, nHeight); } @@ -2772,11 +2768,6 @@ namespace Consensus { CAmount nFees = 0; for (unsigned int i = 0; i < tx.vin.size(); i++) { - if (tx.IsPegsImport() && i==0) - { - nValueIn=GetCoinImportValue(tx); - continue; - } const COutPoint &prevout = tx.vin[i].prevout; const CCoins *coins = inputs.AccessCoins(prevout.hash); assert(coins); @@ -2886,7 +2877,6 @@ bool ContextualCheckInputs( // still computed and checked, and any change will be caught at the next checkpoint. if (fScriptChecks) { for (unsigned int i = 0; i < tx.vin.size(); i++) { - if (tx.IsPegsImport() && i==0) continue; const COutPoint &prevout = tx.vin[i].prevout; const CCoins* coins = inputs.AccessCoins(prevout.hash); assert(coins); @@ -2922,7 +2912,7 @@ bool ContextualCheckInputs( } } - if (tx.IsCoinImport() || tx.IsPegsImport()) + if (tx.IsCoinImport()) { LOCK(cs_main); ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata); @@ -3170,11 +3160,9 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex // restore inputs if (!tx.IsMint()) { CTxUndo &txundo = blockUndo.vtxundo[i-1]; - if (tx.IsPegsImport()) txundo.vprevout.insert(txundo.vprevout.begin(),CTxInUndo()); if (txundo.vprevout.size() != tx.vin.size()) return error("DisconnectBlock(): transaction and undo data inconsistent"); for (unsigned int j = tx.vin.size(); j-- > 0;) { - if (tx.IsPegsImport() && j==0) continue; const COutPoint &out = tx.vin[j].prevout; const CTxInUndo &undo = txundo.vprevout[j]; if (!ApplyTxInUndo(undo, view, out)) @@ -3208,7 +3196,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex } } } - else if (tx.IsCoinImport() || tx.IsPegsImport()) + else if (tx.IsCoinImport()) { RemoveImportTombstone(tx, view); } @@ -3574,7 +3562,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin { for (size_t j = 0; j < tx.vin.size(); j++) { - if (tx.IsPegsImport() && j==0) continue; const CTxIn input = tx.vin[j]; const CTxOut &prevout = view.GetOutputFor(tx.vin[j]); diff --git a/src/miner.cpp b/src/miner.cpp index 53db0b4e..2bd111cf 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -358,13 +358,6 @@ CBlockTemplate* CreateNewBlock(const CPubKey _pk,const CScript& _scriptPubKeyIn, BOOST_FOREACH(const CTxIn& txin, tx.vin) { - if (tx.IsPegsImport() && txin.prevout.n==10e8) - { - CAmount nValueIn = GetCoinImportValue(tx); // burn amount - nTotalIn += nValueIn; - dPriority += (double)nValueIn * 1000; // flat multiplier... max = 1e16. - continue; - } // Read prev transaction if (!view.HaveCoins(txin.prevout.hash)) { diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index f5670eca..1d8afa30 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -720,11 +720,6 @@ class CTransaction return (vin.size() == 1 && vin[0].prevout.n == 10e8); } - bool IsPegsImport() const - { - return (ASSETCHAINS_SELFIMPORT=="PEGSCC" && vin[0].prevout.n == 10e8); - } - friend bool operator==(const CTransaction& a, const CTransaction& b) { return a.hash == b.hash; diff --git a/src/rpc/crosschain.cpp b/src/rpc/crosschain.cpp index f425783c..6141f916 100644 --- a/src/rpc/crosschain.cpp +++ b/src/rpc/crosschain.cpp @@ -732,10 +732,6 @@ UniValue selfimport(const UniValue& params, bool fHelp, const CPubKey& mypk) // return(0); return -1; } - else if (source == "PEGSCC") - { - return -1; - } else if (source == "PUBKEY") { ImportProof proofNull; @@ -815,10 +811,6 @@ UniValue importdual(const UniValue& params, bool fHelp, const CPubKey& mypk) // confirm via ASSETCHAINS_CODAPORT that burnTx/hash is a valid CODA burn // return(0); } - else if (source == "PEGSCC") - { - return -1; - } RETURN_IF_ERROR(CCerror); if ( hex.size() > 0 ) { diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 365afa30..8382485a 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -1,6 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -850,8 +849,6 @@ std::string HelpExampleCli(const std::string& methodname, const std::string& arg { if ( chainName.isKMD() ) { return "> komodo-cli " + methodname + " " + args + "\n"; - } else if ( chainName.SymbolStartsWith("HUSH3") ) { - return "> hush-cli " + methodname + " " + args + "\n"; } else { return "> komodo-cli -ac_name=" + strprintf("%s", chainName.symbol().c_str()) + " " + methodname + " " + args + "\n"; } @@ -865,7 +862,7 @@ std::string HelpExampleRpc(const std::string& methodname, const std::string& arg string experimentalDisabledHelpMsg(const string& rpc, const string& enableArg) { - string daemon = chainName.isKMD() ? "komodod" : "hushd"; + string daemon = "komodod"; string ticker = chainName.isKMD() ? "komodo" : chainName.symbol(); return "\nWARNING: " + rpc + " is disabled.\n" diff --git a/src/tui/README.md b/src/tui/README.md index 61e73379..155ae44d 100644 --- a/src/tui/README.md +++ b/src/tui/README.md @@ -1,6 +1,6 @@ # Komodo Cryptoconditons Terminal User Interfaces (aka TUIs) -These tools creating for demonstration and partial automation of Komodo cryptoconditions modules testing. (RogueCC game, AssetsCC, OraclesCC, GatewaysCC, MarmaraCC, ...) +These tools creating for demonstration and partial automation of Komodo cryptoconditions modules testing. (RogueCC game, AssetsCC, OraclesCC, GatewaysCC, ...) Developer installation (on Ubuntu 18.04) : @@ -42,12 +42,6 @@ Have files uploader/downloader functionality - also there is a AWS branch for AW At the moment raw version of manual gateway how-to guide can be found here: https://docs.komodoplatform.com/cc/contracts/gateways/scenarios/tutorial.html I advice to read it before you start use this tool to understand the flow. -# TUI for MarmaraCC - -`python3 marmara_tui.py` - -![alt text](https://i.imgur.com/uonMWHl.png) - # TUI for AssetsCC (not much finished) `python3 assets_cc_tui.py` diff --git a/src/tui/tui_marmara.py b/src/tui/tui_marmara.py deleted file mode 100755 index cfe62889..00000000 --- a/src/tui/tui_marmara.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python3 - -from lib import rpclib, tuilib -import os -import time - - -header = "\ -___ ___ _____ _ _ _____ \n\ -| \/ | |_ _| | | |_ _|\n\ -| . . | __ _ _ __ _ __ ___ __ _ _ __ __ _ | | | | | | | |\n\ -| |\/| |/ _` | '__| '_ ` _ \ / _` | '__/ _` | | | | | | | | |\n\ -| | | | (_| | | | | | | | | (_| | | | (_| | | | | |_| |_| |_\n\ -\_| |_/\__,_|_| |_| |_| |_|\__,_|_| \__,_| \_/ \___/ \___/\n" - - -menuItems = [ - {"Check current connection": tuilib.getinfo_tui}, - {"Check mempool": tuilib.print_mempool}, - {"Check MARMARA info": tuilib.marmara_info_tui}, - {"Lock funds for MARMARA": tuilib.marmara_lock_tui}, - {"Request MARMARA cheque": tuilib.marmara_receive_tui}, - {"Issue MARMARA cheque": tuilib.marmara_issue_tui}, - {"Check credit loop status": tuilib.marmara_creditloop_tui}, - {"Settle MARMARA loop": tuilib.marmara_settlement_tui}, - {"Exit": exit} -] - - -def main(): - while True: - os.system('clear') - print(tuilib.colorize(header, 'pink')) - print(tuilib.colorize('CLI version 0.1\n', 'green')) - for item in menuItems: - print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) - choice = input(">> ") - try: - if int(choice) < 0: - raise ValueError - # Call the matching function - if list(menuItems[int(choice)].keys())[0] == "Exit": - list(menuItems[int(choice)].values())[0]() - else: - list(menuItems[int(choice)].values())[0](rpc_connection) - except (ValueError, IndexError): - pass - - -if __name__ == "__main__": - while True: - chain = input("Input assetchain name (-ac_name= value) you want to work with: ") - try: - print(tuilib.colorize("Welcome to the MarmaraCC TUI!\n" - "Please provide asset chain RPC connection details for initialization", "blue")) - rpc_connection = tuilib.def_credentials(chain) - rpclib.getinfo(rpc_connection) - except Exception: - print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink")) - else: - print(tuilib.colorize("Succesfully connected!\n", "green")) - with (open("lib/logo.txt", "r")) as logo: - for line in logo: - print(line, end='') - time.sleep(0.04) - print("\n") - break - main() diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 88760969..dee3e819 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -127,7 +127,6 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, if (!tx.IsCoinImport()) { for (unsigned int i = 0; i < tx.vin.size(); i++) { - if (tx.IsPegsImport() && i==0) continue; mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i); } } @@ -155,7 +154,7 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC uint256 txhash = tx.GetHash(); for (unsigned int j = 0; j < tx.vin.size(); j++) { - if (tx.IsPegsImport() && j==0) continue; + const CTxIn input = tx.vin[j]; const CTxOut &prevout = view.GetOutputFor(input); @@ -261,7 +260,7 @@ void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCac uint256 txhash = tx.GetHash(); for (unsigned int j = 0; j < tx.vin.size(); j++) { - if (tx.IsPegsImport() && j==0) continue; + const CTxIn input = tx.vin[j]; const CTxOut &prevout = view.GetOutputFor(input); From d2f32d6284facce16e222f5456707cf607fdf979 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 26 Sep 2022 11:54:09 +0200 Subject: [PATCH 23/27] add komodo_interest_validate, komodo_interest unit tests by dimxy (c) https://github.com/dimxy/komodo/pull/130 --- src/Makefile.ktest.include | 3 +- src/main.cpp | 4 +- src/test-komodo/test_kmd_feat.cpp | 368 ++++++++++++++++++++++++++++++ 3 files changed, 372 insertions(+), 3 deletions(-) create mode 100644 src/test-komodo/test_kmd_feat.cpp diff --git a/src/Makefile.ktest.include b/src/Makefile.ktest.include index bbba1a42..f2595233 100644 --- a/src/Makefile.ktest.include +++ b/src/Makefile.ktest.include @@ -20,7 +20,8 @@ komodo_test_SOURCES = \ test-komodo/test_events.cpp \ test-komodo/test_hex.cpp \ test-komodo/test_haraka_removal.cpp \ - test-komodo/test_oldhash_removal.cpp + test-komodo/test_oldhash_removal.cpp \ + test-komodo/test_kmd_feat.cpp komodo_test_CPPFLAGS = $(komodod_CPPFLAGS) diff --git a/src/main.cpp b/src/main.cpp index 878fff93..d6fe089d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1799,7 +1799,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if ( chainName.isKMD() && chainActive.Tip() != nullptr && !komodo_validate_interest(tx,chainActive.Tip()->nHeight+1, chainActive.Tip()->GetMedianTimePast() + 777)) { - return error("%s: komodo_validate_interest failed txid.%s", __func__, tx.GetHash().ToString()); + return state.DoS(0, error("%s: komodo_validate_interest failed txid.%s", __func__, tx.GetHash().ToString()), REJECT_INVALID, "komodo-interest-invalid"); } if (!CheckTransaction(tiptime,tx, state, verifier, 0, 0)) @@ -5411,7 +5411,7 @@ bool ContextualCheckBlock(int32_t slowflag,const CBlock& block, CValidationState if (!komodo_validate_interest(tx, txheight, cmptime)) { LogPrintf("validate intrest failed for txnum.%i tx.%s\n", i, tx.ToString()); - return error("%s: komodo_validate_interest failed", __func__); + return state.DoS(0, error("%s: komodo_validate_interest failed", __func__), REJECT_INVALID, "komodo-interest-invalid"); } // Check transaction contextually against consensus rules at block height diff --git a/src/test-komodo/test_kmd_feat.cpp b/src/test-komodo/test_kmd_feat.cpp new file mode 100644 index 00000000..93cab0f2 --- /dev/null +++ b/src/test-komodo/test_kmd_feat.cpp @@ -0,0 +1,368 @@ +#include +#include + +#include "consensus/upgrades.h" +#include "consensus/validation.h" +#include "core_io.h" +#include "key_io.h" +#include "main.h" +#include "primitives/transaction.h" +#include "txmempool.h" +#include "policy/fees.h" +#include "util.h" +#include "univalue.h" + +#include "komodo_defs.h" +#include "komodo_globals.h" +#include "komodo_interest.h" +#include "cc/CCinclude.h" + + +const int komodo_interest_height = 247205+1; +const std::string testwif("Usr24VoC3h4cSfSrFiGJkWLYwmkM1VnsBiMyWZvrF6QR5ZQ6Fbuu"); +const std::string testpk("034b082c5819b5bf8798a387630ad236a8e800dbce4c4e24a46f36dfddab3cbff5"); +const std::string testaddr("RXTUtWXgkepi8f2ohWLL9KhtGKRjBV48hT"); + +const uint256 testPrevHash = uint256S("01f1fde483c591ae81bee34f3dfc26ca4d6f061bc4ca15806ae15e07befedce9"); + +// Fake the input of transaction testPrevHash/0 +class FakeCoinsViewDB2 : public CCoinsView { // change name to FakeCoinsViewDB2 to avoid name conflict with same class name in different files (seems a bug in macos gcc) +public: + FakeCoinsViewDB2() {} + + bool GetCoins(const uint256 &txid, CCoins &coins) const { + if (txid == testPrevHash) { + CTxOut txOut; + txOut.nValue = COIN; + txOut.scriptPubKey = GetScriptForDestination(DecodeDestination(testaddr)); + CCoins newCoins; + newCoins.vout.resize(1); + newCoins.vout[0] = txOut; + newCoins.nHeight = komodo_interest_height-1; + coins.swap(newCoins); + return true; + } + return false; + } + + bool HaveCoins(const uint256 &txid) const { + if (txid == testPrevHash) + return true; + return false; + } + + uint256 GetBestBlock() const override + { + return bestBlockHash; + } + + bool BatchWrite(CCoinsMap &mapCoins, + const uint256 &hashBlock, + const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, + CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, + CNullifiersMap &mapSproutNullifiers, + CNullifiersMap &mapSaplingNullifiers) { + return false; + } + + bool GetStats(CCoinsStats &stats) const { + return false; + } + + uint256 bestBlockHash; +}; + +bool TestSignTx(const CKeyStore& keystore, CMutableTransaction& mtx, int32_t vini, CAmount utxovalue, const CScript scriptPubKey) +{ + CTransaction txNewConst(mtx); + SignatureData sigdata; + auto consensusBranchId = CurrentEpochBranchId(chainActive.Height()+1, Params().GetConsensus()); + if (ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, vini, utxovalue, SIGHASH_ALL), scriptPubKey, sigdata, consensusBranchId) != 0) { + UpdateTransaction(mtx, vini, sigdata); + return true; + } else { + std::cerr << __func__ << " signing error for vini=" << vini << " amount=" << utxovalue << std::endl; + return false; + } +} + + +class KomodoFeatures : public ::testing::Test { +protected: + virtual void SetUp() { + SelectParams(CBaseChainParams::MAIN); + fPrintToConsoleOld = fPrintToConsole; + fPrintToConsole = true; // TODO save and restore + + chainName = assetchain(); // ensure KMD + + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + KOMODO_REWIND = 0; + chainActive.SetTip(nullptr); + } + + virtual void TearDown() { + // Revert to test default. No-op on mainnet params. + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); + fPrintToConsole = fPrintToConsoleOld; + } + bool fPrintToConsoleOld; +}; + +// some komodo consensus extensions +TEST_F(KomodoFeatures, komodo_interest_validate) { + + // Add a fake transaction to the wallet + CMutableTransaction mtx0 = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_interest_height-1); + CScript scriptPubKey = GetScriptForDestination(DecodeDestination(testaddr)); + mtx0.vout.push_back(CTxOut(COIN, scriptPubKey)); + + // Fake-mine the transaction + ASSERT_EQ(-1, chainActive.Height()); + CBlock block; + //block.hashPrevBlock = chainActive.Tip()->GetBlockHash(); + block.vtx.push_back(mtx0); + block.hashMerkleRoot = block.BuildMerkleTree(); + auto blockHash = block.GetHash(); + CBlockIndex *pfakeIndex = new CBlockIndex(block); // TODO: change back to auto if index is not cleaned + pfakeIndex->pprev = nullptr; + pfakeIndex->nHeight = komodo_interest_height-1; + pfakeIndex->nTime = 1663755146; + mapBlockIndex.insert(std::make_pair(blockHash, pfakeIndex)); + chainActive.SetTip(pfakeIndex); + EXPECT_TRUE(chainActive.Contains(pfakeIndex)); + EXPECT_EQ(komodo_interest_height-1, chainActive.Height()); + + //std::cerr << " mtx0.GetHash()=" << mtx0.GetHash().GetHex() << std::endl; + EXPECT_EQ(mtx0.GetHash(), testPrevHash); + + FakeCoinsViewDB2 fakedb; + fakedb.bestBlockHash = blockHash; + CCoinsViewCache fakeview(&fakedb); + pcoinsTip = &fakeview; + + CTxMemPool pool(::minRelayTxFee); + bool missingInputs; + CMutableTransaction mtxSpend = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_interest_height); + mtxSpend.vin.push_back(CTxIn(mtx0.GetHash(), 0)); + CScript scriptPubKey1 = GetScriptForDestination(DecodeDestination(testaddr)); + mtxSpend.vout.push_back(CTxOut(COIN, scriptPubKey1)); + + CBasicKeyStore tempKeystore; + CKey key = DecodeSecret(testwif); + tempKeystore.AddKey(key); + + // create coinbase + CMutableTransaction txcb = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_interest_height); + txcb.vin.resize(1); + txcb.vin[0].prevout.SetNull(); + txcb.vin[0].scriptSig = (CScript() << komodo_interest_height << CScriptNum(1)) + COINBASE_FLAGS; + txcb.vout.resize(1); + txcb.vout[0].scriptPubKey = GetScriptForDestination(DecodeDestination(testaddr));; + txcb.vout[0].nValue = GetBlockSubsidy(komodo_interest_height, Params().GetConsensus()) + 0; + txcb.nExpiryHeight = 0; + txcb.nLockTime = pfakeIndex->GetMedianTimePast()+1; + + { + // check invalid interest in mempool + + mtxSpend.nLockTime = chainActive.Tip()->GetMedianTimePast() + 777 - 3600 - 1; // too long time to add into mempool (prevent incorrect interest) + EXPECT_TRUE(TestSignTx(tempKeystore, mtxSpend, 0, mtx0.vout[0].nValue, mtx0.vout[0].scriptPubKey)); + + CValidationState state1; + CTransaction tx1(mtxSpend); + + LOCK( cs_main ); + EXPECT_FALSE(AcceptToMemoryPool(pool, state1, tx1, false, &missingInputs)); + EXPECT_EQ(state1.GetRejectReason(), "komodo-interest-invalid"); + } + { + // check invalid interest in block + + CBlock block; + block.vtx.push_back(txcb); + + mtxSpend.nLockTime = chainActive.Tip()->GetMedianTimePast() - 3600 - 1; // too long time staying in mempool (a bit longer than when adding ) + mtxSpend.vin[0].scriptSig.clear(); + EXPECT_TRUE(TestSignTx(tempKeystore, mtxSpend, 0, mtx0.vout[0].nValue, mtx0.vout[0].scriptPubKey)); + CTransaction tx1(mtxSpend); + block.vtx.push_back(tx1); + + block.nTime = pfakeIndex->GetMedianTimePast(); + + CValidationState state1; + EXPECT_FALSE(ContextualCheckBlock(false, block, state1, pfakeIndex)); + EXPECT_EQ(state1.GetRejectReason(), "komodo-interest-invalid"); + } + { + // check valid interest in mempool + + mtxSpend.nLockTime = chainActive.Tip()->GetMedianTimePast() + 777 - 3600; // not too long time to add into mempool + EXPECT_TRUE(TestSignTx(tempKeystore, mtxSpend, 0, mtx0.vout[0].nValue, mtx0.vout[0].scriptPubKey)); + + CValidationState state1; + CTransaction tx1(mtxSpend); + + LOCK( cs_main ); + EXPECT_TRUE(AcceptToMemoryPool(pool, state1, tx1, false, &missingInputs)); + } + + { + // check valid interest in block + + mtxSpend.nLockTime = chainActive.Tip()->GetMedianTimePast() - 3600; // not too long time in mempool + mtxSpend.vin[0].scriptSig.clear(); + EXPECT_TRUE(TestSignTx(tempKeystore, mtxSpend, 0, mtx0.vout[0].nValue, mtx0.vout[0].scriptPubKey)); + + CBlock block; + block.vtx.push_back(txcb); + CTransaction tx1(mtxSpend); + block.vtx.push_back(tx1); + block.nTime = pfakeIndex->GetMedianTimePast(); + + CValidationState state1; + EXPECT_TRUE(ContextualCheckBlock(false, block, state1, pfakeIndex)); + } +} + +// check komodo_interestnew calculations +TEST_F(KomodoFeatures, komodo_interestnew) { + + // some not working values + EXPECT_EQ(komodo_interestnew(1, 1000LL, 1, 1), 0LL); + // time lower than cut off month time limit + EXPECT_EQ(komodo_interestnew(1000000, 10LL*COIN, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600 /*KOMODO_MAXMEMPOOLTIME*/), 10LL*COIN/10512000 * (31*24*60 - 59)); + + // end of interest era + EXPECT_EQ(komodo_interestnew(7777777-1, 10LL*COIN, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), 10LL*COIN/10512000 * (31*24*60 - 59)); + EXPECT_EQ(komodo_interestnew(7777777, 10LL*COIN, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), 0LL); + + // value less than limit + EXPECT_EQ(komodo_interestnew(1000000, 10LL*COIN-1, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), 0); + // tip less than nLockTime + EXPECT_EQ(komodo_interestnew(1000000, 10LL*COIN-1, 1663839248, 1663839248 - 1), 0); + // not timestamp value + EXPECT_EQ(komodo_interestnew(1000000, 10LL*COIN-1, 400000000U, 400000000U + 30 * 24 * 60 * 60 + 3600), 0); + + // too small period + EXPECT_EQ(komodo_interestnew(1000000, 10LL*COIN, 1663839248, 1663839248 + 3600 - 1), 0); + // time over cut off month time limit + EXPECT_EQ(komodo_interestnew(1000000, 10LL*COIN, 1663839248, 1663839248 + 31 * 24 * 60 * 60 + 3600+1), 10LL*COIN/10512000 * (31*24*60 - 59)); + EXPECT_EQ(komodo_interestnew(1000000, 10LL*COIN, 1663839248, 1663839248 + 32 * 24 * 60 * 60 + 3600), 10LL*COIN/10512000 * (31*24*60 - 59)); + + // time close to cut off year time limit + EXPECT_EQ(komodo_interestnew(1000000-1, 10LL*COIN, 1663839248, 1663839248 + (365 * 24 * 60 - 1) * 60 + 3600), 10LL*COIN/10512000 * (365*24*60 - 59)); + // time over cut off year time limit + EXPECT_EQ(komodo_interestnew(1000000-1, 10LL*COIN, 1663839248, 1663839248 + (365 * 24 * 60 - 1) * 60 + 3600 + 60), 10LL*COIN/10512000 * (365*24*60 - 59)); + EXPECT_EQ(komodo_interestnew(1000000-1, 10LL*COIN, 1663839248, 1663839248 + (365 * 24 * 60 - 1) * 60 + 3600 + 30 * 24 * 60), 10LL*COIN/10512000 * (365*24*60 - 59)); +} + +// check komodo_interest calculations +TEST_F(KomodoFeatures, komodo_interest) { + + const uint32_t activation = 1491350400; // 1491350400 5th April + + { + // some not working values should produce 0LL + EXPECT_EQ(komodo_interest(1, 1000LL, 1, 1), 0LL); + } + { + // nValue <= 25000LL*COIN and nValue >= 25000LL*COIN + // txheight >= 1000000 + // should be routed to komodo_interestnew + + for (CAmount nValue : { 10LL*COIN, 25001LL*COIN }) + { + // time lower than cut off month time limit + EXPECT_EQ(komodo_interest(1000000, nValue, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), nValue/10512000 * (31*24*60 - 59)); + + // end of interest era + EXPECT_EQ(komodo_interest(7777777-1, nValue, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), nValue/10512000 * (31*24*60 - 59)); + EXPECT_EQ(komodo_interest(7777777 /*KOMODO_ENDOFERA*/, nValue, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), 0LL); + + // tip less than nLockTime + EXPECT_EQ(komodo_interest(1000000, nValue-1, 1663839248, 1663839248 - 1), 0); + // not timestamp value + EXPECT_EQ(komodo_interest(1000000, nValue-1, 400000000U, 400000000U + 30 * 24 * 60 * 60 + 3600), 0); + + // too small period + EXPECT_EQ(komodo_interest(1000000, nValue, 1663839248, 1663839248 + 3600 - 1), 0); + // time over cut off month time limit + EXPECT_EQ(komodo_interest(1000000, nValue, 1663839248, 1663839248 + 31 * 24 * 60 * 60 + 3600+1), nValue/10512000 * (31*24*60 - 59)); + EXPECT_EQ(komodo_interest(1000000, nValue, 1663839248, 1663839248 + 32 * 24 * 60 * 60 + 3600), nValue/10512000 * (31*24*60 - 59)); + } + // value less than limit + EXPECT_EQ(komodo_interest(1000000, 10LL*COIN-1, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), 0); + } + + for (auto days : { 1, 10, 365, 365*2, 365*3 }) + { + std::cerr << "running komodo_interest test for days=" << days << "..." << std::endl; + int32_t minutes = days * 24 * 60; + if (minutes > 365 * 24 * 60) + minutes = 365 * 24 * 60; + { + // nValue <= 25000LL*COIN + // txheight < 1000000 + + uint64_t numerator = (10LL*COIN / 20); // assumes 5%! + EXPECT_EQ(komodo_interest(1000000-1, 10LL*COIN, 1663839248, 1663839248 + minutes * 60), numerator * (minutes - 59) / (365ULL * 24 * 60)); + } + { + // nValue <= 25000LL*COIN + // txheight < 250000 + + uint64_t numerator = (10LL*COIN * 5000000 /*KOMODO_INTEREST*/); + uint32_t locktime = activation - 2 * days * 24 * 60 * 60; + uint32_t tiptime = locktime + minutes * 60; + ASSERT_TRUE(tiptime < activation); + uint64_t denominator = (365LL * 24 * 60) / minutes; + denominator = (denominator == 0LL) ? 1LL : denominator; + EXPECT_EQ(komodo_interest(250000-1, 10LL*COIN, locktime, tiptime), numerator / denominator / COIN); + } + { + // !exception + // nValue > 25000LL*COIN + // txheight < 250000 + + uint64_t numerator = (25000LL*COIN+1) / 20; // assumes 5%! + uint64_t denominator = (365LL * 24 * 60) / minutes; // no minutes-59 adjustment + denominator = (denominator == 0LL) ? 1LL : denominator; + EXPECT_EQ(komodo_interest(250000-1, 25000LL*COIN+1, 1663839248, 1663839248 + minutes * 60), numerator / denominator); + } + { + // !exception + // nValue > 25000LL*COIN + // txheight < 1000000 + + uint64_t numerator = (25000LL*COIN+1) / 20; // assumes 5%! + int32_t minutes_adj = minutes - 59; // adjusted since ht=250000 + EXPECT_EQ(komodo_interest(1000000-1, 25000LL*COIN+1, 1663839248, 1663839248 + minutes * 60), numerator * minutes_adj / (365LL * 24 * 60)); + } + { + // exception + // nValue > 25000LL*COIN + // txheight < 1000000 + + for (const auto htval : std::vector>{ {116607, 2502721100000LL}, {126891, 2879650000000LL}, {129510, 3000000000000LL}, {141549, 3500000000000LL}, {154473, 3983399350000LL}, {154736, 3983406748175LL}, {155013, 3983414006565LL}, {155492, 3983427592291LL}, {155613, 9997409999999797LL}, {157927, 9997410667451072LL}, {155613, 2590000000000LL}, {155949, 4000000000000LL} }) + { + int32_t txheight = htval.first; + CAmount nValue = htval.second; + uint64_t numerator = (static_cast(nValue) * 5000000 /*KOMODO_INTEREST*/); // NOTE: uint64_t (for CAmount it is an overflow here for some exceptions) + uint32_t locktime = 1484490069; // close to real tx locktime + // uint32_t locktime = 1663839248; + uint32_t tiptime = locktime + minutes * 60; + // uint32_t tiptime = 1663920715; // test writing time + // int32_t minutes = (tiptime - locktime) / 60; + uint64_t denominator = (365LL * 24 * 60) / minutes; + denominator = (denominator == 0LL) ? 1LL : denominator; + if (txheight < 155949) + EXPECT_EQ(komodo_interest(txheight, nValue, locktime, tiptime), numerator / denominator / COIN); + } + } + } +} \ No newline at end of file From ece67acdbd86c7dfb6ac4e1f350bc9e1d57b542b Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 26 Sep 2022 15:18:13 +0200 Subject: [PATCH 24/27] add interest calculations via CCoinsViewCache::GetValueIn test --- src/test-komodo/test_kmd_feat.cpp | 131 ++++++++++++++++++++++++++---- 1 file changed, 116 insertions(+), 15 deletions(-) diff --git a/src/test-komodo/test_kmd_feat.cpp b/src/test-komodo/test_kmd_feat.cpp index 93cab0f2..e4e20157 100644 --- a/src/test-komodo/test_kmd_feat.cpp +++ b/src/test-komodo/test_kmd_feat.cpp @@ -23,22 +23,26 @@ const std::string testwif("Usr24VoC3h4cSfSrFiGJkWLYwmkM1VnsBiMyWZvrF6QR5ZQ6Fbuu" const std::string testpk("034b082c5819b5bf8798a387630ad236a8e800dbce4c4e24a46f36dfddab3cbff5"); const std::string testaddr("RXTUtWXgkepi8f2ohWLL9KhtGKRjBV48hT"); -const uint256 testPrevHash = uint256S("01f1fde483c591ae81bee34f3dfc26ca4d6f061bc4ca15806ae15e07befedce9"); - -// Fake the input of transaction testPrevHash/0 +// Fake the input of transaction mtx0/0 class FakeCoinsViewDB2 : public CCoinsView { // change name to FakeCoinsViewDB2 to avoid name conflict with same class name in different files (seems a bug in macos gcc) public: - FakeCoinsViewDB2() {} + FakeCoinsViewDB2() { + // allowed mtx0 txids + sAllowedTxIn.insert(uint256S("01f1fde483c591ae81bee34f3dfc26ca4d6f061bc4ca15806ae15e07befedce9")); // 1 * COIN , nLockTime = 0 + sAllowedTxIn.insert(uint256S("c8ff545cdc5e921cdbbd24555a462340fc1092e09977944ec687c5bf3ef9c30b")); // 10 * COIN, nLockTime = 0 + sAllowedTxIn.insert(uint256S("529d8dcec041465fdf6c1f873ef1055eec106db5f02ae222814d3764bb8e6660")); // 10 * COIN, nLockTime = 1663755146 + sAllowedTxIn.insert(uint256S("3533600e69a22776afb765305a0ec46bcb06e1942f36a113d73733190092f9d5")); // 10 * COIN, nLockTime = 1663755147 + } bool GetCoins(const uint256 &txid, CCoins &coins) const { - if (txid == testPrevHash) { + if (sAllowedTxIn.count(txid)) { CTxOut txOut; - txOut.nValue = COIN; + txOut.nValue = 10 * COIN; txOut.scriptPubKey = GetScriptForDestination(DecodeDestination(testaddr)); CCoins newCoins; newCoins.vout.resize(1); newCoins.vout[0] = txOut; - newCoins.nHeight = komodo_interest_height-1; + newCoins.nHeight = komodo_interest_height-1; /* TODO: return correct nHeight depends on txid */ coins.swap(newCoins); return true; } @@ -46,7 +50,7 @@ class FakeCoinsViewDB2 : public CCoinsView { // change name to FakeCoinsViewDB2 } bool HaveCoins(const uint256 &txid) const { - if (txid == testPrevHash) + if (sAllowedTxIn.count(txid)) return true; return false; } @@ -72,6 +76,7 @@ class FakeCoinsViewDB2 : public CCoinsView { // change name to FakeCoinsViewDB2 } uint256 bestBlockHash; + std::set sAllowedTxIn; }; bool TestSignTx(const CKeyStore& keystore, CMutableTransaction& mtx, int32_t vini, CAmount utxovalue, const CScript scriptPubKey) @@ -119,7 +124,8 @@ TEST_F(KomodoFeatures, komodo_interest_validate) { // Add a fake transaction to the wallet CMutableTransaction mtx0 = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_interest_height-1); CScript scriptPubKey = GetScriptForDestination(DecodeDestination(testaddr)); - mtx0.vout.push_back(CTxOut(COIN, scriptPubKey)); + mtx0.vout.push_back(CTxOut(10 * COIN, scriptPubKey)); + mtx0.nLockTime = 1663755146; // Fake-mine the transaction ASSERT_EQ(-1, chainActive.Height()); @@ -137,20 +143,20 @@ TEST_F(KomodoFeatures, komodo_interest_validate) { EXPECT_TRUE(chainActive.Contains(pfakeIndex)); EXPECT_EQ(komodo_interest_height-1, chainActive.Height()); - //std::cerr << " mtx0.GetHash()=" << mtx0.GetHash().GetHex() << std::endl; - EXPECT_EQ(mtx0.GetHash(), testPrevHash); - FakeCoinsViewDB2 fakedb; fakedb.bestBlockHash = blockHash; CCoinsViewCache fakeview(&fakedb); pcoinsTip = &fakeview; + //std::cerr << " mtx0.GetHash()=" << mtx0.GetHash().GetHex() << std::endl; + EXPECT_NE(fakedb.sAllowedTxIn.count(mtx0.GetHash()), 0); + CTxMemPool pool(::minRelayTxFee); bool missingInputs; CMutableTransaction mtxSpend = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_interest_height); mtxSpend.vin.push_back(CTxIn(mtx0.GetHash(), 0)); CScript scriptPubKey1 = GetScriptForDestination(DecodeDestination(testaddr)); - mtxSpend.vout.push_back(CTxOut(COIN, scriptPubKey1)); + mtxSpend.vout.push_back(CTxOut(10 * COIN, scriptPubKey1)); CBasicKeyStore tempKeystore; CKey key = DecodeSecret(testwif); @@ -213,7 +219,6 @@ TEST_F(KomodoFeatures, komodo_interest_validate) { { // check valid interest in block - mtxSpend.nLockTime = chainActive.Tip()->GetMedianTimePast() - 3600; // not too long time in mempool mtxSpend.vin[0].scriptSig.clear(); EXPECT_TRUE(TestSignTx(tempKeystore, mtxSpend, 0, mtx0.vout[0].nValue, mtx0.vout[0].scriptPubKey)); @@ -227,6 +232,102 @@ TEST_F(KomodoFeatures, komodo_interest_validate) { CValidationState state1; EXPECT_TRUE(ContextualCheckBlock(false, block, state1, pfakeIndex)); } + + { + // test interest calculations via CCoinsViewCache::GetValueIn + + const uint32_t tipTimes[] = { + 1663755146, + 1663762346, // chainActive.Tip()->GetMedianTimePast() + 2 * 3600 (MTP from 1663755146 + 2 * 3600) + 1663762346 + 31 * 24 * 60 * 60, /* month */ + 1663762346 + 6 * 30 * 24 * 60 * 60, /* half of a year */ + 1663762346 + 12 * 30 * 24 * 60 * 60, /* year (360 days) */ + 1663762346 + 365 * 24 * 60 * 60, /* year (365 days) */ + }; + + /* komodo_interest_height = 247205+1 */ + const CAmount interestCollectedBefore250k[] = {0, 11415, 4545454, 25000000, 50000000, 50000000}; + /* komodo_interest_height = 333332 */ + const CAmount interestCollectedBefore1M[] = {0, 5802, 4252378, 24663337, 49320871, 49994387}; + /* komodo_interest_height = 3000000 */ + const CAmount interestCollected[] = {0, 5795, 4235195, 4235195, 4235195, 4235195}; + + /* check collected interest */ + + const size_t nMaxTipTimes = sizeof(tipTimes) / sizeof(tipTimes[0]); + const size_t nMaxInterestCollected = sizeof(interestCollected) / sizeof(interestCollected[0]); + assert(nMaxTipTimes == nMaxInterestCollected); + + const int testHeights[] = { + 247205 + 1, 333332, 3000000}; + + CValidationState state; + + for (size_t idx_ht = 0; idx_ht < sizeof(testHeights) / sizeof(testHeights[0]); ++idx_ht) + { + + pfakeIndex->nHeight = testHeights[idx_ht] - 1; + mtx0.nLockTime = 1663755146; + mtxSpend.vin[0] = CTxIn(mtx0.GetHash(), 0); + + for (size_t idx = 0; idx < nMaxTipTimes; ++idx) + { + // make fake last block + CBlock lastBlock; + lastBlock.nTime = tipTimes[idx]; + + CBlockIndex *pLastBlockIndex = new CBlockIndex(block); + pLastBlockIndex->pprev = pfakeIndex; + pLastBlockIndex->nHeight = testHeights[idx_ht]; + pLastBlockIndex->nTime = lastBlock.nTime; + chainActive.SetTip(pLastBlockIndex); + + mtxSpend.nLockTime = lastBlock.nTime; + mtxSpend.vin[0].scriptSig.clear(); + EXPECT_TRUE(TestSignTx(tempKeystore, mtxSpend, 0, mtx0.vout[0].nValue, mtx0.vout[0].scriptPubKey)); + CTransaction tx1(mtxSpend); + + mempool.clear(); + mapBlockIndex.clear(); + + // put tx which we trying to spend into mempool, + // bcz CCoinsViewCache::GetValueIn will call komodo_accrued_interest + // -> komodo_interest_args -> GetTransaction + + auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); + SetMockTime(mtxSpend.nLockTime); + CTxMemPoolEntry entry(mtx0, 0, GetTime(), 0, chainActive.Height(), mempool.HasNoInputsOf(mtx0), false, consensusBranchId); + mempool.addUnchecked(mtx0.GetHash(), entry, false); + + EXPECT_TRUE(mempool.exists(mtx0.GetHash())); + + // force komodo_getblockindex in komodo_interest_args return a value + uint256 zero; + zero.SetNull(); + mapBlockIndex.insert(std::make_pair(zero, pfakeIndex)); + + fakeview.GetBestBlock(); // bring the best block into scope + EXPECT_EQ(chainActive.Tip()->nHeight, testHeights[idx_ht]); + CAmount interest = 0; + CAmount nValueIn = fakeview.GetValueIn(chainActive.Tip()->nHeight, interest, tx1); + + switch (testHeights[idx_ht]) + { + case 247205 + 1: + ASSERT_EQ(interest, interestCollectedBefore250k[idx]); + break; + case 333332: + ASSERT_EQ(interest, interestCollectedBefore1M[idx]); + break; + default: + ASSERT_EQ(interest, interestCollected[idx]); + break; + } + + delete pLastBlockIndex; + } + } + } } // check komodo_interestnew calculations @@ -365,4 +466,4 @@ TEST_F(KomodoFeatures, komodo_interest) { } } } -} \ No newline at end of file +} From 3113cf45dce286c761b4187dfa44ea8c530c30ce Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Sat, 1 Oct 2022 21:04:38 +0200 Subject: [PATCH 25/27] Update Qt 5.12.11 download path (official_releases -> archive) --- depends/packages/qt.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 3113d602..a646474a 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,6 +1,6 @@ PACKAGE=qt $(package)_version=5.12.11 -$(package)_download_path=https://download.qt.io/official_releases/qt/5.12/$($(package)_version)/submodules +$(package)_download_path=https://download.qt.io/archive/qt/5.12/$($(package)_version)/submodules $(package)_suffix=everywhere-src-$($(package)_version).tar.xz $(package)_file_name=qtbase-$($(package)_suffix) $(package)_sha256_hash=1c1b4e33137ca77881074c140d54c3c9747e845a31338cfe8680f171f0bc3a39 From 68f8d3e9f716cbe625f4e2f70f377662a3dfd101 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 17 Oct 2022 12:28:53 +0200 Subject: [PATCH 26/27] Fix AC_CHECK_LIB for gmp - https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Libraries.html - https://stackoverflow.com/questions/53609622/difference-between-single-and-double-square-brackets-in-autoconf --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 47739bd6..b247234d 100644 --- a/configure.ac +++ b/configure.ac @@ -944,7 +944,7 @@ CXXFLAGS="${save_CXXFLAGS}" # platforms, so we use older autoconf detection mechanisms: if test x$TARGET_OS = xdarwin; then AC_CHECK_HEADER([gmp.h],,AC_MSG_ERROR(libgmp headers missing)) -AC_CHECK_LIB([gmp],[[__gmpn_sub_n]],GMP_LIBS=-lgmp, [AC_MSG_ERROR(libgmp missing)]) +AC_CHECK_LIB([gmp],[__gmpn_sub_n],GMP_LIBS=-lgmp, [AC_MSG_ERROR(libgmp missing)]) AC_CHECK_HEADER([gmpxx.h],,AC_MSG_ERROR(libgmpxx headers missing)) AC_CHECK_LIB([gmpxx],[main],GMPXX_LIBS=-lgmpxx, [AC_MSG_ERROR(libgmpxx missing)]) From b931f061d134d007e0cea78079b91d5a89f61316 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 17 Oct 2022 15:07:49 +0200 Subject: [PATCH 27/27] bump version to v0.7.2-beta3 (0.7.2.2) --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b247234d..88d0fff4 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 7) define(_CLIENT_VERSION_REVISION, 2) -define(_CLIENT_VERSION_BUILD, 1) +define(_CLIENT_VERSION_BUILD, 2) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) define(_CLIENT_VERSION_IS_RELEASE, true)