diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index e8b33c073..724525795 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -1695,9 +1695,9 @@ CScript komodo_mineropret(int32_t nHeight) // pass in blockhash and nTime, latch if it is rejected due to local price, then if localprice changes in a way that would validate then issue reconsiderblock // add rpc call for extracting rawprices -int32_t komodo_opretvalidate(int32_t nHeight,CScript scriptPubKey) +int32_t komodo_opretvalidate(const CBlock *block,CBlockIndex * const previndex,int32_t nHeight,CScript scriptPubKey) { - std::vector vopret; char maxflags[2048]; double btcusd,btcgbp,btceur; uint32_t localbits[2048],pricebits[2048],prevbits[2048],newprice; int32_t i,maxflag,lag,lag2,n; uint32_t now = (uint32_t)time(NULL); + std::vector vopret; char maxflags[2048]; double btcusd,btcgbp,btceur; uint32_t localbits[2048],pricebits[2048],prevbits[2048],newprice; int32_t i,prevtime,maxflag,lag,lag2,lag3,n; uint32_t now = (uint32_t)time(NULL); if ( ASSETCHAINS_CBOPRET != 0 && nHeight > 0 ) { GetOpReturnData(scriptPubKey,vopret); @@ -1708,16 +1708,23 @@ int32_t komodo_opretvalidate(int32_t nHeight,CScript scriptPubKey) memset(maxflags,0,sizeof(maxflags)); if ( nHeight > 2 ) { + prevtime = previndex->nTime; lag = (int32_t)(now - pricebits[0]); - lag2 = (int32_t)(komodo_heightstamp(nHeight-1) - pricebits[0]); + lag2 = (int32_t)(pricebits[0] - prevtime); + lag3 = (int32_t)(block->nTime - pricebits[0]); if ( lag < -60 ) // avoid data from future { - fprintf(stderr,"ht.%d now.%u htstamp.%u - pricebits[0] %u -> lag.%d\n",nHeight,now,komodo_heightstamp(nHeight-1),pricebits[0],lag); + fprintf(stderr,"ht.%d now.%u htstamp.%u %u - pricebits[0] %u -> lags.%d %d %d\n",nHeight,now,prevtime,block->nTime,pricebits[0],lag,lag2,lag3); return(-1); } - if ( lag2 < 0 ) + if ( lag2 < 0 ) // must be after last block timestamp { - fprintf(stderr,"ht.%d now.%u htstamp.%u - pricebits[0] %u -> lag2.%d\n",nHeight,now,komodo_heightstamp(nHeight-1),pricebits[0],lag2); + fprintf(stderr,"ht.%d now.%u htstamp.%u - pricebits[0] %u -> lags.%d %d %d\n",nHeight,now,prevtime,block->nTime,pricebits[0],lag,lag2,lag3); + return(-1); + } + if ( lag3 < -60 || lag > ASSETCHAINS_BLOCKTIME ) + { + fprintf(stderr,"ht.%d now.%u htstamp.%u - pricebits[0] %u -> lags.%d %d %d\n",nHeight,now,prevtime,block->nTime,pricebits[0],lag,lag2,lag3); return(-1); } btcusd = (double)pricebits[1]/10000; diff --git a/src/main.cpp b/src/main.cpp index 1036670d6..a037bd828 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -977,7 +977,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in * Ensure that a coinbase transaction is structured according to the consensus rules of the * chain */ -bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeight) +bool ContextualCheckCoinbaseTransaction(const CBlock *block,CBlockIndex * const previndex,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 (((uint64_t)(tx.GetValueOut()) >= ASSETCHAINS_TIMELOCKGTE) || @@ -1020,7 +1020,7 @@ bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeigh } else if ( ASSETCHAINS_CBOPRET != 0 && nHeight > 0 && tx.vout.size() > 0 ) { - if ( komodo_opretvalidate(nHeight,tx.vout[tx.vout.size()-1].scriptPubKey) < 0 ) + if ( komodo_opretvalidate(block,previndex,nHeight,tx.vout[tx.vout.size()-1].scriptPubKey) < 0 ) return(false); } return(true); @@ -1035,7 +1035,7 @@ bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeigh * and ContextualCheckBlock (which calls this function). * 3. The isInitBlockDownload argument is only to assist with testing. */ -bool ContextualCheckTransaction( +bool ContextualCheckTransaction(const CBlock *block, CBlockIndex * const previndex, const CTransaction& tx, CValidationState &state, const int nHeight, @@ -1171,7 +1171,7 @@ bool ContextualCheckTransaction( if (tx.IsCoinBase()) { - if (!ContextualCheckCoinbaseTransaction(tx, nHeight)) + if (!ContextualCheckCoinbaseTransaction(block,previndex,tx, nHeight)) return state.DoS(100, error("CheckTransaction(): invalid script data for coinbase time lock"), REJECT_INVALID, "bad-txns-invalid-script-data-for-coinbase-time-lock"); } @@ -1679,7 +1679,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } // DoS level set to 10 to be more forgiving. // Check transaction contextually against the set of consensus rules which apply in the next block to be mined. - if (!fSkipExpiry && !ContextualCheckTransaction(tx, state, nextBlockHeight, (dosLevel == -1) ? 10 : dosLevel)) + if (!fSkipExpiry && !ContextualCheckTransaction(0,0,tx, state, nextBlockHeight, (dosLevel == -1) ? 10 : dosLevel)) { return error("AcceptToMemoryPool: ContextualCheckTransaction failed"); } @@ -5173,7 +5173,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn const CTransaction& tx = block.vtx[i]; // Check transaction contextually against consensus rules at block height - if (!ContextualCheckTransaction(tx, state, nHeight, 100)) { + if (!ContextualCheckTransaction(&block,pindexPrev,tx, state, nHeight, 100)) { return false; // Failure reason has been set in validation state object } diff --git a/src/main.h b/src/main.h index f12bcb8cd..0cdb0b7a8 100644 --- a/src/main.h +++ b/src/main.h @@ -706,7 +706,7 @@ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, cons std::vector *pvChecks = NULL); /** Check a transaction contextually against a set of consensus rules */ -bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state, int nHeight, int dosLevel, +bool ContextualCheckTransaction(const CBlock *block, CBlockIndex * const pindexPrev,const CTransaction& tx, CValidationState &state, int nHeight, int dosLevel, bool (*isInitBlockDownload)() = IsInitialBlockDownload); /** Apply the effects of this transaction on the UTXO set represented by view */