diff --git a/src/crypto/verus_hash.cpp b/src/crypto/verus_hash.cpp index 09e34ff18..baa5b45bd 100644 --- a/src/crypto/verus_hash.cpp +++ b/src/crypto/verus_hash.cpp @@ -49,7 +49,7 @@ CVerusHash &CVerusHash::Write(const unsigned char *data, size_t len) unsigned char *tmp; // digest up to 32 bytes at a time - for ( int pos = 0; pos < len; pos += 32) + for ( int pos = 0; pos < len; ) { int room = 32 - curPos; @@ -66,7 +66,7 @@ CVerusHash &CVerusHash::Write(const unsigned char *data, size_t len) else { memcpy(curBuf + 32 + curPos, data + pos, len - pos); - curPos = 32 - (len - pos); + curPos += len - pos; pos = len; } } diff --git a/src/crypto/verus_hash.h b/src/crypto/verus_hash.h index 567ac851f..394a5e070 100644 --- a/src/crypto/verus_hash.h +++ b/src/crypto/verus_hash.h @@ -46,7 +46,8 @@ class CVerusHash } private: - unsigned char buf1[64], buf2[64]; + // only buf1, the first source, needs to be zero initialized + unsigned char buf1[64] = {0}, buf2[64]; unsigned char *curBuf = buf1, *result = buf2; size_t curPos = 0; }; diff --git a/src/hash.h b/src/hash.h index 7c6b93b61..485655a00 100644 --- a/src/hash.h +++ b/src/hash.h @@ -203,7 +203,7 @@ public: int nType; int nVersion; - CVerusHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {} + CVerusHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn), state() {} CVerusHashWriter& write(const char *pch, size_t size) { state.Write((const unsigned char*)pch, size); diff --git a/src/komodo_globals.h b/src/komodo_globals.h index aa2995b59..659519ed2 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -56,7 +56,7 @@ uint32_t ASSETCHAIN_INIT; uint32_t ASSETCHAINS_MAGIC = 2387029918; uint64_t ASSETCHAINS_SUPPLY = 10; uint64_t ASSETCHAINS_COMMISSION; -int64_t ASSETCHAINS_GENESISPREMINE = 5000000000; +int64_t ASSETCHAINS_GENESISTXVAL = 5000000000; // consensus variables for coinbase timelock control and timelock transaction support // time locks are specified enough to enable their use initially to lock specific coinbase transactions for emission control diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 6e70ec7c9..186a64a17 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1042,8 +1042,7 @@ uint64_t blockPRG(uint32_t nHeight) { int i; uint8_t hashSrc[8]; - uint32_t result = 0; - uint64_t hashSrc64 = ASSETCHAINS_MAGIC << 32 + nHeight; + uint64_t result, hashSrc64 = (uint64_t)ASSETCHAINS_MAGIC << 32 + nHeight; bits256 hashResult; for ( i = 0; i < sizeof(hashSrc); i++ ) @@ -1051,11 +1050,11 @@ uint64_t blockPRG(uint32_t nHeight) hashSrc[i] = hashSrc64 & 0xff; hashSrc64 >>= 8; } - vcalc_sha256(0,hashResult.bytes,hashSrc,sizeof(hashSrc)); + vcalc_sha256(0, hashResult.bytes, hashSrc, sizeof(hashSrc)); - for ( i = 0; i < sizeof(hashResult.uints) >> 2; i++ ) + for ( i = 0; i < 8; i++ ) { - result ^= hashResult.uints[i]; + result = (result << 8) + hashResult.bytes[i]; } return(result); } @@ -1552,8 +1551,13 @@ int64_t komodo_max_money() max_money = komodo_maxallowed(baseid); else { - // figure out max_money by adding up supply and future block rewards, if no ac_END, max_money uses arbitrary 10,000,000 block end - max_money = (ASSETCHAINS_SUPPLY+1) * SATOSHIDEN + (ASSETCHAINS_MAGIC & 0xffffff) + ASSETCHAINS_GENESISPREMINE; + // figure out max_money by adding up supply to a maximum of 10,000,000 blocks + max_money = (ASSETCHAINS_SUPPLY+1) * SATOSHIDEN + (ASSETCHAINS_MAGIC & 0xffffff) + ASSETCHAINS_GENESISTXVAL; + if ( ASSETCHAINS_LASTERA == 0 && ASSETCHAINS_REWARD[0] == 0 ) + { + max_money += 10000 * 10000000LL; + return((int64_t)max_money); + } for ( int j = 0; j <= ASSETCHAINS_LASTERA && (j == 0 || ASSETCHAINS_ENDSUBSIDY[j - 1] != 0); j++ ) { @@ -1604,9 +1608,9 @@ int64_t komodo_max_money() uint64_t komodo_ac_block_subsidy(int nHeight) { // we have to find our era, start from beginning reward, and determine current subsidy - int64_t numerator, subsidy = 0; + int64_t numerator, denominator, subsidy = 0; int64_t subsidyDifference; - int32_t numhalvings, curEra = 0; + int32_t numhalvings, curEra = 0, sign = 1; static uint64_t cached_subsidy; static int32_t cached_numhalvings; static int cached_era; // check for backwards compat, older chains with no explicit rewards had 0.0001 block reward @@ -1627,7 +1631,7 @@ uint64_t komodo_ac_block_subsidy(int nHeight) { int nStart = curEra ? ASSETCHAINS_ENDSUBSIDY[curEra - 1] : 0; subsidy = (int64_t)ASSETCHAINS_REWARD[curEra]; - if ( subsidy ) + if ( subsidy || (curEra != ASSETCHAINS_LASTERA && ASSETCHAINS_REWARD[curEra + 1] != 0) ) { if ( ASSETCHAINS_HALVING[curEra] != 0 ) { @@ -1645,9 +1649,15 @@ uint64_t komodo_ac_block_subsidy(int nHeight) { // Ex: -ac_eras=3 -ac_reward=0,384,24 -ac_end=1440,260640,0 -ac_halving=1,1440,2103840 -ac_decay 100000000,97750000,0 subsidyDifference = subsidy - ASSETCHAINS_REWARD[curEra + 1]; + if (subsidyDifference < 0) + { + sign = -1; + subsidyDifference *= sign; + } } - numerator = (ASSETCHAINS_ENDSUBSIDY[curEra] - nHeight); - subsidy = subsidy - (subsidyDifference * numerator) / (ASSETCHAINS_ENDSUBSIDY[curEra] - nStart); + denominator = ASSETCHAINS_ENDSUBSIDY[curEra] - nStart; + numerator = denominator - ((ASSETCHAINS_ENDSUBSIDY[curEra] - nHeight) + ((nHeight - nStart) % ASSETCHAINS_HALVING[curEra])); + subsidy = subsidy - sign * ((subsidyDifference * numerator) / denominator); } else { @@ -1732,6 +1742,13 @@ void komodo_args(char *argv0) ASSETCHAINS_TIMELOCKGTE = GetArg("-ac_timelockgte", _ASSETCHAINS_TIMELOCKOFF); ASSETCHAINS_TIMEUNLOCKFROM = GetArg("-ac_timeunlockfrom", 0); ASSETCHAINS_TIMEUNLOCKTO = GetArg("-ac_timeunlockto", 0); + if ( ASSETCHAINS_TIMEUNLOCKFROM > ASSETCHAINS_TIMEUNLOCKTO || + ASSETCHAINS_TIMEUNLOCKTO == 0 ) + { + printf("ASSETCHAINS_TIMELOCKGTE - must specify valid ac_timeunlockfrom and ac_timeunlockto\n"); + ASSETCHAINS_TIMELOCKGTE = _ASSETCHAINS_TIMELOCKOFF; + ASSETCHAINS_TIMEUNLOCKFROM = ASSETCHAINS_TIMEUNLOCKTO = 0; + } Split(GetArg("-ac_end",""), ASSETCHAINS_ENDSUBSIDY, 0); Split(GetArg("-ac_reward",""), ASSETCHAINS_REWARD, 0); diff --git a/src/main.cpp b/src/main.cpp index a70e0aeeb..f9b4b97ae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -901,14 +901,14 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeight) { // if time locks are on, ensure that this coin base is time locked exactly as it should be - if (tx.GetValueOut() >= ASSETCHAINS_TIMELOCKGTE) + if ((uint64_t)(tx.GetValueOut()) >= ASSETCHAINS_TIMELOCKGTE) { CScriptID scriptHash; // to be valid, it must be a P2SH transaction and have an op_return in vout[1] that // holds the full output script, which may include multisig, etc., but starts with // the time lock verify of the correct time lock for this block height - if (tx.vout.size() == 2 && + if (tx.vout.size() == 2 && CScriptExt(tx.vout[0].scriptPubKey).IsPayToScriptHash(&scriptHash) && tx.vout[1].scriptPubKey.size() >= 7 && // minimum for any possible future to prevent out of bounds tx.vout[1].scriptPubKey.data()[0] == OP_RETURN) @@ -3594,7 +3594,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta int nHeight = pindexPrev->nHeight+1; // Check proof of work - if ( (nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) + if ( (ASSETCHAINS_SYMBOL[0] != 0 || (nHeight < 235300 || nHeight > 236000)) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) { cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) << endl; return state.DoS(100, error("%s: incorrect proof of work", __func__), @@ -3603,8 +3603,10 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta // Check timestamp against prev if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) + { return state.Invalid(error("%s: block's timestamp is too early", __func__), REJECT_INVALID, "time-too-old"); + } if (fCheckpointsEnabled) { diff --git a/src/miner.cpp b/src/miner.cpp index 0be7949c7..586fc4977 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -192,8 +192,22 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) CBlockIndex* pindexPrev = chainActive.Tip(); const int nHeight = pindexPrev->nHeight + 1; uint32_t consensusBranchId = CurrentEpochBranchId(nHeight, chainparams.GetConsensus()); - pblock->nTime = GetAdjustedTime(); + const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); + uint32_t proposedTime = GetAdjustedTime(); + if (proposedTime == nMedianTimePast) + { + // too fast or stuck, this addresses the too fast issue, while moving + // forward as quickly as possible + for (int i; i < 100; i++) + { + proposedTime = GetAdjustedTime(); + if (proposedTime == nMedianTimePast) + MilliSleep(10); + } + } + pblock->nTime = GetAdjustedTime(); + CCoinsViewCache view(pcoinsTip); uint32_t expired; @@ -402,8 +416,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) txNew.nExpiryHeight = 0; // check if coinbase transactions must be time locked at current subsidy and prepend the time lock - // to transaction if so - if (txNew.vout[0].nValue >= ASSETCHAINS_TIMELOCKGTE) + // to transaction if so, cast for GTE operator + if ((uint64_t)(txNew.vout[0].nValue) >= ASSETCHAINS_TIMELOCKGTE) { int32_t opretlen, p2shlen, scriptlen; CScriptExt opretScript = CScriptExt(); @@ -769,6 +783,7 @@ void static BitcoinMiner_noeq() LogPrintf("KomodoMiner using %s algorithm:\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]); LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex()); + printf("FOUND BLOCK! \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex().c_str(), hashTarget.GetHex().c_str()); #ifdef ENABLE_WALLET ProcessBlockFound(pblock, *pwallet, reservekey); #else diff --git a/src/script/script_ext.cpp b/src/script/script_ext.cpp index 560c4e0cf..655d256c2 100644 --- a/src/script/script_ext.cpp +++ b/src/script/script_ext.cpp @@ -36,7 +36,7 @@ const CScriptExt &CScriptExt::OpReturnScript(const vector &data, if (data.size() < MAX_SCRIPT_ELEMENT_SIZE) { vector scratch = vector(data); - scratch.insert(data.begin(), opretType); + scratch.insert(scratch.begin(), opretType); *((CScript *)this) << OP_RETURN; *((CScript *)this) << scratch; } @@ -56,11 +56,13 @@ const CScriptExt &CScriptExt::PayToScriptHash(const CScriptID &scriptID) const // P2SH script, adds to whatever is already in the script (for example CLTV) const CScriptExt &CScriptExt::AddCheckLockTimeVerify(int64_t unlocktime) const { - unlocktime = unlocktime < 0 ? 0 : unlocktime; - *((CScript *)this) << CScriptNum::serialize(unlocktime); - *((CScript *)this) << OP_CHECKLOCKTIMEVERIFY; - *((CScript *)this) << OP_DROP; - return *this; + if (unlocktime > 0) + { + *((CScript *)this) << CScriptNum::serialize(unlocktime); + *((CScript *)this) << OP_CHECKLOCKTIMEVERIFY; + *((CScript *)this) << OP_DROP; + return *this; + } } // combined CLTV script and P2PKH @@ -78,11 +80,11 @@ bool CScriptExt::IsCheckLockTimeVerify(int64_t *unlockTime) const { opcodetype op; std::vector unlockTimeParam = std::vector(); - CScript::const_iterator it = this->begin(); + if (this->GetOp2(it, op, &unlockTimeParam)) { - if (unlockTimeParam.size() > 1 && unlockTimeParam.size() < 6 && + if (unlockTimeParam.size() >= 0 && unlockTimeParam.size() < 6 && *(this->data() + unlockTimeParam.size() + 1) == OP_CHECKLOCKTIMEVERIFY) { int i = unlockTimeParam.size() - 1;