diff --git a/src/cc/marmara.cpp b/src/cc/marmara.cpp index 8f8de12e2..0e301ba97 100644 --- a/src/cc/marmara.cpp +++ b/src/cc/marmara.cpp @@ -496,7 +496,7 @@ UniValue MarmaraLock(uint64_t txfee,int64_t amount,int32_t height) else { result.push_back(Pair("result",(char *)"success")); - result.push_back(Pair("rawtx",rawtx)); + result.push_back(Pair("hex",rawtx)); return(result); } } else errorstr = (char *)"insufficient funds"; @@ -600,7 +600,7 @@ UniValue MarmaraSettlement(uint64_t txfee,uint256 refbatontxid) mtx.vout.push_back(MakeCC1of2vout(EVAL_MARMARA,change,Marmarapk,pk)); rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,MarmaraLoopOpret('S',createtxid,mypk,0,refmatures,currency),pubkeys); result.push_back(Pair("result",(char *)"success")); - result.push_back(Pair("rawtx",rawtx)); + result.push_back(Pair("hex",rawtx)); return(result); } else remaining -= inputsum; if ( mtx.vin.size() >= CC_MAXVINS - MARMARA_VINS ) @@ -616,7 +616,7 @@ UniValue MarmaraSettlement(uint64_t txfee,uint256 refbatontxid) rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,MarmaraLoopOpret('D',createtxid,mypk,-remaining,refmatures,currency),pubkeys); result.push_back(Pair("result",(char *)"error")); result.push_back(Pair("error",(char *)"insufficient funds")); - result.push_back(Pair("rawtx",rawtx)); + result.push_back(Pair("hex",rawtx)); result.push_back(Pair("remaining",ValueFromAmount(remaining))); } else @@ -731,7 +731,7 @@ UniValue MarmaraReceive(uint64_t txfee,CPubKey senderpk,int64_t amount,std::stri else { result.push_back(Pair("result",(char *)"success")); - result.push_back(Pair("rawtx",rawtx)); + result.push_back(Pair("hex",rawtx)); result.push_back(Pair("funcid","R")); result.push_back(Pair("createtxid",createtxid.GetHex())); if ( batontxid != zeroid ) @@ -787,7 +787,7 @@ UniValue MarmaraIssue(uint64_t txfee,uint8_t funcid,CPubKey receiverpk,int64_t a else { result.push_back(Pair("result",(char *)"success")); - result.push_back(Pair("rawtx",rawtx)); + result.push_back(Pair("hex",rawtx)); char str[2]; str[0] = funcid, str[1] = 0; result.push_back(Pair("funcid",str)); result.push_back(Pair("createtxid",createtxid.GetHex())); @@ -1025,7 +1025,7 @@ UniValue MarmaraPoolPayout(uint64_t txfee,int32_t firstheight,double perc,char * else { result.push_back(Pair("result",(char *)"success")); - result.push_back(Pair("rawtx",rawtx)); + result.push_back(Pair("hex",rawtx)); if ( totalpayout > 0 && total > totalpayout-txfee ) { result.push_back(Pair("firstheight",firstheight)); diff --git a/src/chain.h b/src/chain.h index 49b206480..45db77720 100644 --- a/src/chain.h +++ b/src/chain.h @@ -115,6 +115,7 @@ enum BlockStatus: uint32_t { BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, BLOCK_ACTIVATES_UPGRADE = 128, //! block activates a network upgrade + BLOCK_IN_TMPFILE = 256 }; //! Short-hand for the highest consensus validity we implement. diff --git a/src/komodo.h b/src/komodo.h index 62310a0ed..35fee05ad 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -708,7 +708,9 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr if ( ASSETCHAINS_SYMBOL[0] != 0 ) printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",ASSETCHAINS_SYMBOL,height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth); if (RemoveOrphanedBlocks(*notarizedheightp)) - fprintf(stderr, "Sucessfully removed all known orphaned blocks before height %d\n",*notarizedheightp); + { + //fprintf(stderr, "Sucessfully removed all known orphaned blocks before height %d\n",*notarizedheightp); + } if ( ASSETCHAINS_SYMBOL[0] == 0 ) { if ( signedfp == 0 ) diff --git a/src/main.cpp b/src/main.cpp index a2980dea8..bfb1a0535 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -76,6 +76,7 @@ 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; @@ -182,8 +183,9 @@ namespace { multimap mapBlocksUnlinked; CCriticalSection cs_LastBlockFile; - std::vector vinfoBlockFile; + std::vector 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 @@ -1998,12 +2000,11 @@ bool RemoveOrphanedBlocks(int32_t notarized_height) LOCK(cs_main); std::vector prunedblocks; std::set setTips; - int32_t n = 0; + 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; - fprintf(stderr, "removing oprhans from before %d\n", notarized_height); - // Most of this code is a direct copy from GetChainTips RPC. Which gives a return of all + // 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) { @@ -2032,14 +2033,16 @@ bool RemoveOrphanedBlocks(int32_t notarized_height) if ( forked != 0 ) prunedblocks.push_back(block); } - if (pblocktree->EraseBatchSync(prunedblocks)) + 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; @@ -2192,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); @@ -3223,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); @@ -3255,6 +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() ) @@ -4549,43 +4570,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 *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; @@ -4602,19 +4637,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 *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; @@ -4658,7 +4700,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 ) { @@ -4667,9 +4709,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"); @@ -5170,13 +5212,14 @@ bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, C CDiskBlockPos blockPos; if (dbp != NULL) blockPos = *dbp; - if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL)) + if (!FindBlockPos(1,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"); + pindex->nStatus |= BLOCK_IN_TMPFILE; } catch (const std::runtime_error& e) { return AbortNode(state, std::string("System error: ") + e.what()); } @@ -5494,7 +5537,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); @@ -5638,6 +5681,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]); @@ -5661,7 +5705,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::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) @@ -6002,6 +6045,7 @@ void UnloadBlockIndex() nSyncStarted = 0; mapBlocksUnlinked.clear(); vinfoBlockFile.clear(); + tmpBlockFiles.clear(); nLastBlockFile = 0; nBlockSequenceId = 1; mapBlockSource.clear(); @@ -6037,6 +6081,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)); @@ -6069,7 +6114,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"); diff --git a/src/main.h b/src/main.h index 35c01c23a..40170fa70 100644 --- a/src/main.h +++ b/src/main.h @@ -803,7 +803,7 @@ bool GetAddressUnspent(uint160 addressHash, int type, std::vector > &unspentOutputs); /** Functions for disk access for blocks */ -bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); +bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos,bool checkPOW); bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW); bool RemoveOrphanedBlocks(int32_t notarized_height); diff --git a/src/sendalert.cpp b/src/sendalert.cpp index 700146338..6525cb356 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -103,7 +103,7 @@ void ThreadSendAlert() // 4000 or higher will put the RPC into safe mode alert.nPriority = 4000; alert.strComment = ""; - alert.strStatusBar = "Your client version has degraded networking behavior. Please update to the most recent version of Verus (0.3.2 or later)."; + alert.strStatusBar = "Your client version has degraded networking behavior. Please update to the most recent version of Komodo (0.3.3 or later)."; alert.strRPCError = alert.strStatusBar; // Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done: