X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fmain.cpp;h=c9bd58d4f56f2e50d9dbba030e35cb8c01a60e49;hb=e9a025643ea90b52f6f0989746adf98770c9f578;hp=328d61b122188364598965f1b3ee6e7cb8020984;hpb=fd3035cd568a2a8d3017845d9eed7fc0daeaa2e7;p=novacoin.git diff --git a/src/main.cpp b/src/main.cpp index 328d61b..c9bd58d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,7 +6,7 @@ #include "alert.h" #include "checkpoints.h" #include "db.h" -#include "txdb.h" +#include "txdb-leveldb.h" #include "init.h" #include "interface.h" #include "checkqueue.h" @@ -2537,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)) { @@ -2572,6 +2559,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) } } + // ppcoin: ask for pending sync-checkpoint if any if (!IsInitialBlockDownload()) Checkpoints::AskForPendingSyncCheckpoint(pfrom); @@ -2606,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++) @@ -2621,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); } @@ -2860,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; @@ -3823,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(); @@ -3849,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 @@ -3890,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();