Merge branch 'FSM' into patch-gcc-8

This commit is contained in:
jl777
2019-01-25 16:33:13 -11:00
committed by GitHub
281 changed files with 12240 additions and 3233 deletions

View File

@@ -3,6 +3,21 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
/******************************************************************************
* Copyright © 2014-2019 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "main.h"
#include "sodium.h"
@@ -61,12 +76,13 @@ using namespace std;
* Global state
*/
#define TMPFILE_START 100000000
CCriticalSection cs_main;
extern uint8_t NOTARY_PUBKEY33[33];
extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING,KOMODO_EXTRASATOSHI;
int32_t KOMODO_NEWBLOCKS;
int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
void komodo_broadcast(CBlock *pblock,int32_t limit);
//void komodo_broadcast(CBlock *pblock,int32_t limit);
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
void komodo_setactivation(int32_t height);
@@ -167,8 +183,9 @@ namespace {
multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
CCriticalSection cs_LastBlockFile;
std::vector<CBlockFileInfo> vinfoBlockFile;
std::vector<CBlockFileInfo> vinfoBlockFile,tmpBlockFiles;
int nLastBlockFile = 0;
int nLastTmpFile = 0;
/** 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
@@ -1076,6 +1093,7 @@ bool ContextualCheckTransaction(
}
// Rules that apply to Overwinter or later:
//fprintf(stderr,"ht.%d overwinterActive.%d tx.overwintered.%d\n",nHeight,overwinterActive,overwinterActive);
if (overwinterActive)
{
// Reject transactions intended for Sprout
@@ -1610,6 +1628,15 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
if ( nextBlockHeight <= 1 || chainActive.LastTip() == 0 )
tiptime = (uint32_t)time(NULL);
else tiptime = (uint32_t)chainActive.LastTip()->nTime;
// is it already in the memory pool?
uint256 hash = tx.GetHash();
if (pool.exists(hash))
{
//fprintf(stderr,"already in mempool\n");
return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
}
// Node operator can choose to reject tx by number of transparent inputs
static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0);
@@ -1648,7 +1675,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
// Rather not work on nonstandard transactions (unless -testnet/-regtest)
string reason;
if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
if (!fSkipExpiry && Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
{
//
//fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\nscriptPubKey: %s\n",reason.c_str(),tx.vout[0].scriptPubKey.ToString().c_str());
@@ -1657,21 +1684,14 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Only accept nLockTime-using transactions that can be mined in the next
// block; we don't want our mempool filled up with transactions that can't
// be mined yet.
if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
if (!fSkipExpiry && !CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
{
//fprintf(stderr,"AcceptToMemoryPool reject non-final\n");
return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
}
// is it already in the memory pool?
uint256 hash = tx.GetHash();
if (pool.exists(hash))
{
//fprintf(stderr,"already in mempool\n");
return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
}
// Check for conflicts with in-memory transactions
if (!fSkipExpiry)
{
LOCK(pool.cs); // protect pool.mapNextTx
for (unsigned int i = 0; i < tx.vin.size(); i++)
@@ -1721,7 +1741,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
if (ExistsImportTombstone(tx, view))
return state.Invalid(false, REJECT_DUPLICATE, "import tombstone exists");
}
else
else if (!fSkipExpiry)
{
// do all inputs exist?
// Note that this does not check for the presence of actual outputs (see the next check for that),
@@ -1733,10 +1753,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
if (pfMissingInputs)
*pfMissingInputs = true;
//fprintf(stderr,"missing inputs\n");
if (!fSkipExpiry)
return state.DoS(0, error("AcceptToMemoryPool: tx inputs not found"),REJECT_INVALID, "bad-txns-inputs-missing");
else
return(false);
return state.DoS(0, error("AcceptToMemoryPool: tx inputs not found"),REJECT_INVALID, "bad-txns-inputs-missing");
}
}
@@ -1744,10 +1761,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
if (!view.HaveInputs(tx))
{
//fprintf(stderr,"accept failure.1\n");
if (!fSkipExpiry)
return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent");
else
return(false);
return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent");
}
}
// are the joinsplit's requirements met?
@@ -1756,6 +1770,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
//fprintf(stderr,"accept failure.2\n");
return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
}
// Bring the best block into scope
view.GetBestBlock();
@@ -1790,7 +1805,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Keep track of transactions that spend a coinbase, which we re-scan
// during reorgs to ensure COINBASE_MATURITY is still met.
bool fSpendsCoinbase = false;
if (!tx.IsCoinImport()) {
if (!fSkipExpiry && !tx.IsCoinImport()) {
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
const CCoins *coins = view.AccessCoins(txin.prevout.hash);
if (coins->IsCoinBase()) {
@@ -1853,7 +1868,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
dFreeCount += nSize;
}
if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
if (!tx.IsCoinImport() && fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
{
string errmsg = strprintf("absurdly high fees %s, %d > %d",
hash.ToString(),
@@ -1865,7 +1880,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
PrecomputedTransactionData txdata(tx);
if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
if (!fSkipExpiry && !ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
{
//fprintf(stderr,"accept failure.9\n");
return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
@@ -1886,7 +1901,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
flag = 1;
KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.LastTip()->GetHeight() + 1;
}
if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
if (!fSkipExpiry && !ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
{
if ( flag != 0 )
KOMODO_CONNECTING = -1;
@@ -1896,8 +1911,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
KOMODO_CONNECTING = -1;
// Store transaction in memory
if ( komodo_is_notarytx(tx) == 0 )
KOMODO_ON_DEMAND++;
pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
if (!tx.IsCoinImport())
@@ -1968,6 +1981,73 @@ bool GetAddressUnspent(uint160 addressHash, int type,
return true;
}
struct CompareBlocksByHeightMain
{
bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
{
/* Make sure that unequal blocks with the same height do not compare
equal. Use the pointers themselves to make a distinction. */
if (a->GetHeight() != b->GetHeight())
return (a->GetHeight() > b->GetHeight());
return a < b;
}
};
bool RemoveOrphanedBlocks(int32_t notarized_height)
{
LOCK(cs_main);
std::vector<const CBlockIndex*> prunedblocks;
std::set<const CBlockIndex*, CompareBlocksByHeightMain> setTips;
int32_t m=0,n = 0;
// get notarised timestamp and use this as a backup incase the forked block has no height.
// we -600 to make sure the time is within future block constraints.
uint32_t notarized_timestamp = komodo_heightstamp(notarized_height)-600;
// Most of this code is a direct copy from GetChainTips RPC. Which gives a return of all
// blocks that are not in the main chain.
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
{
n++;
setTips.insert(item.second);
}
n = 0;
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
{
const CBlockIndex* pprev=0;
n++;
if ( item.second != 0 )
pprev = item.second->pprev;
if (pprev)
setTips.erase(pprev);
}
const CBlockIndex *forked;
BOOST_FOREACH(const CBlockIndex* block, setTips)
{
// We skip anything over notarised height to avoid breaking normal consensus rules.
if ( block->GetHeight() > notarized_height || block->nTime > notarized_timestamp )
continue;
// We can also check if the block is in the active chain as a backup test.
forked = chainActive.FindFork(block);
// Here we save each forked block to a vector for removal later.
if ( forked != 0 )
prunedblocks.push_back(block);
}
if (prunedblocks.size() > 0 && pblocktree->EraseBatchSync(prunedblocks))
{
// Blocks cleared from disk succesfully, using internal DB batch erase function. Which exists, but has never been used before.
// We need to try and clear the block index from mapBlockIndex now, otherwise node will need a restart.
BOOST_FOREACH(const CBlockIndex* block, prunedblocks)
{
m++;
mapBlockIndex.erase(block->GetBlockHash());
}
fprintf(stderr, "%s removed %d orphans from %d blocks before %d\n",ASSETCHAINS_SYMBOL,m,n, notarized_height);
return true;
}
return false;
}
/*uint64_t myGettxout(uint256 hash,int32_t n)
{
CCoins coins;
@@ -2115,7 +2195,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
// CBlock and CBlockIndex
//
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
{
// Open history file to append
CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
@@ -2683,6 +2763,7 @@ bool ContextualCheckInputs(
if (tx.IsCoinImport())
{
LOCK(cs_main);
ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
return VerifyCoinImport(tx.vin[0].scriptSig, checker, state);
}
@@ -3145,9 +3226,12 @@ static int64_t nTimeConnect = 0;
static int64_t nTimeIndex = 0;
static int64_t nTimeCallbacks = 0;
static int64_t nTimeTotal = 0;
bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false);
bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos);
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW)
{
CDiskBlockPos blockPos;
const CChainParams& chainparams = Params();
if ( KOMODO_STOPAT != 0 && pindex->GetHeight() > KOMODO_STOPAT )
return(false);
@@ -3177,7 +3261,21 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
return false;
fprintf(stderr,"grandfathered exception, until jan 15th 2019\n");
}
if ( (pindex->nStatus & BLOCK_IN_TMPFILE) != 0 )
{
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
if (!FindBlockPos(0,state, blockPos, nBlockSize+8, pindex->GetHeight(), block.GetBlockTime(),false))
return error("ConnectBlock(): FindBlockPos failed");
if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
return error("ConnectBlock(): FindBlockPos failed");
pindex->nStatus &= (~BLOCK_IN_TMPFILE);
pindex->nFile = blockPos.nFile;
pindex->nDataPos = blockPos.nPos;
if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
return error("AcceptBlock(): ReceivedBlockTransactions failed");
setDirtyFileInfo.insert(blockPos.nFile);
fprintf(stderr,"added ht.%d copy of tmpfile to %d.%d\n",pindex->GetHeight(),blockPos.nFile,blockPos.nPos);
}
// verify that the view's current state corresponds to the previous block
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
if ( hashPrevBlock != view.GetBestBlock() )
@@ -3451,7 +3549,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
{
if ( block.vtx[0].vout.size() >= 2 && block.vtx[0].vout[1].nValue == checktoshis )
blockReward += checktoshis;
else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
else if ( pindex->GetHeight() > 1 )
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_SYMBOL[0] != 0 && pindex->GetHeight() == 1 && block.vtx[0].GetValueOut() != blockReward)
@@ -3485,6 +3584,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
CDiskBlockPos pos;
if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
return error("ConnectBlock(): FindUndoPos failed");
if ( pindex->pprev == 0 )
fprintf(stderr,"ConnectBlock: unexpected null pprev\n");
if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
return AbortNode(state, "Failed to write undo data");
@@ -3792,7 +3893,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
CValidationState stateDummy;
// don't keep staking or invalid transactions
if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block) != 0)) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block,pindexDelete->GetHeight()) != 0)) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
{
mempool.remove(tx, removed, true);
}
@@ -3823,7 +3924,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
{
CTransaction &tx = block.vtx[i];
//if ((i == (block.vtx.size() - 1)) && ((ASSETCHAINS_LWMAPOS && block.IsVerusPOSBlock()) || (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block) != 0))))
if ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block) != 0)))
if ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block,pindexDelete->GetHeight()) != 0)))
{
EraseFromWallets(tx.GetHash());
}
@@ -3986,10 +4087,10 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
KOMODO_INSYNC = (int32_t)pindexNew->GetHeight();
else KOMODO_INSYNC = 0;
//fprintf(stderr,"connect.%d insync.%d ASSETCHAINS_SAPLING.%d\n",(int32_t)pindexNew->GetHeight(),KOMODO_INSYNC,ASSETCHAINS_SAPLING);
if ( KOMODO_INSYNC != 0 ) //ASSETCHAINS_SYMBOL[0] == 0 &&
/*if ( KOMODO_INSYNC != 0 ) //ASSETCHAINS_SYMBOL[0] == 0 &&
komodo_broadcast(pblock,8);
else if ( ASSETCHAINS_SYMBOL[0] != 0 )
komodo_broadcast(pblock,4);
komodo_broadcast(pblock,4);*/
if ( ASSETCHAINS_SAPLING <= 0 && pindexNew->nTime > KOMODO_SAPLING_ACTIVATION - 24*3600 )
komodo_activate_sapling(pindexNew);
return true;
@@ -4106,7 +4207,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
"- " + strprintf(_("Fork point: %s %s, height %d"),
ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->GetHeight()) + "\n\n" +
_("Please help, human!");
LogPrintf("*** %s\n", msg);
LogPrintf("*** %s\nif you launch with -maxreorg=%d it might be able to resolve this automatically", msg,reorgLength+10);
uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
StartShutdown();
return false;
@@ -4471,43 +4572,57 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
return true;
}
bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown)
{
std::vector<CBlockFileInfo> *ptr; int *lastfilep;
LOCK(cs_LastBlockFile);
unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
if (vinfoBlockFile.size() <= nFile) {
vinfoBlockFile.resize(nFile + 1);
unsigned int nFile;
if ( tmpflag != 0 )
{
ptr = &tmpBlockFiles;
nFile = nLastTmpFile;
lastfilep = &nLastTmpFile;
}
else
{
ptr = &vinfoBlockFile;
lastfilep = &nLastBlockFile;
nFile = fKnown ? pos.nFile : nLastBlockFile;
if (vinfoBlockFile.size() <= nFile) {
vinfoBlockFile.resize(nFile + 1);
}
}
if (!fKnown) {
while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
while ((*ptr)[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
nFile++;
if (vinfoBlockFile.size() <= nFile) {
vinfoBlockFile.resize(nFile + 1);
if ((*ptr).size() <= nFile) {
(*ptr).resize(nFile + 1);
}
}
pos.nFile = nFile;
pos.nPos = vinfoBlockFile[nFile].nSize;
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 != nLastBlockFile) {
if (nFile != *lastfilep) {
if (!fKnown) {
LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
LogPrintf("Leaving block file %i: %s\n", nFile, (*ptr)[nFile].ToString());
}
FlushBlockFile(!fKnown);
nLastBlockFile = nFile;
*lastfilep = nFile;
}
vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
(*ptr)[nFile].AddBlock(nHeight, nTime);
if (fKnown)
vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
(*ptr)[nFile].nSize = std::max(pos.nPos + nAddSize, (*ptr)[nFile].nSize);
else
vinfoBlockFile[nFile].nSize += nAddSize;
(*ptr)[nFile].nSize += nAddSize;
if (!fKnown) {
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
unsigned int nNewChunks = ((*ptr)[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
if (nNewChunks > nOldChunks) {
if (fPruneMode)
fCheckForPruning = true;
@@ -4524,19 +4639,26 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
}
}
setDirtyFileInfo.insert(nFile);
setDirtyFileInfo.insert(nFile + tmpflag*TMPFILE_START);
return true;
}
bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
{
pos.nFile = nFile;
std::vector<CBlockFileInfo> *ptr; int *lastfilep;
LOCK(cs_LastBlockFile);
pos.nFile = nFile;
if ( nFile >= TMPFILE_START )
{
fprintf(stderr,"skip tmp undo\n");
return(false);
nFile %= TMPFILE_START;
ptr = &tmpBlockFiles;
} else ptr = &vinfoBlockFile;
unsigned int nNewSize;
pos.nPos = vinfoBlockFile[nFile].nUndoSize;
nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
pos.nPos = (*ptr)[nFile].nUndoSize;
nNewSize = (*ptr)[nFile].nUndoSize += nAddSize;
setDirtyFileInfo.insert(nFile);
unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
@@ -4580,7 +4702,7 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,
*futureblockp = 0;
if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
{
CBlockIndex *tipindex;
/*CBlockIndex *tipindex;
//fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
{
@@ -4589,9 +4711,9 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,
sleep(1);
//fprintf(stderr,"now its valid\n");
}
else
else*/
{
if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
if (blockhdr.GetBlockTime() < GetAdjustedTime() + 300)
*futureblockp = 1;
//LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
@@ -4689,6 +4811,9 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
// Check transactions
CTransaction sTx;
CTransaction *ptx = NULL;
if ( ASSETCHAINS_CC != 0 && !fCheckPOW )
return true;
if ( ASSETCHAINS_CC != 0 ) // CC contracts might refer to transactions in the current block, from a CC spend within the same block and out of order
{
int32_t i,j,rejects=0,lastrejects=0;
@@ -4719,7 +4844,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
CValidationState state;
CTransaction Tx;
const CTransaction &tx = (CTransaction)block.vtx[i];
if (tx.IsCoinBase() || (!tx.vjoinsplit.empty() && !tx.vShieldedSpend.empty()) || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block) != 0)))
if (tx.IsCoinBase() || !tx.vjoinsplit.empty() || !tx.vShieldedSpend.empty() || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block,height) != 0)))
continue;
Tx = tx;
if ( myAddtomempool(Tx, &state, true) == false ) // happens with out of order tx in block on resync
@@ -4766,7 +4891,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
if (nSigOps > MAX_BLOCK_SIGOPS)
return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"),
REJECT_INVALID, "bad-blk-sigops", true);
if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
if ( fCheckPOW && komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
{
//static uint32_t counter;
//if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
@@ -4782,6 +4907,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
if ( ASSETCHAINS_CC != 0 )
{
LOCK2(cs_main,mempool.cs);
// here we add back all txs from the temp mempool to the main mempool.
BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx)
{
@@ -5066,8 +5192,8 @@ bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, C
// the problem is when a future sapling block comes in before we detected saplinght
if ( saplinght > 0 && (tmpptr= chainActive.LastTip()) != 0 )
{
fprintf(stderr,"saplinght.%d tipht.%d blockht.%d cmp.%d\n",saplinght,(int32_t)tmpptr->GetHeight(),pindex->GetHeight(),pindex->GetHeight() < 0 || pindex->GetHeight() >= saplinght || (tmpptr->GetHeight() > saplinght-720 && tmpptr->GetHeight() < saplinght+720));
if ( pindex->GetHeight() < 0 || pindex->GetHeight() >= saplinght || (tmpptr->GetHeight() > saplinght-720 && tmpptr->GetHeight() < saplinght+720) )
fprintf(stderr,"saplinght.%d tipht.%d blockht.%d cmp.%d\n",saplinght,(int32_t)tmpptr->GetHeight(),pindex->GetHeight(),pindex->GetHeight() < 0 || (pindex->GetHeight() >= saplinght && pindex->GetHeight() < saplinght+50000) || (tmpptr->GetHeight() > saplinght-720 && tmpptr->GetHeight() < saplinght+720));
if ( pindex->GetHeight() < 0 || (pindex->GetHeight() >= saplinght && pindex->GetHeight() < saplinght+50000) || (tmpptr->GetHeight() > saplinght-720 && tmpptr->GetHeight() < saplinght+720) )
*futureblockp = 1;
}
if ( *futureblockp == 0 )
@@ -5082,19 +5208,22 @@ bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, C
}
int nHeight = pindex->GetHeight();
int32_t usetmp = 0;
// Write block to history file
try {
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
CDiskBlockPos blockPos;
if (dbp != NULL)
blockPos = *dbp;
if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
if (!FindBlockPos(usetmp,state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
return error("AcceptBlock(): FindBlockPos failed");
if (dbp == NULL)
if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
AbortNode(state, "Failed to write block");
if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
return error("AcceptBlock(): ReceivedBlockTransactions failed");
if ( usetmp != 0 )
pindex->nStatus |= BLOCK_IN_TMPFILE;
} catch (const std::runtime_error& e) {
return AbortNode(state, std::string("System error: ") + e.what());
}
@@ -5412,7 +5541,7 @@ bool CheckDiskSpace(uint64_t nAdditionalBytes)
FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
{
static int32_t didinit[64];
static int32_t didinit[256];
if (pos.IsNull())
return NULL;
boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
@@ -5556,6 +5685,7 @@ bool static LoadBlockIndexDB()
// Load block file info
pblocktree->ReadLastBlockFile(nLastBlockFile);
vinfoBlockFile.resize(nLastBlockFile + 1);
tmpBlockFiles.resize(nLastTmpFile + 1);
LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
@@ -5579,7 +5709,6 @@ bool static LoadBlockIndexDB()
if (pindex->nStatus & BLOCK_HAVE_DATA) {
setBlkDataFiles.insert(pindex->nFile);
}
//komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
}
//fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
@@ -5920,6 +6049,7 @@ void UnloadBlockIndex()
nSyncStarted = 0;
mapBlocksUnlinked.clear();
vinfoBlockFile.clear();
tmpBlockFiles.clear();
nLastBlockFile = 0;
nBlockSequenceId = 1;
mapBlockSource.clear();
@@ -5955,6 +6085,7 @@ bool LoadBlockIndex()
bool InitBlockIndex() {
const CChainParams& chainparams = Params();
LOCK(cs_main);
tmpBlockFiles.clear();
// Initialize global variables that cannot be constructed at startup.
recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
@@ -5987,7 +6118,7 @@ bool InitBlockIndex() {
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
CDiskBlockPos blockPos;
CValidationState state;
if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
if (!FindBlockPos(0,state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
return error("LoadBlockIndex(): FindBlockPos failed");
if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
return error("LoadBlockIndex(): writing genesis block to disk failed");
@@ -6986,6 +7117,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
else if (strCommand == "tx")
{
if (IsInitialBlockDownload())
return true;
vector<uint256> vWorkQueue;
vector<uint256> vEraseQueue;
CTransaction tx;