Bug fixes in hash algorithm, parameters, and time lock support
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -36,7 +36,7 @@ const CScriptExt &CScriptExt::OpReturnScript(const vector<unsigned char> &data,
|
||||
if (data.size() < MAX_SCRIPT_ELEMENT_SIZE)
|
||||
{
|
||||
vector<unsigned char> scratch = vector<unsigned char>(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<unsigned char> unlockTimeParam = std::vector<unsigned char>();
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user