diff options
author | Gregory Maxwell <greg@xiph.org> | 2013-01-11 06:27:30 -0800 |
---|---|---|
committer | Gregory Maxwell <greg@xiph.org> | 2013-01-11 06:27:30 -0800 |
commit | 1f4b80a43798eff00167c529abd770635ea98a26 (patch) | |
tree | 69e64f6678cbc17e0471b4fcbd8bd23b5f32e86c /src/main.h | |
parent | 45a1ec51b14aae32397a5e3e3d67ff9137855137 (diff) | |
parent | 1f355b66cd90f1bd96a862604a7216e8ba56f853 (diff) |
Merge pull request #2145 from sipa/checkcoins
Coin database checks
Diffstat (limited to 'src/main.h')
-rw-r--r-- | src/main.h | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/src/main.h b/src/main.h index d34778d12f..50e0004585 100644 --- a/src/main.h +++ b/src/main.h @@ -128,6 +128,8 @@ FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false); bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL); /** Load the block tree and coins database from disk */ bool LoadBlockIndex(); +/** Verify consistency of the block and coin databases */ +bool VerifyDB(); /** Print the loaded block tree */ void PrintBlockTree(); /** Find a block by height in the currently-connected chain */ @@ -748,7 +750,7 @@ public: READWRITE(vtxundo); ) - bool WriteToDisk(CDiskBlockPos &pos) + bool WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock) { // Open history file to append CAutoFile fileout = CAutoFile(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); @@ -766,6 +768,12 @@ public: pos.nPos = (unsigned int)fileOutPos; fileout << *this; + // calculate & write checksum + CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); + hasher << hashBlock; + hasher << *this; + fileout << hasher.GetHash(); + // Flush stdio buffers and commit to disk before returning fflush(fileout); if (!IsInitialBlockDownload()) @@ -773,6 +781,44 @@ public: return true; } + + bool ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock) + { + // Open history file to read + CAutoFile filein = CAutoFile(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); + if (!filein) + return error("CBlockUndo::ReadFromDisk() : OpenBlockFile failed"); + + // Read block + uint256 hashChecksum; + try { + filein >> *this; + } + catch (std::exception &e) { + return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); + } + + // for compatibility with pre-release code that didn't write checksums to undo data + // TODO: replace by a simply 'filein >> hashChecksum' in the above try block + try { + filein >> hashChecksum; + } catch (std::exception &e) { + hashChecksum = 0; + } + uint32_t hashInit = hashChecksum.Get64(0) & 0xFFFFFFFFUL; + if (hashChecksum == 0 || memcmp(&hashInit, pchMessageStart, 4) == 0) + return true; + + // Verify checksum + CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); + hasher << hashBlock; + hasher << *this; + if (hashChecksum != hasher.GetHash()) + return error("CBlockUndo::ReadFromDisk() : checksum mismatch"); + + return true; + } + }; /** pruned version of CTransaction: only retains metadata and unspent transaction outputs @@ -1307,8 +1353,11 @@ public: } - // Undo the effects of this block (with given index) on the UTXO set represented by coins - bool DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &coins); + /** Undo the effects of this block (with given index) on the UTXO set represented by coins. + * In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean + * will be true if no problems were found. Otherwise, the return value will be false in case + * of problems. Note that in any case, coins may be modified. */ + bool DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &coins, bool *pfClean = NULL); // Apply the effects of this block (with given index) on the UTXO set represented by coins bool ConnectBlock(CBlockIndex *pindex, CCoinsViewCache &coins, bool fJustCheck=false); |