X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fmain.cpp;h=c9bd58d4f56f2e50d9dbba030e35cb8c01a60e49;hb=e9a025643ea90b52f6f0989746adf98770c9f578;hp=292cc51d3238488b067765f8ef5a59a3018debc3;hpb=68a1b56a7c7a82ee863f5bddbb7708946da950a6;p=novacoin.git diff --git a/src/main.cpp b/src/main.cpp index 292cc51..c9bd58d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,9 +6,9 @@ #include "alert.h" #include "checkpoints.h" #include "db.h" -#include "txdb.h" +#include "txdb-leveldb.h" #include "init.h" -#include "ui_interface.h" +#include "interface.h" #include "checkqueue.h" #include "kernel.h" #include @@ -1746,8 +1746,10 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (tx.nTime >= CHECKLOCKTIMEVERIFY_SWITCH_TIME) { nFlags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; - // OP_CHECKSEQUENCEVERIFY is senseless without BIP68, so we're going disable it for now. - // nFlags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; + } + + if (tx.nTime >= CHECKSEQUENCEVERIFY_SWITCH_TIME) { + nFlags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; } std::vector vChecks; @@ -1981,10 +1983,10 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) } // Connect further blocks - BOOST_REVERSE_FOREACH(CBlockIndex *pindex, vpindexSecondary) + for (std::vector::reverse_iterator rit = vpindexSecondary.rbegin(); rit != vpindexSecondary.rend(); ++rit) { CBlock block; - if (!block.ReadFromDisk(pindex)) + if (!block.ReadFromDisk(*rit)) { printf("SetBestChain() : ReadFromDisk failed\n"); break; @@ -1994,7 +1996,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) break; } // errors now are not fatal, we still did a reorganisation to a new chain in a valid way - if (!block.SetBestChainInner(txdb, pindex)) + if (!block.SetBestChainInner(txdb, *rit)) break; } } @@ -2535,19 +2537,6 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) if (!pblock->CheckBlock(true, true, (pblock->nTime > Checkpoints::GetLastCheckpointTime()))) return error("ProcessBlock() : CheckBlock FAILED"); - // ppcoin: verify hash target and signature of coinstake tx - if (pblock->IsProofOfStake()) - { - uint256 hashProofOfStake = 0, targetProofOfStake = 0; - if (!CheckProofOfStake(pblock->vtx[1], pblock->nBits, hashProofOfStake, targetProofOfStake)) - { - printf("WARNING: ProcessBlock(): check proof-of-stake failed for block %s\n", hash.ToString().c_str()); - return false; // do not error here as we expect this during initial block download - } - if (!mapProofOfStake.count(hash)) // add to mapProofOfStake - mapProofOfStake.insert(make_pair(hash, hashProofOfStake)); - } - CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint(); if (pcheckpoint && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash)) { @@ -2570,6 +2559,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) } } + // ppcoin: ask for pending sync-checkpoint if any if (!IsInitialBlockDownload()) Checkpoints::AskForPendingSyncCheckpoint(pfrom); @@ -2604,11 +2594,31 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) return true; } + // ppcoin: verify hash target and signature of coinstake tx + if (pblock->IsProofOfStake()) + { + uint256 hashProofOfStake = 0, targetProofOfStake = 0; + if (!CheckProofOfStake(pblock->vtx[1], pblock->nBits, hashProofOfStake, targetProofOfStake)) + { + // Having prev block in index should be enough for validation + if (mapBlockIndex.count(pblock->hashPrevBlock)) + return error("ProcessBlock(): check proof-of-stake (%s, %d) failed for block %s\n", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, hash.ToString().c_str()); + + // Orphan blocks should be validated later once all parents successfully added to local chain + printf("ProcessBlock(): delaying proof-of-stake validation for orphan block %s\n", hash.ToString().c_str()); + return false; // do not error here as we expect this to happen here + } + + // Needed for AcceptBlock() + if (!mapProofOfStake.count(hash)) + mapProofOfStake.insert(make_pair(hash, hashProofOfStake)); + } + // Store to disk if (!pblock->AcceptBlock()) return error("ProcessBlock() : AcceptBlock FAILED"); - // Recursively process any orphan blocks that depended on this one + // Process any orphan blocks that depended on this one vector vWorkQueue; vWorkQueue.push_back(hash); for (unsigned int i = 0; i < vWorkQueue.size(); i++) @@ -2619,12 +2629,36 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) ++mi) { CBlock* pblockOrphan = (*mi).second; - if (pblockOrphan->AcceptBlock()) - vWorkQueue.push_back(pblockOrphan->GetHash()); - mapOrphanBlocks.erase(pblockOrphan->GetHash()); - setStakeSeenOrphan.erase(pblockOrphan->GetProofOfStake()); + uint256 hashOrphanBlock = pblockOrphan->GetHash(); + + if (pblockOrphan->IsProofOfStake()) { + // Check proof-of-stake and do other contextual + // preparations before running AcceptBlock() + uint256 hashOrphanProofOfStake = 0; + uint256 targetOrphanProofOfStake = 0; + + if (CheckProofOfStake(pblockOrphan->vtx[1], pblockOrphan->nBits, hashOrphanProofOfStake, targetOrphanProofOfStake)) + { + // Needed for AcceptBlock() + if (!mapProofOfStake.count(hashOrphanBlock)) + mapProofOfStake.insert(make_pair(hashOrphanBlock, hashOrphanProofOfStake)); + + // Finally, we're ready to run AcceptBlock() + if (pblockOrphan->AcceptBlock()) + vWorkQueue.push_back(hashOrphanBlock); + setStakeSeenOrphan.erase(pblockOrphan->GetProofOfStake()); + } + } else { + // proof-of-work verification + // is notoriously simpler + if (pblockOrphan->AcceptBlock()) + vWorkQueue.push_back(hashOrphanBlock); + } + + mapOrphanBlocks.erase(hashOrphanBlock); delete pblockOrphan; } + mapOrphanBlocksByPrev.erase(hashPrev); } @@ -2662,7 +2696,7 @@ bool CBlock::CheckBlockSignature() const bool CheckDiskSpace(uint64_t nAdditionalBytes) { - uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available; + uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available; // Check for nMinDiskSpace bytes (currently 50MB) if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) @@ -2678,7 +2712,7 @@ bool CheckDiskSpace(uint64_t nAdditionalBytes) return true; } -static filesystem::path BlockFilePath(unsigned int nFile) +static boost::filesystem::path BlockFilePath(unsigned int nFile) { string strBlockFn = strprintf("blk%04u.dat", nFile); return GetDataDir() / strBlockFn; @@ -2786,12 +2820,12 @@ bool LoadBlockIndex(bool fAllowNew) // CTxOut(empty) // vMerkleTree: 4cb33b3b6a - const char* pszTimestamp = "https://bitcointalk.org/index.php?topic=134179.msg1502196#msg1502196"; + const string strTimestamp = "https://bitcointalk.org/index.php?topic=134179.msg1502196#msg1502196"; CTransaction txNew; txNew.nTime = 1360105017; txNew.vin.resize(1); txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(9999) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(9999) << vector(strTimestamp.begin(), strTimestamp.end()); txNew.vout[0].SetEmpty(); CBlock block; block.vtx.push_back(txNew); @@ -2858,10 +2892,6 @@ bool LoadBlockIndex(bool fAllowNew) if (!txdb.WriteModifierUpgradeTime(nModifierUpgradeTime)) return error("LoadBlockIndex() : failed to write upgrade info"); } - -#ifndef USE_LEVELDB - txdb.Close(); -#endif } return true; @@ -3821,7 +3851,7 @@ bool ProcessMessages(CNode* pfrom) if (!hdr.IsValid()) { printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str()); - continue; + return false; } string strCommand = hdr.GetCommand(); @@ -3847,7 +3877,7 @@ bool ProcessMessages(CNode* pfrom) { printf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum); - continue; + return false; } // Copy message to its own buffer @@ -3888,8 +3918,10 @@ bool ProcessMessages(CNode* pfrom) PrintExceptionContinue(NULL, "ProcessMessages()"); } - if (!fRet) + if (!fRet) { printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize); + return false; + } } vRecv.Compact();