diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index d22ac895f..fc4c66eb5 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1433,14 +1433,15 @@ uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeigh diff = (iter + blocktime - txtime - minage); if ( ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH || ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASHV2 ) { - if ( PoSperc < ASSETCHAINS_STAKED ) + /*if ( PoSperc < ASSETCHAINS_STAKED ) { // Under PoS % target and we need to increase diff. //fprintf(stderr, "PoS too low diff.%i changed to.",diff); diff = diff * ( (ASSETCHAINS_STAKED - PoSperc + 1) * (ASSETCHAINS_STAKED - PoSperc + 1) * ( nHeight < 50 ? 1000 : 1)); //fprintf(stderr, "%i \n",diff); } - else if ( PoSperc > ASSETCHAINS_STAKED ) + else */ + if ( PoSperc > ASSETCHAINS_STAKED ) { // Over PoS target need to lower diff. //fprintf(stderr, "PoS too high diff.%i changed to.",diff); @@ -1460,14 +1461,17 @@ uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeigh coinage = (value * diff); if ( ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH || ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASHV2 ) { - if ( blocktime+iter+segid*2 > prevtime+128 ) - coinage *= ((blocktime+iter+segid*2) - (prevtime+102)); - } - else - { - if ( blocktime+iter+segid*2 > prevtime+480 ) - coinage *= ((blocktime+iter+segid*2) - (prevtime+400)); + if ( PoSperc < ASSETCHAINS_STAKED ) + { + // Under PoS % target and we need to increase diff. + //fprintf(stderr, "PoS too low diff.%i changed to.",diff); + if ( blocktime+iter+segid*2 > prevtime+128 ) + coinage *= ((blocktime+iter+segid*2) - (prevtime+102)); + //fprintf(stderr, "%i \n",diff); + } } + if ( blocktime+iter+segid*2 > prevtime+480 ) + coinage *= ((blocktime+iter+segid*2) - (prevtime+400)); coinage256 = arith_uint256(coinage+1); hashval = ratio * (UintToArith256(hash) / coinage256); if ( hashval <= bnTarget ) @@ -1774,9 +1778,9 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height) int32_t komodo_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 *txidp); -uint64_t komodo_notarypayamount(int32_t height, int64_t numnotaries) +uint64_t komodo_notarypayamount(int32_t height, int64_t notarycount) { - if ( numnotaries == 0 ) + if ( notarycount == 0 ) { fprintf(stderr, "komodo_notarypayamount failed num notaries is 0!\n"); return(0); @@ -1793,18 +1797,41 @@ uint64_t komodo_notarypayamount(int32_t height, int64_t numnotaries) } // how many block since last notarisation. int32_t n = height - notarizedht; - fprintf(stderr, "blocks since last notarisation: %i\n",n); + fprintf(stderr, "blocks since last notarization: %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; + ret = AmountToPay / notarycount; 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); +int32_t komodo_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *script, int32_t len) +{ + // 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, "<<<<< &NotarisationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len) { // fetch notary pubkey array. @@ -1818,25 +1845,11 @@ uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &Notar return(0); numSN = numStakedNotaries(staked_pubkeys,staked_era); - // 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, "notarypay found VALID NOTARIZATION ht.%i\n",notarizedheight); - } - else - { - fprintf(stderr, "notarypay found INVALID NOTARIZATION ht.%i\n",notarizedheight); - return(0); - } - } else return(0); - + // Check the notarisation is valid and get the notarized height to calcualte the payment. + int32_t notarizedheight = komodo_getnotarizedheight(timestamp, height, script, len); + if ( notarizedheight == 0 ) + return(0); + // resize coinbase vouts to number of notary nodes +1 for coinbase itself. txNew.vout.resize(NotarisationNotaries.size()+1); diff --git a/src/miner.cpp b/src/miner.cpp index 8f1792f83..0b0e12895 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -154,6 +154,7 @@ 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, int32_t height, uint8_t *script, int32_t len); +int32_t komodo_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *script, int32_t len); CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake) { @@ -174,7 +175,6 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 uint64_t deposits; int32_t isrealtime,kmdheight; uint32_t blocktime; const CChainParams& chainparams = Params(); bool fNotarisationBlock = false; std::vector NotarisationNotaries; - static std::string invalidnotarisation; //fprintf(stderr,"create new block\n"); // Create new block @@ -233,6 +233,9 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); uint32_t proposedTime = GetAdjustedTime(); + + int32_t last_notarizedheight = 0; + if (proposedTime == nMedianTimePast) { // too fast or stuck, this addresses the too fast issue, while moving @@ -297,6 +300,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 CAmount nTotalIn = 0; bool fMissingInputs = false; bool fNotarisation = false; + std::vector TMP_NotarisationNotaries = {0}; if (tx.IsCoinImport()) { CAmount nValueIn = GetCoinImportValue(tx); // burn amount @@ -304,6 +308,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 dPriority += (double)nValueIn * 1000; // flat multiplier... max = 1e16. } else { //int numNotaryVins = 0; + TMP_NotarisationNotaries.clear(); bool fToCryptoAddress = false; if ( numSN != 0 && staked_pubkeys[0][0] != 0 && komodo_is_notarytx(tx) == 1 ) fToCryptoAddress = true; @@ -356,39 +361,22 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 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); - } + // We can add the index of each notary to vector, and clear it if this notarisation is not valid later on. + TMP_NotarisationNotaries.push_back(i); } } } dPriority += (double)nValueIn * nConf; } - if ( numSN != 0 && NotarisationNotaries.size() >= numSN / 5 ) + if ( numSN != 0 && TMP_NotarisationNotaries.size() >= numSN / 5 ) { // check a notary didnt sign twice (this would be an invalid notarisation later on and cause problems) - std::set checkdupes( NotarisationNotaries.begin(), NotarisationNotaries.end() ); - if ( checkdupes.size() != NotarisationNotaries.size() ) + std::set checkdupes( TMP_NotarisationNotaries.begin(), TMP_NotarisationNotaries.end() ); + if ( checkdupes.size() != TMP_NotarisationNotaries.size() ) { - NotarisationNotaries.clear(); fprintf(stderr, "possible notarisation is signed multiple times by same notary, passed as normal transaction.\n"); - } - else if ( tx.GetHash().ToString() == invalidnotarisation ) - { - // check if the last notarisation we tried was flagged as invalid. - // then clear it, in case next time it is seen as valid. - NotarisationNotaries.clear(); - invalidnotarisation = ""; - fprintf(stderr, "notarisation %s is invalid leave it as a normal tx.\n", invalidnotarisation.c_str()); - } - else - fNotarisation = true; - } else NotarisationNotaries.clear(); - + } else fNotarisation = true; + } nTotalIn += tx.GetShieldedValueIn(); } @@ -405,10 +393,43 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 if (fNotarisation) { - dPriority = 1e16; - Notarisations++; - fNotarisationBlock = true; - fprintf(stderr, "Notarisation[%i] %s set to maximum priority\n",Notarisations,hash.ToString().c_str()); + // check if the notarization found is actually valid. + if ( tx.vout.size() == 2 && tx.vout[1].nValue == 0 ) + { + // Get the OP_RETURN for the notarisation + uint8_t *script = (uint8_t *)&tx.vout[1].scriptPubKey[0]; + int32_t scriptlen = (int32_t)tx.vout[1].scriptPubKey.size(); + if ( script[0] == OP_RETURN ) + { + int32_t notarizedheight = komodo_getnotarizedheight(pblock->nTime, nHeight, script, scriptlen); + if ( notarizedheight != 0 ) + { + if ( last_notarizedheight == 0 ) + { + // this is the first one we see, add it to the block as TX1 + NotarisationNotaries = TMP_NotarisationNotaries; + dPriority = 1e16; + fNotarisationBlock = true; + last_notarizedheight = notarizedheight; + fprintf(stderr, "Notarisation %s set to maximum priority\n",hash.ToString().c_str()); + } + else if ( notarizedheight > last_notarizedheight ) + continue; // leave this notarisation for the next block, it will be valid! + else + { + // we need to remove the last seen notarzation from block + double dPriority = vecPriority.front().get<0>(); + CFeeRate feeRate = vecPriority.front().get<1>(); + const CTransaction& Tx = *(vecPriority.front().get<2>()); + // add this one as its valid before the other one. + NotarisationNotaries = TMP_NotarisationNotaries; + dPriority = 1e16; + fNotarisationBlock = true; + fprintf(stderr, "Notarisation %s set to maximum priority replacing notarization %s\n",hash.ToString().c_str(), Tx.GetHash().ToString().c_str()); + } + } + } + } } else if ( dPriority == 1e16 ) { @@ -421,8 +442,6 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 porphan->dPriority = dPriority; porphan->feeRate = feeRate; } - 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()))); } @@ -700,11 +719,12 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 int32_t scriptlen = (int32_t)pblock->vtx[1].vout[1].scriptPubKey.size(); if ( script[0] == OP_RETURN ) { + fprintf(stderr, ">>>>>MINER NotarisationNotaries.%li\n",NotarisationNotaries.size()); uint64_t totalsats = komodo_notarypay(txNew, NotarisationNotaries, pblock->nTime, nHeight, script, scriptlen); if ( totalsats == 0 ) { fprintf(stderr, "Could not create notary payment, trying again.\n"); - invalidnotarisation = pblock->vtx[1].GetHash().ToString(); + // invalidnotarisation = pblock->vtx[1].GetHash().ToString(); if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) ) { LEAVE_CRITICAL_SECTION(cs_main); diff --git a/src/pow.cpp b/src/pow.cpp index d36357800..1716099ee 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -44,10 +44,15 @@ unsigned int lwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { - if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH) + if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH && ASSETCHAINS_STAKED == 0) return lwmaGetNextWorkRequired(pindexLast, pblock, params); - unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); + arith_uint256 bnLimit; + if (ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH) + bnLimit = UintToArith256(params.powLimit); + else + bnLimit = UintToArith256(params.powAlternate); + unsigned int nProofOfWorkLimit = bnLimit.GetCompact(); // Genesis block if (pindexLast == NULL ) return nProofOfWorkLimit; @@ -102,7 +107,13 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg, nActualTimespan = params.MaxActualTimespan(); // Retarget - const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); + arith_uint256 bnLimit; + if (ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH) + bnLimit = UintToArith256(params.powLimit); + else + bnLimit = UintToArith256(params.powAlternate); + + const arith_uint256 bnPowLimit = bnLimit; //UintToArith256(params.powLimit); arith_uint256 bnNew {bnAvg}; bnNew /= params.AveragingWindowTimespan(); bnNew *= nActualTimespan;