From 2cf210288737e6c5f047379c9502e4a4f3863d34 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Wed, 30 Jan 2019 00:33:08 +0800 Subject: [PATCH 01/12] -ac_notarypay --- src/komodo.h | 28 +++++++--- src/komodo_bitcoind.h | 114 ++++++++++++++++++++++++++++++++++++++++ src/komodo_defs.h | 2 +- src/komodo_globals.h | 2 +- src/komodo_utils.h | 7 ++- src/main.cpp | 17 +++++- src/miner.cpp | 71 ++++++++++++++++++++----- src/notaries_staked.cpp | 4 +- 8 files changed, 218 insertions(+), 27 deletions(-) diff --git a/src/komodo.h b/src/komodo.h index af4ea499c..9978e8588 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -37,7 +37,7 @@ 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); -void komodo_connectblock(CBlockIndex *pindex,CBlock& block); +int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block); #include "komodo_structs.h" #include "komodo_globals.h" @@ -695,6 +695,11 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr } else if ( ASSETCHAINS_SYMBOL[0] == 0 && matched != 0 && notarized != 0 && validated != 0 ) komodo_rwccdata((char *)"KMD",1,&ccdata,0); + else + { + fprintf(stderr, "NOT matched NOTARISATION\n"); + return (-2); + } if ( matched != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height ) { sp->NOTARIZED_HEIGHT = *notarizedheightp; @@ -708,10 +713,7 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->MoM,sp->MoMdepth); if ( ASSETCHAINS_SYMBOL[0] != 0 ) printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",ASSETCHAINS_SYMBOL,height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth); - if ( 0 && RemoveOrphanedBlocks(*notarizedheightp)) - { - //fprintf(stderr, "Sucessfully removed all known orphaned blocks before height %d\n",*notarizedheightp); - } + if ( ASSETCHAINS_SYMBOL[0] == 0 ) { if ( signedfp == 0 ) @@ -798,7 +800,8 @@ int32_t komodo_notarycmp(uint8_t *scriptPubKey,int32_t scriptlen,uint8_t pubkeys return(-1); } -void komodo_connectblock(CBlockIndex *pindex,CBlock& block) +// int32_t ! +int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block) { static int32_t hwmheight; int32_t staked_era; static int32_t lastStakedEra; @@ -809,7 +812,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) if ( pindex == 0 ) { fprintf(stderr,"komodo_connectblock null pindex\n"); - return; + return -1; } memset(&zero,0,sizeof(zero)); komodo_init(pindex->GetHeight()); @@ -817,7 +820,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) { fprintf(stderr,"unexpected null komodostateptr.[%s]\n",ASSETCHAINS_SYMBOL); - return; + return -1; } //fprintf(stderr,"%s connect.%d\n",ASSETCHAINS_SYMBOL,pindex->nHeight); if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 || IS_STAKED_NOTARY > -1 ) @@ -858,6 +861,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) komodo_stateupdate(pindex->GetHeight(),0,0,0,zero,0,0,0,0,-pindex->GetHeight(),pindex->nTime,0,0,0,0,zero,0); } komodo_currentheight_set(chainActive.LastTip()->GetHeight()); + int transaction = 0; if ( pindex != 0 ) { height = pindex->GetHeight(); @@ -913,6 +917,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) fwrite(&signedmask,1,sizeof(signedmask),signedfp); fflush(signedfp); } + transaction = i; printf("[%s] ht.%d txi.%d signedmask.%llx numvins.%d numvouts.%d <<<<<<<<<<< notarized\n",ASSETCHAINS_SYMBOL,height,i,(long long)signedmask,numvins,numvouts); } notarized = 1; @@ -938,10 +943,13 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) if ( IS_KOMODO_NOTARY != 0 && ASSETCHAINS_SYMBOL[0] == 0 ) printf("%.8f ",dstr(block.vtx[i].vout[j].nValue)); len = block.vtx[i].vout[j].scriptPubKey.size(); + if ( len >= sizeof(uint32_t) && len <= sizeof(scriptbuf) ) { memcpy(scriptbuf,(uint8_t *)&block.vtx[i].vout[j].scriptPubKey[0],len); notaryid = komodo_voutupdate(&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()); + if ( notaryid == -2 ) + return(-1); if ( 0 && i > 0 ) { for (k=0; kGetHeight()); + if (notarized = 1) + return(transaction); + else + return(-1); } diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index aaf560192..3187099c7 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1772,6 +1772,96 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height) return(isPOS); } +uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &NotarisationNotaries, uint32_t timestamp) +{ + // fetch notary pubkey array. + uint64_t total = 0; + int32_t staked_era; int8_t numSN; + uint8_t staked_pubkeys[64][33]; + staked_era = STAKED_era(timestamp); + numSN = numStakedNotaries(staked_pubkeys,staked_era); + // resize coinbase vouts to number of notary nodes +1 for coinbase itself. + txNew.vout.resize(NotarisationNotaries.size()+1); + // loop over notarisation vins and add transaction to coinbase. + for (int8_t n = 0; n < NotarisationNotaries.size(); n++) + { + uint8_t *ptr; + txNew.vout[n+1].scriptPubKey.resize(35); + ptr = (uint8_t *)&txNew.vout[n+1].scriptPubKey[0]; + ptr[0] = 33; + for (int8_t i=0; i<33; i++) + { + ptr[i+1] = staked_pubkeys[NotarisationNotaries[n]][i]; + //fprintf(stderr,"%02x",ptr[i+1]); + } + ptr[34] = OP_CHECKSIG; + //fprintf(stderr," set notary %i PUBKEY33 into vout[%i]\n",NotarisationNotaries[n],n+1); + txNew.vout[n+1].nValue = ASSETCHAINS_NOTARY_PAY; // ASSETCHAINS_NOTARY_PAY + total += txNew.vout[n+1].nValue; + } + return(total); +} + +uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) +{ + std::vector NotarisationNotaries; + uint32_t timestamp = pblock->nTime; + int32_t staked_era; int8_t numSN; + uint8_t staked_pubkeys[64][33]; + staked_era = STAKED_era(timestamp); + numSN = numStakedNotaries(staked_pubkeys,staked_era); + + uint8_t *script; int32_t scriptlen; + // loop over notaries array and extract index of signers. + + BOOST_FOREACH(const CTxIn& txin, pblock->vtx[1].vin) + { + uint256 hash; CTransaction tx1; + if ( GetTransaction(txin.prevout.hash,tx1,hash,false) ) + { + for (int8_t i = 0; i < numSN; i++) + { + //tx1.vout[txin.prevout.n].scriptPubKey + script = (uint8_t *)&tx1.vout[txin.prevout.n].scriptPubKey[0]; + scriptlen = (int32_t)tx1.vout[txin.prevout.n].scriptPubKey.size(); + if ( scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[i],33) == 0 ) + NotarisationNotaries.push_back(i); + } + } + } + const CChainParams& chainparams = Params(); + const Consensus::Params &consensusParams = chainparams.GetConsensus(); + CMutableTransaction txNew = CreateNewContextualCMutableTransaction(consensusParams, height); + uint64_t totalsats = komodo_notarypay(txNew, NotarisationNotaries, pblock->nTime); + int8_t n = 0, i = 0, matches = 0; + uint64_t total = 0; + //fprintf(stderr, "txNew.vout size = %li\n",txNew.vout.size()); + BOOST_FOREACH(const CTxOut& txout, txNew.vout) + { + if ( n == 0 ) + { + n++; + continue; + } + script = (uint8_t *)&txout.scriptPubKey[0]; + scriptlen = (int32_t)txout.scriptPubKey.size(); + // ASSETCHAINS_NOTARY_PAY = nValue! + if ( txout.nValue == ASSETCHAINS_NOTARY_PAY && scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[NotarisationNotaries[n-1]],33) == 0 ) + { + matches++; + total += txout.nValue; + fprintf(stderr, "matched.%i\n", NotarisationNotaries[n-1]); + } + n++; + } + if ( matches = n && matches != 0 && total == totalsats ) + { + fprintf(stderr, "VALIDATED.\n" ); + return(totalsats); + } + return(-1); +} + int64_t komodo_checkcommission(CBlock *pblock,int32_t height) { int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0; @@ -1952,6 +2042,30 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) return(-1); } } + if( failed == 0 && ASSETCHAINS_NOTARY_PAY != 0 && pblock->vtx[0].vout.size() != 1 ) + { + if ( slowflag != 0 && komodo_checknotarypay(pblock,height) < 0 ) + { + fprintf(stderr, "Komodo notary pay validation failed.%i\n",height); + return(0); + } + else + { + // Check the notarisation tx is to the crypto address and meets min sigs. + if ( !komodo_is_notarytx(pblock->vtx[1]) == 1 ) + { + fprintf(stderr, "notarisation is not to crypto address.%i\n",height); + return(0); + } + // Check min sigs. + if ( pblock->vtx[1].vin.size() < num_notaries_STAKED[STAKED_era(pblock->nTime)] ) + { + fprintf(stderr, "block does not meet minsigs .%i\n",height); + return(0); + } + } + } + //fprintf(stderr,"komodo_checkPOW possible.%d slowflag.%d ht.%d notaryid.%d failed.%d\n",possible,slowflag,height,notaryid,failed); if ( failed != 0 && possible == 0 && notaryid < 0 ) return(-1); diff --git a/src/komodo_defs.h b/src/komodo_defs.h index e60e9d3d5..32fb74dab 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -40,7 +40,7 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; extern uint32_t ASSETCHAIN_INIT, ASSETCHAINS_MAGIC; extern int32_t VERUS_BLOCK_POSUNITS, ASSETCHAINS_LWMAPOS, ASSETCHAINS_SAPLING, ASSETCHAINS_OVERWINTER; -extern uint64_t ASSETCHAINS_SUPPLY, ASSETCHAINS_FOUNDERS_REWARD; +extern uint64_t ASSETCHAINS_SUPPLY, ASSETCHAINS_FOUNDERS_REWARD, ASSETCHAINS_NOTARY_PAY; extern uint64_t ASSETCHAINS_TIMELOCKGTE; extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_VERUSHASH,ASSETCHAINS_EQUIHASH,KOMODO_INITDONE; diff --git a/src/komodo_globals.h b/src/komodo_globals.h index a227b642c..13caee41d 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -97,7 +97,7 @@ int32_t ASSETCHAINS_OVERWINTER = -1; uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE; int32_t ASSETCHAINS_STAKED; -uint64_t ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY = 10,MIN_RECV_SATS,ASSETCHAINS_FOUNDERS_REWARD; +uint64_t ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY = 10,MIN_RECV_SATS,ASSETCHAINS_FOUNDERS_REWARD,ASSETCHAINS_NOTARY_PAY; uint32_t KOMODO_INITDONE; char KMDUSERPASS[8192+512+1],BTCUSERPASS[8192]; uint16_t KMD_PORT = 7771,BITCOIND_RPCPORT = 7771; diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 51c84a326..4dbf49637 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1895,6 +1895,9 @@ void komodo_args(char *argv0) } else { + ASSETCHAINS_NOTARY_PAY = GetArg("-ac_notarypay",0); + if ( ASSETCHAINS_NOTARY_PAY != 0 ) + printf("Assetchains NOTARY PAY set to %lu sats per notarisation per notary. Cannot work with ac_script or ac_pubkey!\n",ASSETCHAINS_NOTARY_PAY); if ( ASSETCHAINS_COMMISSION != 0 ) { ASSETCHAINS_COMMISSION = 0; @@ -1911,7 +1914,7 @@ void komodo_args(char *argv0) fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n"); exit(0); } - 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_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 ) + 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_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY != 0 ) { fprintf(stderr,"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; @@ -2006,6 +2009,8 @@ void komodo_args(char *argv0) } fprintf(stderr," <- CCLIB name\n"); } + if ( ASSETCHAINS_NOTARY_PAY != 0 ) + extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_NOTARY_PAY),(void *)&ASSETCHAINS_NOTARY_PAY); } addn = GetArg("-seednode",""); diff --git a/src/main.cpp b/src/main.cpp index 24044b42f..69790a72e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3572,6 +3572,17 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin fprintf(stderr,"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_NOTARY_PAY != 0 && block.vtx[0].vout.size() > 1 ) + { + uint64_t notarypaycheque = komodo_checknotarypay((CBlock *)&block,(int32_t)pindex->GetHeight()); + if ( notarypaycheque > 0 ) + blockReward += notarypaycheque; + else if ( is_STAKED(ASSETCHAINS_SYMBOL) == 4 && IS_STAKED_NOTARY > 0 ) + blockReward += 999999999999999; // Notaries can validate any block for now. + else + return state.DoS(100, error("ConnectBlock(): Notary Pay exceeds coinbase (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward), + REJECT_INVALID, "bad-cb-amount"); + } if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->GetHeight() == 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), @@ -3684,7 +3695,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001); //FlushStateToDisk(); - komodo_connectblock(pindex,*(CBlock *)&block); + int tmp = komodo_connectblock(pindex,*(CBlock *)&block); // != block-nVersion-7000000; + if ( tmp > 0 ) + { + printf("VALID NOTARISATION connect block.%i tx.%i\n NOT VALIDATING HERE YET!",pindex->GetHeight(),tmp); + } return true; } diff --git a/src/miner.cpp b/src/miner.cpp index a1af2c7bf..4ad70912c 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -55,6 +55,8 @@ #include "sodium.h" +#include "notaries_staked.h" + #include #include #ifdef ENABLE_MINING @@ -151,6 +153,7 @@ int32_t komodo_is_notarytx(const CTransaction& tx); CScript Marmara_scriptPubKey(int32_t height,CPubKey pk); CScript MarmaraCoinbaseOpret(uint8_t funcid,int32_t height,CPubKey pk); int32_t komodo_is_notarytx(const CTransaction& tx); +uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &NotarisationNotaries, uint32_t timestamp); CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake) { @@ -170,6 +173,8 @@ 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; + //fprintf(stderr,"create new block\n"); // Create new block if ( gpucount < 0 ) @@ -239,6 +244,11 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 } } pblock->nTime = GetAdjustedTime(); + // Now we have the block time, we can get the active notaries. + int32_t staked_era; int8_t numSN; + uint8_t staked_pubkeys[64][33]; + staked_era = STAKED_era(pblock->nTime); + numSN = numStakedNotaries(staked_pubkeys,staked_era); CCoinsViewCache view(pcoinsTip); uint32_t expired; uint64_t commission; @@ -249,13 +259,14 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 // Priority order to process transactions list vOrphan; // list memory doesn't move map > mapDependers; - bool fPrintPriority = GetBoolArg("-printpriority", false); + bool fPrintPriority = GetBoolArg("-printpriority", true); // This vector will be sorted into a priority queue: vector vecPriority; vecPriority.reserve(mempool.mapTx.size() + 1); // now add transactions from the mem pool + int32_t Notarisations = 0; for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) { @@ -329,22 +340,33 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 nTotalIn += nValueIn; int nConf = nHeight - coins->nHeight; - - // This is to test is a tx is a notarisation and assign it max priotity. - if ( fToCryptoAddress && NOTARYADDRS[0][0] != 0 && NUM_NOTARIES != 0 ) + + uint8_t *script; int32_t scriptlen; uint256 hash; CTransaction tx1; + // loop over notaries array and extract index of signers. + if ( fToCryptoAddress && staked_pubkeys[0][0] != 0 && GetTransaction(txin.prevout.hash,tx1,hash,false) ) { - uint256 hash; CTransaction tx1; CTxDestination address; - if ( GetTransaction(txin.prevout.hash,tx1,hash,false) && (ExtractDestination(tx1.vout[txin.prevout.n].scriptPubKey, address)) ) + for (int8_t i = 0; i < numSN; i++) { - for (int i = 0; i < NUM_NOTARIES; i++) - if ( strcmp(NOTARYADDRS[i],CBitcoinAddress(address).ToString().c_str()) == 0 ) - numNotaryVins++; + script = (uint8_t *)&tx1.vout[txin.prevout.n].scriptPubKey[0]; + scriptlen = (int32_t)tx1.vout[txin.prevout.n].scriptPubKey.size(); + if ( scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[i],33) == 0 ) + { + numNotaryVins++; + if ( Notarisations == 0 ) + { + // Until we get a valid notarization this will always be 0. + // We can add the index of each notary to vector, and clear it if this notarisation is not valid later on. + NotarisationNotaries.push_back(i); + } + } } } dPriority += (double)nValueIn * nConf; } - if ( NUM_NOTARIES != 0 && numNotaryVins >= NUM_NOTARIES / 5 ) + if ( numSN != 0 && numNotaryVins >= numSN / 5 ) fNotarisation = true; + else + NotarisationNotaries.clear(); nTotalIn += tx.GetShieldedValueIn(); } @@ -360,16 +382,27 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize); - if (fNotarisation) { + if (fNotarisation) + { dPriority = 1e16; - //fprintf(stderr, "Notarisation.%s set to maximum priority.\n",hash.ToString().c_str()); + Notarisations++; + fNotarisationBlock = true; + fprintf(stderr, "Notarisation[%i] %s set to maximum priority\n",Notarisations,hash.ToString().c_str()); + } + else if ( dPriority == 1e16 ) + { + dPriority -= 10; + // make sure notarisation is tx[1] in block. + // Need to check this? Tried sapling tx and it was not set to max priotity, maybe missing something. } if (porphan) { porphan->dPriority = dPriority; porphan->feeRate = feeRate; } - else + else if ( fNotarisation && Notarisations != 1 && is_STAKED(ASSETCHAINS_SYMBOL) != 0) + continue; // If we have added a notarisation already skip the next one. There can only be one per block. + else vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx()))); } @@ -637,7 +670,17 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 txNew.vout[0].scriptPubKey = CScriptExt().PayToScriptHash(CScriptID(opretScript)); txNew.vout[1].scriptPubKey = CScriptExt().OpReturnScript(opretScript, OPRETTYPE_TIMELOCK); txNew.vout[1].nValue = 0; - } // timelocks and commissions are currently incompatible due to validation complexity of the combination + // timelocks and commissions are currently incompatible due to validation complexity of the combination + } + else if ( fNotarisationBlock && ASSETCHAINS_NOTARY_PAY != 0 ) + { + // This block contains a valid notarisation as best as we can know. We cant check this 100% until we try to connect block. + // This assumes notaries are not going to collude to create invalid notarisations. + // If they did this, then the block would be invalid, and all kinds of werid things will happen. + // We can test this, and see what happens, if its unreliable, we will need to create a CC contract. + uint64_t totalsats = komodo_notarypay(txNew, NotarisationNotaries, pblock->nTime); + fprintf(stderr, "Created notary payment coinbase totalsat.%lu\n",totalsats); + } pblock->vtx[0] = txNew; pblocktemplate->vTxFees[0] = -nFees; diff --git a/src/notaries_staked.cpp b/src/notaries_staked.cpp index 9dcba0653..23bc0f8fd 100644 --- a/src/notaries_staked.cpp +++ b/src/notaries_staked.cpp @@ -21,7 +21,9 @@ int8_t is_STAKED(const char *chain_name) { else if ( (strncmp(chain_name, "LABS", 4) == 0) ) STAKED = 2; else if ( (strcmp(chain_name, "CFEK") == 0) || (strncmp(chain_name, "CFEK", 4) == 0) ) - STAKED = 3; + STAKED = 3; + else if ( (strcmp(chain_name, "NOTARYTEST") == 0) ) + STAKED = 4; else if ( (strcmp(chain_name, "THIS_CHAIN_IS_BANNED") == 0) ) STAKED = 255; // This means that all notarisations for chains that are in 255 group are invalid. doneinit = 1; From abb78c279fc40dfb45266a8607be4082503923d7 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Wed, 30 Jan 2019 00:39:16 +0800 Subject: [PATCH 02/12] fix min sigs --- src/komodo_bitcoind.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 3187099c7..e7677b25d 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -2047,7 +2047,7 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) if ( slowflag != 0 && komodo_checknotarypay(pblock,height) < 0 ) { fprintf(stderr, "Komodo notary pay validation failed.%i\n",height); - return(0); + return(0); // skip validation } else { @@ -2055,13 +2055,13 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) if ( !komodo_is_notarytx(pblock->vtx[1]) == 1 ) { fprintf(stderr, "notarisation is not to crypto address.%i\n",height); - return(0); + return(0); // skip validatiuon } // Check min sigs. - if ( pblock->vtx[1].vin.size() < num_notaries_STAKED[STAKED_era(pblock->nTime)] ) + if ( pblock->vtx[1].vin.size() < (num_notaries_STAKED[STAKED_era(pblock->nTime)]/5) ) { fprintf(stderr, "block does not meet minsigs .%i\n",height); - return(0); + return(0); // skip validation } } } From 84500049345ffe92dbd6affc60e49ce8202b6d21 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Wed, 30 Jan 2019 12:14:51 +0800 Subject: [PATCH 03/12] limit some prints to -ac_notarypay --- src/komodo.h | 2 +- src/main.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/komodo.h b/src/komodo.h index 9978e8588..f8575ade8 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -695,7 +695,7 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr } else if ( ASSETCHAINS_SYMBOL[0] == 0 && matched != 0 && notarized != 0 && validated != 0 ) komodo_rwccdata((char *)"KMD",1,&ccdata,0); - else + else if ( ASSETCHAINS_NOTARY_PAY != 0 ) { fprintf(stderr, "NOT matched NOTARISATION\n"); return (-2); diff --git a/src/main.cpp b/src/main.cpp index 69790a72e..098b8c388 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3696,9 +3696,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin //FlushStateToDisk(); int tmp = komodo_connectblock(pindex,*(CBlock *)&block); // != block-nVersion-7000000; - if ( tmp > 0 ) + if ( ASSETCHAINS_NOTARY_PAY != 0 && tmp > 0 ) { - printf("VALID NOTARISATION connect block.%i tx.%i\n NOT VALIDATING HERE YET!",pindex->GetHeight(),tmp); + printf("VALID NOTARISATION connect block.%i tx.%i\n NOT VALIDATING HERE YET!\n",pindex->GetHeight(),tmp); + if ( tmp != 1 ) + printf("INVALID NOTARISATION notarisation tx is not in vtx[1].\n"; } return true; } From 87a1f9f0003c0b30c0315397e93b2e4c656d751e Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Wed, 30 Jan 2019 12:27:56 +0800 Subject: [PATCH 04/12] fix ) --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 098b8c388..2d5134b4b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3700,7 +3700,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin { printf("VALID NOTARISATION connect block.%i tx.%i\n NOT VALIDATING HERE YET!\n",pindex->GetHeight(),tmp); if ( tmp != 1 ) - printf("INVALID NOTARISATION notarisation tx is not in vtx[1].\n"; + printf("INVALID NOTARISATION notarisation tx is not in vtx[1].\n"); } return true; } From 14b64d13fea3e40a6e245d12a1bf3e61e25f72fa Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Wed, 30 Jan 2019 16:55:04 +0800 Subject: [PATCH 05/12] assetchains_algo in getinfo --- src/rpc/misc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 5e919b9bb..180403e00 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -79,7 +79,7 @@ int8_t StakedNotaryID(std::string ¬aryname, char *Raddress); #define VERUS_VERSION "0.4.0g" extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; extern uint32_t ASSETCHAINS_CC; -extern uint32_t ASSETCHAINS_MAGIC; +extern uint32_t ASSETCHAINS_MAGIC,ASSETCHAINS_ALGO; extern uint64_t ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY; extern int32_t ASSETCHAINS_LWMAPOS,ASSETCHAINS_SAPLING,ASSETCHAINS_STAKED; extern uint64_t ASSETCHAINS_ENDSUBSIDY[],ASSETCHAINS_REWARD[],ASSETCHAINS_HALVING[],ASSETCHAINS_DECAY[]; @@ -319,6 +319,8 @@ UniValue getinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("staked", ASSETCHAINS_STAKED)); if ( ASSETCHAINS_LWMAPOS != 0 ) obj.push_back(Pair("veruspos", ASSETCHAINS_LWMAPOS)); + if ( ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH ) + obj.push_back(Pair("algo",ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO])); } return obj; } From cce73b01a767aed3d4cb31757e6c1d0863433940 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Fri, 1 Feb 2019 04:01:16 +0800 Subject: [PATCH 06/12] new tempfile rotation. --- src/komodo_utils.h | 1 - src/main.cpp | 150 ++++++++++++++++++++++++++++++++------------- src/main.h | 2 +- 3 files changed, 109 insertions(+), 44 deletions(-) diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 4dbf49637..fd312e527 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1749,7 +1749,6 @@ void komodo_args(char *argv0) printf("ASSETCHAINS_LASTERA, if specified, must be between 1 and %u. ASSETCHAINS_LASTERA set to %lu\n", ASSETCHAINS_MAX_ERAS, ASSETCHAINS_LASTERA); } ASSETCHAINS_LASTERA -= 1; - printf("ASSETCHAINS_LASTERA = %lu\n", ASSETCHAINS_LASTERA); ASSETCHAINS_TIMELOCKGTE = (uint64_t)GetArg("-ac_timelockgte", _ASSETCHAINS_TIMELOCKOFF); ASSETCHAINS_TIMEUNLOCKFROM = GetArg("-ac_timeunlockfrom", 0); diff --git a/src/main.cpp b/src/main.cpp index 2d5134b4b..074ad81ac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -187,6 +187,8 @@ namespace { std::vector vinfoBlockFile,tmpBlockFiles; int nLastBlockFile = 0; int nLastTmpFile = 0; + unsigned int maxTempFileSize0 = MAX_TEMPFILE_SIZE; + unsigned int maxTempFileSize1 = MAX_TEMPFILE_SIZE; /** Global flag to indicate we should check to see if there are * block/undo files that should be deleted. Set on startup * or if we allocate more file space when we're in prune mode @@ -3639,7 +3641,15 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin setDirtyBlockIndex.insert(pindex); } - ConnectNotarisations(block, pindex->GetHeight()); + ConnectNotarisations(block, pindex->GetHeight()); // MoMoM notarisation DB. + + int notarisationTx = komodo_connectblock(pindex,*(CBlock *)&block); // dPoW state update. + if ( ASSETCHAINS_NOTARY_PAY != 0 && notarisationTx > 0 ) + { + printf("VALID NOTARISATION connect block.%i tx.%i\n",pindex->GetHeight(),notarisationTx); + if ( notarisationTx != 1 ) + printf("INVALID: notarisation tx is not in vtx[1].\n"); + } if (fTxIndex) if (!pblocktree->WriteTxIndex(vPos)) @@ -3695,13 +3705,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001); //FlushStateToDisk(); - int tmp = komodo_connectblock(pindex,*(CBlock *)&block); // != block-nVersion-7000000; - if ( ASSETCHAINS_NOTARY_PAY != 0 && tmp > 0 ) - { - printf("VALID NOTARISATION connect block.%i tx.%i\n NOT VALIDATING HERE YET!\n",pindex->GetHeight(),tmp); - if ( tmp != 1 ) - printf("INVALID NOTARISATION notarisation tx is not in vtx[1].\n"); - } return true; } @@ -4618,7 +4621,7 @@ bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, u std::vector *ptr; int *lastfilep; LOCK(cs_LastBlockFile); - unsigned int nFile; + unsigned int nFile,maxTempFileSize; if ( tmpflag != 0 ) { @@ -4628,6 +4631,10 @@ bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, u if (tmpBlockFiles.size() <= nFile) { tmpBlockFiles.resize(nFile + 1); } + if ( nFile == 0 ) + maxTempFileSize = maxTempFileSize0; + else if ( nFile == 1 ) + maxTempFileSize = maxTempFileSize1; } else { @@ -4638,49 +4645,86 @@ bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, u vinfoBlockFile.resize(nFile + 1); } } + if (!fKnown) { - while ( (*ptr)[nFile].nSize + nAddSize >= ((tmpflag != 0) ? MAX_TEMPFILE_SIZE : MAX_BLOCKFILE_SIZE) ) { + bool tmpfileflag = false; + while ( (*ptr)[nFile].nSize + nAddSize >= ((tmpflag != 0) ? maxTempFileSize : MAX_BLOCKFILE_SIZE) ) { + if ( tmpflag != 0 && tmpfileflag ) + break; nFile++; if ((*ptr).size() <= nFile) { (*ptr).resize(nFile + 1); } + tmpfileflag = true; } pos.nFile = nFile + tmpflag*TMPFILE_START; pos.nPos = (*ptr)[nFile].nSize; - if ( 0 && tmpflag != 0 ) - fprintf(stderr,"pos.nFile %d nPos %u\n",pos.nFile,pos.nPos); } - if (nFile != *lastfilep) { if (!fKnown) { LogPrintf("Leaving block file %i: %s\n", nFile, (*ptr)[nFile].ToString()); } FlushBlockFile(!fKnown); - //fprintf(stderr, "nFile = %i size.%li\n",nFile,tmpBlockFiles.size()); - if ( tmpflag != 0 && tmpBlockFiles.size() >= 4 ) + //fprintf(stderr, "nFile = %i size.%li maxTempFileSize0.%u maxTempFileSize1.%u\n",nFile,tmpBlockFiles.size(),maxTempFileSize0,maxTempFileSize1); + if ( tmpflag != 0 && tmpBlockFiles.size() >= 3 ) { - if ( nFile == 1 ) + if ( nFile == 1 ) // Trying to get to second temp file. { - PruneOneBlockFile(true,TMPFILE_START+2); - tmpBlockFiles[2].SetNull(); - LogPrintf("Reset tempfile 2\n"); + if (!PruneOneBlockFile(true,TMPFILE_START+1)) + { + // file 1 is not ready to be used yet increase file 0's size. + fprintf(stderr, "Cant clear file 1!\n"); + // We will reset the position to the end of the first file, even if its over max size. + nFile = 0; + pos.nFile = TMPFILE_START; + pos.nPos = (*ptr)[0].nSize; + // Increase temp file one's max size by a chunk, so we wait a reasonable time to recheck the other file. + maxTempFileSize0 += BLOCKFILE_CHUNK_SIZE; + } + else + { + // The file 1 is able to be used now. Reset max size, and set nfile to use file 1. + fprintf(stderr, "CLEARED file 1!\n"); + maxTempFileSize0 = MAX_TEMPFILE_SIZE; + nFile = 1; + tmpBlockFiles[1].SetNull(); + pos.nFile = TMPFILE_START+1; + pos.nPos = (*ptr)[1].nSize; + boost::filesystem::remove(GetBlockPosFilename(pos, "blk")); + LogPrintf("Prune: deleted temp blk (%05u)\n",nFile); + } + if ( 0 && tmpflag != 0 ) + fprintf(stderr,"pos.nFile %d nPos %u\n",pos.nFile,pos.nPos); } - else if ( nFile == 2 ) + else if ( nFile == 2 ) // Trying to get to third temp file. { - PruneOneBlockFile(true,TMPFILE_START+3); - tmpBlockFiles[3].SetNull(); - LogPrintf("Reset tempfile 3\n"); + if (!PruneOneBlockFile(true,TMPFILE_START)) + { + fprintf(stderr, "Cant clear file 0!\n"); + // We will reset the position to the end of the second block file, even if its over max size. + nFile = 1; + pos.nFile = TMPFILE_START+1; + pos.nPos = (*ptr)[1].nSize; + // Increase temp file one's max size by a chunk, so we wait a reasonable time to recheck the other file. + maxTempFileSize1 += BLOCKFILE_CHUNK_SIZE; + } + else + { + // The file 0 is able to be used now. Reset max size, and set nfile to use file 0. + fprintf(stderr, "CLEARED file 0!\n"); + maxTempFileSize1 = MAX_TEMPFILE_SIZE; + nFile = 0; + tmpBlockFiles[0].SetNull(); + pos.nFile = TMPFILE_START; + pos.nPos = (*ptr)[0].nSize; + boost::filesystem::remove(GetBlockPosFilename(pos, "blk")); + LogPrintf("Prune: deleted temp blk (%05u)\n",nFile); + } + if ( 0 && tmpflag != 0 ) + fprintf(stderr,"pos.nFile %d nPos %u\n",pos.nFile,pos.nPos); } } - if ( tmpflag != 0 && nFile == 3 ) - { - PruneOneBlockFile(true,TMPFILE_START); - tmpBlockFiles[0].SetNull(); - PruneOneBlockFile(true,TMPFILE_START+1); - tmpBlockFiles[1].SetNull(); - nFile = 0; - LogPrintf("Reset tempfile 0 and 1\n"); - } + //fprintf(stderr, "nFile = %i size.%li maxTempFileSize0.%u maxTempFileSize1.%u\n",nFile,tmpBlockFiles.size(),maxTempFileSize0,maxTempFileSize1); sleep(30); *lastfilep = nFile; //fprintf(stderr, "*lastfilep = %i\n",*lastfilep); } @@ -5512,32 +5556,53 @@ uint64_t CalculateCurrentUsage() } /* Prune a block file (modify associated database entries)*/ -void PruneOneBlockFile(bool tempfile, const int fileNumber) +bool PruneOneBlockFile(bool tempfile, const int fileNumber) { + uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height; + notarized_height = komodo_notarized_height(&prevMoMheight,¬arized_hash,¬arized_desttxid); //fprintf(stderr, "pruneblockfile.%i\n",fileNumber); sleep(15); - for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) { + for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) + { CBlockIndex* pindex = it->second; - if (pindex && pindex->nFile == fileNumber) { + if (pindex && pindex->nFile == fileNumber) + { + if ( tempfile && (pindex->nStatus & BLOCK_IN_TMPFILE != 0) ) + { + if ( chainActive.Contains(pindex) ) + { + // Block is in main chain so we cant clear this file! + return(false); + } + if ( pindex->GetHeight() > notarized_height ) // Need to check this, does an invalid block have a height? + { + // This blocks height is not older than last notarization so it can be reorged into the main chain. + // We cant clear this file! + return(false); + } + else + { + // Block is not in main chain and is older than last notarised block so its safe for removal. + fprintf(stderr, "Block [%i] in tempfile.%i We can clear this block!\n",pindex->GetHeight(),fileNumber); + // Add index to list and remove after loop? + } + } pindex->nStatus &= ~BLOCK_HAVE_DATA; pindex->nStatus &= ~BLOCK_HAVE_UNDO; pindex->nFile = 0; pindex->nDataPos = 0; pindex->nUndoPos = 0; setDirtyBlockIndex.insert(pindex); - if (pindex->nStatus & BLOCK_IN_TMPFILE != 0 ) - { - // We should be able to clear these blocks from the index as they are not in the main chains block files. - fprintf(stderr, "Block still in tempfile.%i\n",fileNumber); - } // Prune from mapBlocksUnlinked -- any block we prune would have // to be downloaded again in order to consider its chain, at which // point it would be considered as a candidate for // mapBlocksUnlinked or setBlockIndexCandidates. std::pair::iterator, std::multimap::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev); - while (range.first != range.second) { + while (range.first != range.second) + { std::multimap::iterator it = range.first; range.first++; - if (it->second == pindex) { + if (it->second == pindex) + { mapBlocksUnlinked.erase(it); } } @@ -5546,6 +5611,7 @@ void PruneOneBlockFile(bool tempfile, const int fileNumber) if (!tempfile) vinfoBlockFile[fileNumber].SetNull(); setDirtyFileInfo.insert(fileNumber); + return(true); } diff --git a/src/main.h b/src/main.h index 35de3f4de..f12bcb8cd 100644 --- a/src/main.h +++ b/src/main.h @@ -808,7 +808,7 @@ bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHea bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos,bool checkPOW); bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW); bool RemoveOrphanedBlocks(int32_t notarized_height); -void PruneOneBlockFile(bool tempfile, const int fileNumber); +bool PruneOneBlockFile(bool tempfile, const int fileNumber); /** Functions for validating blocks and updating the block tree */ From 1f62670ea2224c942d86a28a972e6b7f96ec2522 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Fri, 1 Feb 2019 16:47:43 +0800 Subject: [PATCH 07/12] See comment for test plan. Adds Validation --- src/komodo_bitcoind.h | 21 +++++++++++---------- src/main.cpp | 7 +++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index e7677b25d..e679c4084 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1775,6 +1775,7 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height) uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &NotarisationNotaries, uint32_t timestamp) { // fetch notary pubkey array. + // Need a better/safer way for notaries era, should really be height based rather than timestamp? uint64_t total = 0; int32_t staked_era; int8_t numSN; uint8_t staked_pubkeys[64][33]; @@ -1783,6 +1784,7 @@ uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &Notar // resize coinbase vouts to number of notary nodes +1 for coinbase itself. txNew.vout.resize(NotarisationNotaries.size()+1); // loop over notarisation vins and add transaction to coinbase. + // Commented prints here can be used to verify manually the pubkeys match. for (int8_t n = 0; n < NotarisationNotaries.size(); n++) { uint8_t *ptr; @@ -1796,7 +1798,7 @@ uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &Notar } ptr[34] = OP_CHECKSIG; //fprintf(stderr," set notary %i PUBKEY33 into vout[%i]\n",NotarisationNotaries[n],n+1); - txNew.vout[n+1].nValue = ASSETCHAINS_NOTARY_PAY; // ASSETCHAINS_NOTARY_PAY + txNew.vout[n+1].nValue = ASSETCHAINS_NOTARY_PAY; total += txNew.vout[n+1].nValue; } return(total); @@ -1812,8 +1814,7 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) numSN = numStakedNotaries(staked_pubkeys,staked_era); uint8_t *script; int32_t scriptlen; - // loop over notaries array and extract index of signers. - + // Loop notarisation, and create the coinbase tx, with the same function the miner uses. BOOST_FOREACH(const CTxIn& txin, pblock->vtx[1].vin) { uint256 hash; CTransaction tx1; @@ -1836,6 +1837,7 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) int8_t n = 0, i = 0, matches = 0; uint64_t total = 0; //fprintf(stderr, "txNew.vout size = %li\n",txNew.vout.size()); + // Check the created coinbase is equal to the coinbase the miner submitted in the block. BOOST_FOREACH(const CTxOut& txout, txNew.vout) { if ( n == 0 ) @@ -1845,7 +1847,6 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) } script = (uint8_t *)&txout.scriptPubKey[0]; scriptlen = (int32_t)txout.scriptPubKey.size(); - // ASSETCHAINS_NOTARY_PAY = nValue! if ( txout.nValue == ASSETCHAINS_NOTARY_PAY && scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[NotarisationNotaries[n-1]],33) == 0 ) { matches++; @@ -2047,25 +2048,25 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) if ( slowflag != 0 && komodo_checknotarypay(pblock,height) < 0 ) { fprintf(stderr, "Komodo notary pay validation failed.%i\n",height); - return(0); // skip validation + return(-1); } else { - // Check the notarisation tx is to the crypto address and meets min sigs. + // Check the notarisation tx is to the crypto address. if ( !komodo_is_notarytx(pblock->vtx[1]) == 1 ) { fprintf(stderr, "notarisation is not to crypto address.%i\n",height); - return(0); // skip validatiuon + return(-1); } // Check min sigs. if ( pblock->vtx[1].vin.size() < (num_notaries_STAKED[STAKED_era(pblock->nTime)]/5) ) { - fprintf(stderr, "block does not meet minsigs .%i\n",height); - return(0); // skip validation + fprintf(stderr, "block notarization does not meet minsigs .%i\n",height); + return(-1); } } } - + //fprintf(stderr,"komodo_checkPOW possible.%d slowflag.%d ht.%d notaryid.%d failed.%d\n",possible,slowflag,height,notaryid,failed); if ( failed != 0 && possible == 0 && notaryid < 0 ) return(-1); diff --git a/src/main.cpp b/src/main.cpp index 074ad81ac..99fb44147 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3579,10 +3579,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin uint64_t notarypaycheque = komodo_checknotarypay((CBlock *)&block,(int32_t)pindex->GetHeight()); if ( notarypaycheque > 0 ) blockReward += notarypaycheque; - else if ( is_STAKED(ASSETCHAINS_SYMBOL) == 4 && IS_STAKED_NOTARY > 0 ) - blockReward += 999999999999999; // Notaries can validate any block for now. else - return state.DoS(100, error("ConnectBlock(): Notary Pay exceeds coinbase (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward), + return state.DoS(100, error("ConnectBlock(): Notary Pay exceeds the amount allowed! (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward), REJECT_INVALID, "bad-cb-amount"); } if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->GetHeight() == 1 && block.vtx[0].GetValueOut() != blockReward) @@ -3648,7 +3646,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin { printf("VALID NOTARISATION connect block.%i tx.%i\n",pindex->GetHeight(),notarisationTx); if ( notarisationTx != 1 ) - printf("INVALID: notarisation tx is not in vtx[1].\n"); + return state.DoS(100, error("ConnectBlock(): Notarisation is not in TX position 1! Invalid Block!"), + REJECT_INVALID, "bad-notarization-position"); } if (fTxIndex) From f82808e03641d1b6787887a8e1abf2914c1d3ee6 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Fri, 1 Feb 2019 18:38:55 +0800 Subject: [PATCH 08/12] z_mergetoaddress changes to enable merge of coinbase's, while skipping iguana utxos. --- src/wallet/rpcwallet.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 50aeb2f27..70696d4f5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4777,7 +4777,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) + strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT) + ") Limit on the maximum number of UTXOs to merge. Set to 0 to use node option -mempooltxinputlimit (before Overwinter), or as many as will fit in the transaction (after Overwinter).\n" "4. shielded_limit (numeric, optional, default=" + strprintf("%d Sprout or %d Sapling Notes", MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT, MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT) + ") Limit on the maximum number of notes to merge. Set to 0 to merge as many as will fit in the transaction.\n" - "5. maximum_utxo_size (numeric, optional) eg, 0.0001 anything under 10000 satoshies will be merged, ignores p2pk utxo!\n" + "5. maximum_utxo_size (numeric, optional) eg, 0.0001 anything under 10000 satoshies will be merged, ignores 10,000 sat p2pk utxo that iguana uses, and merges coinbase utxo.\n" "6. \"memo\" (string, optional) Encoded as hex. When toaddress is a z-addr, this will be stored in the memo field of the new note.\n" "\nResult:\n" @@ -4960,7 +4960,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) if (useAnyUTXO || taddrs.size() > 0) { // Get available utxos vector vecOutputs; - pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, false); + pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, maximum_utxo_size != 0 ? true : false); // Find unspent utxos and update estimated size for (const COutput& out : vecOutputs) { @@ -4981,14 +4981,13 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) CAmount nValue = out.tx->vout[out.i].nValue; - if (maximum_utxo_size != 0) { - if (nValue > maximum_utxo_size) { - continue; - } else { - if (out.tx->vout[out.i].scriptPubKey.size() == 35 && nValue == 10000) { - continue; - } - } + if (maximum_utxo_size != 0) + { + //fprintf(stderr, "utxo txid.%s vout.%i nValue.%li scriptpubkeylength.%i\n",out.tx->GetHash().ToString().c_str(),out.i,nValue,out.tx->vout[out.i].scriptPubKey.size()); + if (nValue > maximum_utxo_size) + continue; + if (nValue == 10000 && out.tx->vout[out.i].scriptPubKey.size() == 35) + continue; } utxoCounter++; @@ -5093,10 +5092,11 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) size_t numUtxos = utxoInputs.size(); size_t numNotes = sproutNoteInputs.size() + saplingNoteInputs.size(); + fprintf(stderr, "num utxos.%li\n", numUtxos); if (numUtxos < 2 && numNotes == 0) { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Could not find any funds to merge."); } - + // Sanity check: Don't do anything if: // - We only have one from address // - It's equal to toaddress From 0ee5e12f0810dd211bb8868fb7f192136b9ed46e Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sun, 3 Feb 2019 02:37:04 +0800 Subject: [PATCH 09/12] New method of ac_notarypay --- src/komodo.h | 75 ++++++++++++++----------- src/komodo_bitcoind.h | 128 ++++++++++++++++++++++++++++++++++-------- src/main.cpp | 46 +++++++++------ src/miner.cpp | 18 +++--- 4 files changed, 187 insertions(+), 80 deletions(-) diff --git a/src/komodo.h b/src/komodo.h index f8575ade8..7860863d2 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -37,7 +37,7 @@ 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(CBlockIndex *pindex,CBlock& block); +int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block); #include "komodo_structs.h" #include "komodo_globals.h" @@ -531,7 +531,7 @@ int32_t komodo_validate_chain(uint256 srchash,int32_t notarized_height) } else return(1); } -int32_t komodo_voutupdate(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_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) { static uint256 zero; static FILE *signedfp; int32_t opretlen,nid,offset,k,MoMdepth,matched,len = 0; uint256 MoM,srchash,desttxid; uint8_t crypto777[33]; struct komodo_state *sp; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; @@ -616,7 +616,7 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr if ( j == 1 && opretlen >= len+offset-opoffset ) { memset(&MoMoMdata,0,sizeof(MoMoMdata)); - if ( matched == 0 && bitweight(signedmask) >= KOMODO_MINRATIFY ) + if ( matched == 0 && signedmask != 0 && bitweight(signedmask) >= KOMODO_MINRATIFY ) notarized = 1; if ( strcmp("PIZZA",ccdata.symbol) == 0 || strncmp("TXSCL",ccdata.symbol,5) == 0 ) notarized = 1; @@ -685,7 +685,7 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr else { komodo_rwccdata(ASSETCHAINS_SYMBOL,1,&ccdata,&MoMoMdata); - if ( matched != 0 ) + if ( !fJustCheck && matched != 0 ) printf("[%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); } if ( MoMoMdata.pairs != 0 ) @@ -695,13 +695,10 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr } else if ( ASSETCHAINS_SYMBOL[0] == 0 && matched != 0 && notarized != 0 && validated != 0 ) komodo_rwccdata((char *)"KMD",1,&ccdata,0); - else if ( ASSETCHAINS_NOTARY_PAY != 0 ) - { - fprintf(stderr, "NOT matched NOTARISATION\n"); - return (-2); - } if ( matched != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height ) { + if ( fJustCheck ) + return(-2); sp->NOTARIZED_HEIGHT = *notarizedheightp; sp->NOTARIZED_HASH = srchash; sp->NOTARIZED_DESTTXID = desttxid; @@ -744,7 +741,7 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr } else if ( matched != 0 && i == 0 && j == 1 && opretlen == 149 ) { - if ( notaryid >= 0 && notaryid < 64 ) + if ( !fJustCheck && notaryid >= 0 && notaryid < 64 ) komodo_paxpricefeed(height,&scriptbuf[len],opretlen); } else if ( matched != 0 ) @@ -801,18 +798,18 @@ int32_t komodo_notarycmp(uint8_t *scriptPubKey,int32_t scriptlen,uint8_t pubkeys } // int32_t ! -int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block) +int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) { static int32_t hwmheight; int32_t staked_era; static int32_t lastStakedEra; - + std::vector notarisations; uint64_t signedmask,voutmask; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; uint8_t scriptbuf[10001],pubkeys[64][33],rmd160[20],scriptPubKey[35]; uint256 zero,btctxid,txhash; int32_t i,j,k,numnotaries,notarized,scriptlen,isratification,nid,numvalid,specialtx,notarizedheight,notaryid,len,numvouts,numvins,height,txn_count; if ( pindex == 0 ) { fprintf(stderr,"komodo_connectblock null pindex\n"); - return -1; + return(0); } memset(&zero,0,sizeof(zero)); komodo_init(pindex->GetHeight()); @@ -820,13 +817,13 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block) if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) { fprintf(stderr,"unexpected null komodostateptr.[%s]\n",ASSETCHAINS_SYMBOL); - return -1; + return(0); } //fprintf(stderr,"%s connect.%d\n",ASSETCHAINS_SYMBOL,pindex->nHeight); if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 || IS_STAKED_NOTARY > -1 ) { staked_era = STAKED_era(pindex->GetBlockTime()); - if ( staked_era != lastStakedEra ) + if ( !fJustCheck && staked_era != lastStakedEra ) { uint8_t tmp_pubkeys[64][33]; int8_t numSN = numStakedNotaries(tmp_pubkeys,staked_era); @@ -842,8 +839,8 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block) fprintf(stderr, "Staked Notary Protection Active! NotaryID.%d RADD.%s ERA.%d MIN_TX_VALUE.%lu \n",IS_STAKED_NOTARY,NOTARY_ADDRESS.c_str(),staked_era,MIN_RECV_SATS); } } + lastStakedEra = staked_era; } - lastStakedEra = staked_era; } numnotaries = komodo_notaries(pubkeys,pindex->GetHeight(),pindex->GetBlockTime()); calc_rmd160_sha256(rmd160,pubkeys[0],33); @@ -857,11 +854,13 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block) komodo_purge_ccdata((int32_t)pindex->GetHeight()); hwmheight = pindex->GetHeight(); } - komodo_event_rewind(sp,symbol,pindex->GetHeight()); - komodo_stateupdate(pindex->GetHeight(),0,0,0,zero,0,0,0,0,-pindex->GetHeight(),pindex->nTime,0,0,0,0,zero,0); + if (!fJustCheck) + { + komodo_event_rewind(sp,symbol,pindex->GetHeight()); + komodo_stateupdate(pindex->GetHeight(),0,0,0,zero,0,0,0,0,-pindex->GetHeight(),pindex->nTime,0,0,0,0,zero,0); + } } komodo_currentheight_set(chainActive.LastTip()->GetHeight()); - int transaction = 0; if ( pindex != 0 ) { height = pindex->GetHeight(); @@ -869,9 +868,12 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block) for (i=0; i 1) + break; txhash = block.vtx[i].GetHash(); numvouts = block.vtx[i].vout.size(); notaryid = -1; @@ -900,7 +902,7 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block) (numvalid >= KOMODO_MINRATIFY && ASSETCHAINS_SYMBOL[0] != 0) || numvalid > (numnotaries/5) ) { - if ( ASSETCHAINS_SYMBOL[0] != 0) + if ( !fJustCheck && ASSETCHAINS_SYMBOL[0] != 0) { static FILE *signedfp; if ( signedfp == 0 ) @@ -917,7 +919,6 @@ int32_t komodo_connectblock(CBlockIndex *pindex,CBlock& block) fwrite(&signedmask,1,sizeof(signedmask),signedfp); fflush(signedfp); } - transaction = i; printf("[%s] ht.%d txi.%d signedmask.%llx numvins.%d numvouts.%d <<<<<<<<<<< notarized\n",ASSETCHAINS_SYMBOL,height,i,(long long)signedmask,numvins,numvouts); } notarized = 1; @@ -947,9 +948,13 @@ int32_t komodo_connectblock(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(&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()); - if ( notaryid == -2 ) - return(-1); + 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()); + if ( fJustCheck && notaryid == -2 ) + { + // We see a valid notarisation here, save its location. + notarisations.push_back(i); + } + //fprintf(stderr, "notaryid.%i\n",notaryid); if ( 0 && i > 0 ) { for (k=0; kGetHeight() == hwmheight ) + if ( !fJustCheck && pindex->GetHeight() == hwmheight ) komodo_stateupdate(height,0,0,0,zero,0,0,0,0,height,(uint32_t)pindex->nTime,0,0,0,0,zero,0); } else fprintf(stderr,"komodo_connectblock: unexpected null pindex\n"); //KOMODO_INITDONE = (uint32_t)time(NULL); //fprintf(stderr,"%s end connect.%d\n",ASSETCHAINS_SYMBOL,pindex->GetHeight()); - if (notarized = 1) - return(transaction); - else - return(-1); + if (fJustCheck) + { + if (notarisations.size() == 0) + return(0); + if ( notarisations.size() == 1 && notarisations[0] == 1 ) + return(1); + else + return(-1); + } + else return(0); } diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index e679c4084..a139adf90 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1772,17 +1772,67 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height) return(isPOS); } -uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &NotarisationNotaries, uint32_t timestamp) +int32_t komodo_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 *txidp); + +uint64_t komodo_notarypayamount(int32_t height, int64_t numnotaries) +{ + if ( numnotaries == 0 ) + return(0); + // fetch notarised height + int32_t notarizedht,prevMoMheight; uint256 notarizedhash,txid; + uint64_t AmountToPay=0,ret=0; + notarizedht = komodo_notarized_height(&prevMoMheight,¬arizedhash,&txid); + // dont think this can happen, just sanity check. + if ( height == notarizedht ) + return(0); + // how many block since last notarisation. + int32_t n = height - notarizedht; + fprintf(stderr, "blocks since last notarisation: %i\n",n); + // multiply the amount possible to be used for each block by the amount of blocks passed + // to get the total posible to be paid for this notarisation. + AmountToPay = ASSETCHAINS_NOTARY_PAY*n; + //fprintf(stderr, "AmountToPay.%lu\n",AmountToPay); + ret = AmountToPay / numnotaries; + fprintf(stderr, "payment per notary.%lu\n",ret); + return(ret); +} + +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); + +uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &NotarisationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len) { // fetch notary pubkey array. // Need a better/safer way for notaries era, should really be height based rather than timestamp? - uint64_t total = 0; + uint64_t total = 0, AmountToPay = 0; int32_t staked_era; int8_t numSN; uint8_t staked_pubkeys[64][33]; staked_era = STAKED_era(timestamp); numSN = numStakedNotaries(staked_pubkeys,staked_era); // resize coinbase vouts to number of notary nodes +1 for coinbase itself. txNew.vout.resize(NotarisationNotaries.size()+1); + + // Check the notarisation is valid, and extract notarised height. + uint64_t voutmask; + uint8_t scriptbuf[10001]; + int32_t isratification,specialtx,notarizedheight; + + if ( len >= sizeof(uint32_t) && len <= sizeof(scriptbuf) ) + { + memcpy(scriptbuf,script,len); + if ( komodo_voutupdate(true,&isratification,0,scriptbuf,len,height,uint256(),1,1,&voutmask,&specialtx,¬arizedheight,0,1,0,timestamp) == -2 ) + { + fprintf(stderr, "VALID NOTARIZATION ht.%i\n",notarizedheight); + } + else + { + fprintf(stderr, "INVALID NOTARIZATION ht.%i\n",notarizedheight); + return(0); + } + } else return(0); + + // Calcualte the amount to pay. + AmountToPay = komodo_notarypayamount(notarizedheight,NotarisationNotaries.size()); + // loop over notarisation vins and add transaction to coinbase. // Commented prints here can be used to verify manually the pubkeys match. for (int8_t n = 0; n < NotarisationNotaries.size(); n++) @@ -1798,7 +1848,7 @@ uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &Notar } ptr[34] = OP_CHECKSIG; //fprintf(stderr," set notary %i PUBKEY33 into vout[%i]\n",NotarisationNotaries[n],n+1); - txNew.vout[n+1].nValue = ASSETCHAINS_NOTARY_PAY; + txNew.vout[n+1].nValue = AmountToPay; total += txNew.vout[n+1].nValue; } return(total); @@ -1832,35 +1882,69 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) } const CChainParams& chainparams = Params(); const Consensus::Params &consensusParams = chainparams.GetConsensus(); + uint64_t totalsats = 0; CMutableTransaction txNew = CreateNewContextualCMutableTransaction(consensusParams, height); - uint64_t totalsats = komodo_notarypay(txNew, NotarisationNotaries, pblock->nTime); - int8_t n = 0, i = 0, matches = 0; - uint64_t total = 0; - //fprintf(stderr, "txNew.vout size = %li\n",txNew.vout.size()); - // Check the created coinbase is equal to the coinbase the miner submitted in the block. - BOOST_FOREACH(const CTxOut& txout, txNew.vout) + if ( pblock->vtx[1].vout.size() == 2 && pblock->vtx[1].vout[1].nValue == 0 ) { - if ( n == 0 ) + // Get the OP_RETURN for the notarisation + uint8_t *script = (uint8_t *)&pblock->vtx[1].vout[1].scriptPubKey[0]; + int32_t scriptlen = (int32_t)pblock->vtx[1].vout[1].scriptPubKey.size(); + if ( script[0] == OP_RETURN ) + { + totalsats = komodo_notarypay(txNew, NotarisationNotaries, pblock->nTime, height, script, scriptlen); + } + else + { + fprintf(stderr, "vout 2 of notarisation is not OP_RETURN scriptlen.%i\n", scriptlen); + return(-1); + } + } + + // if notarypay fails, because the notarisation is not valid, exit now as txNew was not created. + if ( totalsats == 0 ) + { + fprintf(stderr, "notary pay RETURNED 0!\n"); + return(-1); + } + + int8_t n = 0, i = 0, matches = 0; + uint64_t total = 0, AmountToPay = 0; + + // get the pay amount from the created tx. + AmountToPay = txNew.vout[1].nValue; + + //fprintf(stderr, "txNew.vout size = %li\n",txNew.vout.size()); + // Check the created coinbase pays the correct notaries. + BOOST_FOREACH(const CTxOut& txout, pblock->vtx[0].vout) + { + // skip the coinbase + if ( n == 0 ) { n++; continue; } + // Check the pubkeys match the pubkeys in the notarisation. script = (uint8_t *)&txout.scriptPubKey[0]; scriptlen = (int32_t)txout.scriptPubKey.size(); - if ( txout.nValue == ASSETCHAINS_NOTARY_PAY && scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[NotarisationNotaries[n-1]],33) == 0 ) + if ( scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[NotarisationNotaries[n-1]],33) == 0 ) { - matches++; - total += txout.nValue; - fprintf(stderr, "matched.%i\n", NotarisationNotaries[n-1]); + // check the value is correct + if ( pblock->vtx[0].vout[n].nValue == AmountToPay ) + { + matches++; + total += txout.nValue; + fprintf(stderr, "matched.%i\n", NotarisationNotaries[n-1]); + } + else fprintf(stderr, "NOT MATCHED AmountPaid.%lu AmountToPay.%lu notaryid.%i\n", pblock->vtx[0].vout[n].nValue, AmountToPay, NotarisationNotaries[n-1]); } - n++; + n++; } - if ( matches = n && matches != 0 && total == totalsats ) + if ( matches != 0 && matches == NotarisationNotaries.size() && totalsats == total ) { fprintf(stderr, "VALIDATED.\n" ); return(totalsats); } - return(-1); + return(0); } int64_t komodo_checkcommission(CBlock *pblock,int32_t height) @@ -2043,14 +2127,10 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) return(-1); } } - if( failed == 0 && ASSETCHAINS_NOTARY_PAY != 0 && pblock->vtx[0].vout.size() != 1 ) + if ( failed == 0 && ASSETCHAINS_NOTARY_PAY != 0 && pblock->vtx[0].vout.size() > 1 ) { - if ( slowflag != 0 && komodo_checknotarypay(pblock,height) < 0 ) - { - fprintf(stderr, "Komodo notary pay validation failed.%i\n",height); - return(-1); - } - else + // We check the full validation in ConnectBlock directly to get the amount for coinbase. So just approx here. + if ( slowflag == 0 ) { // Check the notarisation tx is to the crypto address. if ( !komodo_is_notarytx(pblock->vtx[1]) == 1 ) diff --git a/src/main.cpp b/src/main.cpp index 99fb44147..ec79fafbc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3574,14 +3574,32 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin fprintf(stderr,"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_NOTARY_PAY != 0 && block.vtx[0].vout.size() > 1 ) + bool sleepflag = false; + if ( ASSETCHAINS_NOTARY_PAY != 0 ) { - uint64_t notarypaycheque = komodo_checknotarypay((CBlock *)&block,(int32_t)pindex->GetHeight()); - if ( notarypaycheque > 0 ) - blockReward += notarypaycheque; - else - return state.DoS(100, error("ConnectBlock(): Notary Pay exceeds the amount allowed! (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward), - REJECT_INVALID, "bad-cb-amount"); + // do a full block scan to get notarisation position and to enforce 1 notarisation is in block only. + // if notarisation in the block, must be position 1 and the coinbase must pay notaries. + int notarisationTx = komodo_connectblock(true,pindex,*(CBlock *)&block); + // -1 means that more than 1 notarisation is in a block, or the notarisation is not in order. + if ( notarisationTx == -1 ) + return state.DoS(100, error("ConnectBlock(): Notarisation is not in TX position 1! Invalid Block!"), + REJECT_INVALID, "bad-notarization-position"); + // 1 means this block contains a valid notarisation + if ( notarisationTx == 1 ) + { + // Check if the notaries have been paid. + if ( block.vtx[0].vout.size() == 1 ) + return state.DoS(100, error("ConnectBlock(): Notary has not been paid!"), + REJECT_INVALID, "bad-cb-amount"); + // calculate the notaries compensation and validate the amounts and pubkeys are correct. + uint64_t notarypaycheque = komodo_checknotarypay((CBlock *)&block,(int32_t)pindex->GetHeight()); + fprintf(stderr, "notarypaycheque.%lu\n", notarypaycheque); + if ( notarypaycheque > 0 ) + blockReward += notarypaycheque; + else + return state.DoS(100, error("ConnectBlock(): Notary pay Validation Failed!"), + REJECT_INVALID, "bad-cb-amount"); + } } if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->GetHeight() == 1 && block.vtx[0].GetValueOut() != blockReward) { @@ -3592,6 +3610,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin { if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->GetHeight() >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward ) { + //fprintf(stderr, "coinbase pays too much\n"); + //sleepflag = true; return state.DoS(100, error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)", block.vtx[0].GetValueOut(), blockReward), @@ -3641,15 +3661,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin ConnectNotarisations(block, pindex->GetHeight()); // MoMoM notarisation DB. - int notarisationTx = komodo_connectblock(pindex,*(CBlock *)&block); // dPoW state update. - if ( ASSETCHAINS_NOTARY_PAY != 0 && notarisationTx > 0 ) - { - printf("VALID NOTARISATION connect block.%i tx.%i\n",pindex->GetHeight(),notarisationTx); - if ( notarisationTx != 1 ) - return state.DoS(100, error("ConnectBlock(): Notarisation is not in TX position 1! Invalid Block!"), - REJECT_INVALID, "bad-notarization-position"); - } - if (fTxIndex) if (!pblocktree->WriteTxIndex(vPos)) return AbortNode(state, "Failed to write transaction index"); @@ -3704,6 +3715,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001); //FlushStateToDisk(); + komodo_connectblock(false,pindex,*(CBlock *)&block); // dPoW state update. + if (sleepflag) + sleep(30); return true; } diff --git a/src/miner.cpp b/src/miner.cpp index 4ad70912c..6476a7b48 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -153,7 +153,7 @@ int32_t komodo_is_notarytx(const CTransaction& tx); CScript Marmara_scriptPubKey(int32_t height,CPubKey pk); CScript MarmaraCoinbaseOpret(uint8_t funcid,int32_t height,CPubKey pk); int32_t komodo_is_notarytx(const CTransaction& tx); -uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &NotarisationNotaries, uint32_t timestamp); +uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &NotarisationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len); CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake) { @@ -672,14 +672,16 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 txNew.vout[1].nValue = 0; // timelocks and commissions are currently incompatible due to validation complexity of the combination } - else if ( fNotarisationBlock && ASSETCHAINS_NOTARY_PAY != 0 ) + else if ( fNotarisationBlock && ASSETCHAINS_NOTARY_PAY != 0 && pblock->vtx[1].vout.size() == 2 && pblock->vtx[1].vout[1].nValue == 0 ) { - // This block contains a valid notarisation as best as we can know. We cant check this 100% until we try to connect block. - // This assumes notaries are not going to collude to create invalid notarisations. - // If they did this, then the block would be invalid, and all kinds of werid things will happen. - // We can test this, and see what happens, if its unreliable, we will need to create a CC contract. - uint64_t totalsats = komodo_notarypay(txNew, NotarisationNotaries, pblock->nTime); - fprintf(stderr, "Created notary payment coinbase totalsat.%lu\n",totalsats); + // Get the OP_RETURN for the notarisation + uint8_t *script = (uint8_t *)&pblock->vtx[1].vout[1].scriptPubKey[0]; + int32_t scriptlen = (int32_t)pblock->vtx[1].vout[1].scriptPubKey.size(); + if ( script[0] == OP_RETURN ) + { + uint64_t totalsats = komodo_notarypay(txNew, NotarisationNotaries, pblock->nTime, nHeight, script, scriptlen); + fprintf(stderr, "Created notary payment coinbase totalsat.%lu\n",totalsats); + } else fprintf(stderr, "vout 2 of notarisation is not OP_RETURN scriptlen.%i\n", scriptlen); } pblock->vtx[0] = txNew; From c6e5b70f23db45a5d5458e9577e784669d960119 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sun, 3 Feb 2019 02:44:17 +0800 Subject: [PATCH 10/12] fix --- src/komodo_bitcoind.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index a139adf90..2bd97fa68 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1904,7 +1904,7 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) if ( totalsats == 0 ) { fprintf(stderr, "notary pay RETURNED 0!\n"); - return(-1); + return(0); } int8_t n = 0, i = 0, matches = 0; From 52f7cc2caf7d35b6065ec0af09ee2b501fb8a69a Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sun, 3 Feb 2019 12:10:26 +0800 Subject: [PATCH 11/12] Add some better prints/comments, move ac_notarypay validation to before temp file fix, to aviod possible attack vector. --- src/komodo_bitcoind.h | 35 ++++++++++++++++--------- src/main.cpp | 60 +++++++++++++++++++++---------------------- 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 2bd97fa68..6fd3b47b3 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1807,6 +1807,9 @@ uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &Notar int32_t staked_era; int8_t numSN; uint8_t staked_pubkeys[64][33]; staked_era = STAKED_era(timestamp); + // No point going further, no notaries can be paid. + if ( staked_era == 0 ) + return(0); numSN = numStakedNotaries(staked_pubkeys,staked_era); // resize coinbase vouts to number of notary nodes +1 for coinbase itself. txNew.vout.resize(NotarisationNotaries.size()+1); @@ -1821,11 +1824,11 @@ uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &Notar memcpy(scriptbuf,script,len); if ( komodo_voutupdate(true,&isratification,0,scriptbuf,len,height,uint256(),1,1,&voutmask,&specialtx,¬arizedheight,0,1,0,timestamp) == -2 ) { - fprintf(stderr, "VALID NOTARIZATION ht.%i\n",notarizedheight); + fprintf(stderr, "notarypay found VALID NOTARIZATION ht.%i\n",notarizedheight); } else { - fprintf(stderr, "INVALID NOTARIZATION ht.%i\n",notarizedheight); + fprintf(stderr, "notarypay found INVALID NOTARIZATION ht.%i\n",notarizedheight); return(0); } } else return(0); @@ -1861,10 +1864,13 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) int32_t staked_era; int8_t numSN; uint8_t staked_pubkeys[64][33]; staked_era = STAKED_era(timestamp); + // No point going further, no notaries can be paid. + if ( staked_era == 0 ) + return(0); numSN = numStakedNotaries(staked_pubkeys,staked_era); uint8_t *script; int32_t scriptlen; - // Loop notarisation, and create the coinbase tx, with the same function the miner uses. + // Loop over the notarisation and extract the position of the participating notaries in the array of pukeys for this era. BOOST_FOREACH(const CTxIn& txin, pblock->vtx[1].vin) { uint256 hash; CTransaction tx1; @@ -1872,7 +1878,6 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) { for (int8_t i = 0; i < numSN; i++) { - //tx1.vout[txin.prevout.n].scriptPubKey script = (uint8_t *)&tx1.vout[txin.prevout.n].scriptPubKey[0]; scriptlen = (int32_t)tx1.vout[txin.prevout.n].scriptPubKey.size(); if ( scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,staked_pubkeys[i],33) == 0 ) @@ -1891,19 +1896,22 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) int32_t scriptlen = (int32_t)pblock->vtx[1].vout[1].scriptPubKey.size(); if ( script[0] == OP_RETURN ) { + // Create the coinbase tx again, using the extracted data, this is the same function the miner uses, with the same data. + // This allows us to know exactly that the coinbase is correct. totalsats = komodo_notarypay(txNew, NotarisationNotaries, pblock->nTime, height, script, scriptlen); } else { fprintf(stderr, "vout 2 of notarisation is not OP_RETURN scriptlen.%i\n", scriptlen); - return(-1); + return(0); } } // if notarypay fails, because the notarisation is not valid, exit now as txNew was not created. + // This should never happen, as the notarisation is checked before this function is called. if ( totalsats == 0 ) { - fprintf(stderr, "notary pay RETURNED 0!\n"); + fprintf(stderr, "notary pay returned 0!\n"); return(0); } @@ -1913,11 +1921,10 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) // get the pay amount from the created tx. AmountToPay = txNew.vout[1].nValue; - //fprintf(stderr, "txNew.vout size = %li\n",txNew.vout.size()); // Check the created coinbase pays the correct notaries. BOOST_FOREACH(const CTxOut& txout, pblock->vtx[0].vout) { - // skip the coinbase + // skip the coinbase paid to the miner. if ( n == 0 ) { n++; @@ -1933,7 +1940,7 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) { matches++; total += txout.nValue; - fprintf(stderr, "matched.%i\n", NotarisationNotaries[n-1]); + fprintf(stderr, "MATCHED AmountPaid.%lu notaryid.%i\n",AmountToPay,NotarisationNotaries[n-1]); } else fprintf(stderr, "NOT MATCHED AmountPaid.%lu AmountToPay.%lu notaryid.%i\n", pblock->vtx[0].vout[n].nValue, AmountToPay, NotarisationNotaries[n-1]); } @@ -1941,7 +1948,7 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height) } if ( matches != 0 && matches == NotarisationNotaries.size() && totalsats == total ) { - fprintf(stderr, "VALIDATED.\n" ); + fprintf(stderr, "Validated coinbase matches notarisation in tx position 1.\n" ); return(totalsats); } return(0); @@ -2127,6 +2134,10 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) return(-1); } } + // Consensus rule to force miners to mine the notary coinbase payment happens in ConnectBlock + // the default daemon miner, checks the actual vins so the only way this will fail, is if someone changes the miner, + // and then creates txs to the crypto address meeting min sigs and puts it in tx position 1. + // If they go through this effort, the block will still fail at connect block, and will be auto purged by the temp file fix. if ( failed == 0 && ASSETCHAINS_NOTARY_PAY != 0 && pblock->vtx[0].vout.size() > 1 ) { // We check the full validation in ConnectBlock directly to get the amount for coinbase. So just approx here. @@ -2135,13 +2146,13 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) // Check the notarisation tx is to the crypto address. if ( !komodo_is_notarytx(pblock->vtx[1]) == 1 ) { - fprintf(stderr, "notarisation is not to crypto address.%i\n",height); + fprintf(stderr, "notarisation is not to crypto address ht.%i\n",height); return(-1); } // Check min sigs. if ( pblock->vtx[1].vin.size() < (num_notaries_STAKED[STAKED_era(pblock->nTime)]/5) ) { - fprintf(stderr, "block notarization does not meet minsigs .%i\n",height); + fprintf(stderr, "ht.%i does not meet minsigs.%i sigs.%li\n",height,(num_notaries_STAKED[STAKED_era(pblock->nTime)]/5),pblock->vtx[1].vin.size()); return(-1); } } diff --git a/src/main.cpp b/src/main.cpp index ec79fafbc..656cc0a96 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3267,6 +3267,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin auto verifier = libzcash::ProofVerifier::Strict(); auto disabledVerifier = libzcash::ProofVerifier::Disabled(); int32_t futureblock; + CAmount blockReward = 0; // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in if (!CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 ) { @@ -3280,6 +3281,34 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return false; fprintf(stderr,"grandfathered exception, until jan 15th 2019\n"); } + // Do this here before the block is moved to the main block files. + if ( ASSETCHAINS_NOTARY_PAY != 0 && pindex->GetHeight() != 0 ) + { + // do a full block scan to get notarisation position and to enforce 1 notarisation is in block only. + // if notarisation in the block, must be position 1 and the coinbase must pay notaries. + int notarisationTx = komodo_connectblock(true,pindex,*(CBlock *)&block); + // -1 means that more than 1 notarisation is in a block, or the notarisation is not in order. + if ( notarisationTx == -1 ) + return state.DoS(100, error("ConnectBlock(): Notarisation is not in TX position 1! Invalid Block!"), + REJECT_INVALID, "bad-notarization-position"); + // 1 means this block contains a valid notarisation + if ( notarisationTx == 1 ) + { + // Check if the notaries have been paid. + if ( block.vtx[0].vout.size() == 1 ) + return state.DoS(100, error("ConnectBlock(): Notaries have not been paid!"), + REJECT_INVALID, "bad-cb-amount"); + // calculate the notaries compensation and validate the amounts and pubkeys are correct. + uint64_t notarypaycheque = komodo_checknotarypay((CBlock *)&block,(int32_t)pindex->GetHeight()); + fprintf(stderr, "notarypaycheque.%lu\n", notarypaycheque); + if ( notarypaycheque > 0 ) + blockReward += notarypaycheque; + else + return state.DoS(100, error("ConnectBlock(): Notary pay validation failed!"), + REJECT_INVALID, "bad-cb-amount"); + } + } + // Move the block to the main block file, we need this to create the TxIndex in the following loop. if ( (pindex->nStatus & BLOCK_IN_TMPFILE) != 0 ) { unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); @@ -3562,7 +3591,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart; LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001); - CAmount blockReward = nFees + GetBlockSubsidy(pindex->GetHeight(), chainparams.GetConsensus()) + sum; + blockReward += nFees + GetBlockSubsidy(pindex->GetHeight(), chainparams.GetConsensus()) + sum; if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 ) //ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && { uint64_t checktoshis; @@ -3574,33 +3603,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin fprintf(stderr,"checktoshis %.8f vs %.8f numvouts %d\n",dstr(checktoshis),dstr(block.vtx[0].vout[1].nValue),(int32_t)block.vtx[0].vout.size()); } } - bool sleepflag = false; - if ( ASSETCHAINS_NOTARY_PAY != 0 ) - { - // do a full block scan to get notarisation position and to enforce 1 notarisation is in block only. - // if notarisation in the block, must be position 1 and the coinbase must pay notaries. - int notarisationTx = komodo_connectblock(true,pindex,*(CBlock *)&block); - // -1 means that more than 1 notarisation is in a block, or the notarisation is not in order. - if ( notarisationTx == -1 ) - return state.DoS(100, error("ConnectBlock(): Notarisation is not in TX position 1! Invalid Block!"), - REJECT_INVALID, "bad-notarization-position"); - // 1 means this block contains a valid notarisation - if ( notarisationTx == 1 ) - { - // Check if the notaries have been paid. - if ( block.vtx[0].vout.size() == 1 ) - return state.DoS(100, error("ConnectBlock(): Notary has not been paid!"), - REJECT_INVALID, "bad-cb-amount"); - // calculate the notaries compensation and validate the amounts and pubkeys are correct. - uint64_t notarypaycheque = komodo_checknotarypay((CBlock *)&block,(int32_t)pindex->GetHeight()); - fprintf(stderr, "notarypaycheque.%lu\n", notarypaycheque); - if ( notarypaycheque > 0 ) - blockReward += notarypaycheque; - else - return state.DoS(100, error("ConnectBlock(): Notary pay Validation Failed!"), - REJECT_INVALID, "bad-cb-amount"); - } - } if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->GetHeight() == 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), @@ -3716,8 +3718,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin //FlushStateToDisk(); komodo_connectblock(false,pindex,*(CBlock *)&block); // dPoW state update. - if (sleepflag) - sleep(30); return true; } From 1b504fe06681235f5b28bbd2ff25e7ce48ed963e Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sun, 3 Feb 2019 13:42:54 +0800 Subject: [PATCH 12/12] Change ERA to 3 at: (GMT): Sunday, 3 February 2019 9:00:00 AM --- src/notaries_staked.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/notaries_staked.h b/src/notaries_staked.h index b407e6412..2941fd9ac 100644 --- a/src/notaries_staked.h +++ b/src/notaries_staked.h @@ -23,7 +23,7 @@ static const char *iguanaSeeds[8][1] = static const int STAKED_ERA_GAP = 777; static const int NUM_STAKED_ERAS = 4; -static const int STAKED_NOTARIES_TIMESTAMP[NUM_STAKED_ERAS] = {1542964044, 1604222222, 1604233333, 1604244444}; +static const int STAKED_NOTARIES_TIMESTAMP[NUM_STAKED_ERAS] = {1542964044, 1549184400, 1604233333, 1604244444}; // Era array of pubkeys. static const char *notaries_STAKED[NUM_STAKED_ERAS][64][2] = @@ -78,20 +78,22 @@ static const char *notaries_STAKED[NUM_STAKED_ERAS][64][2] = {"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x {"alright", "0285657c689b903218c97f5f10fe1d10ace2ed6595112d9017f54fb42ea1c1dda8" }, //RXmXeQ8LfJK6Y1aTM97cRz9Gu5f6fmR3sg {"webworker01", "031d1fb39ae4dca28965c3abdbd21faa0f685f6d7b87a60561afa7c448343fef6d" }, //RGsQiArk5sTmjXZV9UzGMW5njyvtSnsTN8 - {"CrisF", "03f87f1bccb744d90fdbf7fad1515a98e9fc7feb1800e460d2e7565b88c3971bf3" }, //RMwEpnaVe3cesWbMqqKYPPkaLcDkooTDgZ - {"smk762", "02eacef682d2f86e0103c18f4da46116e17196f3fb8f73ed931acb78e81d8e1aa5" }, // RQVvzJ8gepCDVjhqCAc5Tia1kTmt8KDPL9 - {"jorian", "02150c410a606b898bcab4f083e48e0f98a510e0d48d4db367d37f318d26ae72e3" }, // RFgzxZe2P4RWKx6E9QGPK3rx3TXeWxSqa8 + {"CrisF", "024d19acf0d5de212cdd50326cd143292545d366a71b2b9c6df9f2110de2dfa1f2" }, // RKtAD2kyRRMx4EiG1eeTNprF5h2nmGbzzu + {"smk762", "029f6c1f38c4d6825acb3b4b5147f7992e943b617cdaa0f4f5f36187e239d52d5a" }, // RPy6Xj2LWrxNoEW9YyREDgBZDZZ5qURXBU + {"jorian", "0288e682c1ac449f1b85c4acb2d0bcd216d5df34c15fd18b8a8dd5fa64b8ece8ef" }, // RR1yT5aB19VwFoUCGTW4q4pk4qmhHEEE4t {"TonyL", "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" }, // RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev - {"Emman", "038f642dcdacbdf510b7869d74544dbc6792548d9d1f8d73a999dd9f45f513c935" }, //RN2KsQGW36Ah4NorJDxLJp2xiYJJEzk9Y6 {"CHMEX", "03ed125d1beb118d12ff0a052bdb0cee32591386d718309b2924f2c36b4e7388e6" }, // RF4HiVeuYpaznRPs7fkRAKKYqT5tuxQQTL {"metaphilibert", "0344182c376f054e3755d712361672138660bda8005abb64067eb5aa98bdb40d10" }, // RG28QSnYFADBg1dAVkH1uPGYS6F8ioEUM2 - {"jusoaresf", "02dfb7ed72a23f6d07f0ea2f28192ee174733cc8412ec0f97b073007b78fab6346" }, // RBQGfE5Hxsjm1BPraTxbneRuNasPDuoLnu - {"mylo", "03f6b7fcaf0b8b8ec432d0de839a76598b78418dadd50c8e5594c0e557d914ec09" }, // RXN4hoZkhUkkrnef9nTUDw3E3vVALAD8Kx - {"blackjok3r2", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca - {"blackjok3r3", "03c3e4c0206551dbf3a4b24d18e5d2737080541184211e3bfd2b1092177410b9c2" }, // RMMav2AVse5XHPvDfTzRpMbFhK3GqFmtSN - {"kmdkrazy", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca - {"alrighttest", "02e9dfe248f453b499315a90375e58a1c9ad79f5f3932ecb2205399a0f262d65fc" }, // RBevSstS8JtDXMEFNcJws4QTYN4PcE2VL5 - {"alrighttest1", "03527c7ecd6a8c5db6d685a64e6e18c1edb49e2f057a434f56c3f1253a26e9c6a2" }, // RBw2jNU3dnGk86ZLqPMadJwRwg3NU8eC6s + {"greentea", "02054c14ae81838a063d22a75eaa3c961415f6825a57c8b8e4148d19dad64f128e" }, // REF7R76WpL1v7nSXjjiNHtRa2xYtq5qk1p + {"CMaurice", "025830ce81bd1301fb67d5872344efa7a9ff99ae85fe1234f18c085db9072b740f" }, // RX7pXUaV24xFn6DVKV8t3PrRF3gKw6TBjf + {"Bar_F1sh_Rel", "0395f2d9dd9ccb78caf74bff49b6d959afb95af746462e1b35f4a167d8e82b3666" }, // RBbLxJagCA9QHDazQvfnDZe874V1K4Gu8t + {"zatJUM", "030fff499b6dc0215344b28a0b6b4becdfb00cd34cd1b36b983ec14f47965fd4bc" }, // RSoEDLBasth7anxS8gbkg6KgeGiz8rhqv1 + {"dwy", "03669457b2934d98b5761121dd01b243aed336479625b293be9f8c43a6ae7aaeff" }, // RKhZMqRF361FSGFAzstP5AhozekPjoVh5q + {"gcharang", "03336ca9db27cb6e882830e20dc525884e27dc94d557a5e68b972a5cbf9e8c62a8" }, // RJYiWn3FRCSSLf9Pe5RJcbrKQYosaMburP + {"computergenie", "03448ce28fb21748e8b05bbe32d6b1e758b589ac1eb359e5d552f8868f2b75dc92" }, // RGeniexxkjnR34hg7ZnCf36kmfuJusf6rE + {"daemonfox", "0383484bdc745b2b953c85b5a0c496a1f27bc42ae971f15779ed1532421b3dd943" }, // + {"SHossain", "02791f5c215b8a19c143a98e3371ff03b5613df9ac430c4a331ca55fed5761c800" }, // RKdLoHkyeorXmMtj91B1AAnAGiwsdt9MdF + {"Nabob", "03ee91c20b6d26e3604022f42df6bb8de6f669da4591f93b568778cba13d9e9ddf" }, // RRwCLPZDzpHEFJnLev4phy51e2stHRUAaU }, { {"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x @@ -114,7 +116,7 @@ static const char *notaries_STAKED[NUM_STAKED_ERAS][64][2] = } }; -static const int32_t num_notaries_STAKED[NUM_STAKED_ERAS] = { 17, 25, 17, 17 }; +static const int32_t num_notaries_STAKED[NUM_STAKED_ERAS] = { 17, 25, 19, 17 }; int8_t is_STAKED(const char *chain_name); int32_t STAKED_era(int timestamp);