diff -uNr a/bitcoin/manifest b/bitcoin/manifest --- a/bitcoin/manifest 5e95516c2bdccfbb9fdb2924c3e1f778472d30287367b604c954be289c309fde87e44a3367c27734df0e167d7fa36ae267bc6ed8d3c79625b7ca15bf97f1fa3f +++ b/bitcoin/manifest be308814fb804ce1acf810e0174b2ce4835b603dba43672f7953c2a14602bb396f1eba2e0e0810f7a80695cd5952317f0df49f308c0afb31161e9020198ad0f0 @@ -41,3 +41,4 @@ 709104 bitcoin_tx_fee_cleanup jfw Add nMinRelayTxFee global accessed with new -minrelaytxfee option, minrelaytxfee field in getinfo, and setminrelaytxfee RPC command. Use this to replace the fixed MIN_RELAY_TX_FEE. Simplify mempool acceptance rules so this threshold always applies (no special-case free transactions or rubber-banding threshold by current block size). Adjust block generation logic accordingly, though it still sorts on a strange age-value priority rather than fee. Simplify wallet to always send using its configured fee (-paytxfee) and change its default to match the default minrelaytxfee, removing the fixed MIN_TX_FEE. Make nTransactionFee access thread-safe and expand the help text for its inconsistently named RPC setter. Fees are now figured properly without premature rounding, as floor((size*rate)/1024) rather than (floor(size/1000)+1)*rate. *NOTE:* This change may substantially impact wallet transaction fees and node memory usage patterns but puts more control over these in the hands of the operator. 712609 bitcoin_fsync_all_blocks jfw Don't skip fsync of blocks to disk during sync, because this can leave the raw block collection unrecoverably inconsistent with the BDB block index in the event of a crash. 713908 bitcoin_checkblocks_cleanup jfw Let the -checkblocks option take a positive integer value to set the the check depth limit or zero for no limit. Drop the default from 2500 to 144. Break the implementation out from a long-winded CTxDB member function whose class context was irrelevant to it. Simplify its loop bounds (which revealed a corner case of genesis block possibly going unchecked), fix off-by-one on the nominal depth limit and make it count from the first *good* block found. Add progress reporting and improve error messages and commentary. Exit before loading other things when it fails. *NOTE:* This breaks CLI/config file compatibility with the prior sloppy undocumented situation where any -checkblocks value at all would enable full checking. +732505 bitcoin_getblockindex_etc_corrected jfw Add 'getblockindex' RPC command to view CBlockIndex objects as found in the memory block index and ultimately the database. Also corrects the InvalidChainFound log message for consistency with the safe mode warning changed in bitcoin_help_tuneups, and adds 'eatblock' to the safe mode command whitelist (since it's equivalent to receiving blocks from the network, which is not restricted in safe mode). (Prior patch version missed the newline in the log message.) diff -uNr a/bitcoin/src/bitcoinrpc.cpp b/bitcoin/src/bitcoinrpc.cpp --- a/bitcoin/src/bitcoinrpc.cpp cf90b3587fee9524551fe517aff743c52062de1e377f468d58f6185f2b6cf66894f62bff386d3c43864775240923d19e12042f295c5ab82f3a8587ba7fb495df +++ b/bitcoin/src/bitcoinrpc.cpp 75044b931d61cddd9f751edc71844e87fe3a1f1343e45a6d44b417f32258740690a5297033cfa6789954607f639141101d117bbf7a91ce1f900d29f9d9212fc7 @@ -1939,6 +1939,59 @@ return hash.GetHex(); } +Value getblockindex(const Array ¶ms, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getblockindex \n" + "Returns a record from the block index, containing metadata on the given block:\n" + " \"hash\" : block hash (hex string or null; should be the same as provided)\n" + " \"previousblockhash\" : hash of the previous block in chain (hex string or null)\n" + " \"nextblockhash\" : hash of the next block in chain (hex string or null)\n" + " \"file\" : block file number on disk\n" + " \"blockpos\" : byte position in block file (number)\n" + " \"height\" : height of block in chain (number)\n" + " \"chainwork\" : total chain work (bignum, as hex string)\n" + " \"version\" : block version (number)\n" + " \"merkleroot\" : merkle root (hex string)\n" + " \"time\" : block time in seconds since epoch (number)\n" + " \"bits\" : difficulty target in compact format (32-bit hex string)\n" + " \"nonce\" : block nonce (number)" + ); + + uint256 hashBlock = 0; + hashBlock.SetHex(params[0].get_str()); + + if (mapBlockIndex.count(hashBlock) == 0) + throw JSONRPCError(-5, "Block not found"); + CBlockIndex *pindex = mapBlockIndex[hashBlock]; + if (!pindex) + throw runtime_error("BUG: null mapBlockIndex entry"); + + Object result; + result.push_back(Pair("hash", pindex->phashBlock + ? pindex->phashBlock->GetHex() + : Value::null)); + result.push_back(Pair("previousblockhash", pindex->pprev && pindex->pprev->phashBlock + ? pindex->pprev->phashBlock->GetHex() + : Value::null)); + result.push_back(Pair("nextblockhash", pindex->pnext && pindex->pnext->phashBlock + ? pindex->pnext->phashBlock->GetHex() + : Value::null)); + result.push_back(Pair("file", (boost::int64_t)pindex->nFile)); + result.push_back(Pair("blockpos", (boost::int64_t)pindex->nBlockPos)); + result.push_back(Pair("height", pindex->nHeight)); + result.push_back(Pair("chainwork", pindex->bnChainWork.GetHex())); + // block header + result.push_back(Pair("version", pindex->nVersion)); + result.push_back(Pair("merkleroot", pindex->hashMerkleRoot.GetHex())); + result.push_back(Pair("time", (boost::int64_t)pindex->nTime)); + result.push_back(Pair("bits", strprintf("%08x", pindex->nBits))); + // Including the decoded difficulty target as a double might be nice here, as from GetDifficulty(), but I haven't figured out how that encoding works and whether such conversion is precise. -jfw + result.push_back(Pair("nonce", (boost::int64_t)pindex->nNonce)); + return result; +} + // // Call Table @@ -1993,6 +2046,7 @@ make_pair("dumpprivkey", &dumpprivkey), make_pair("getrawtransaction", &getrawtransaction), make_pair("sendrawtransaction", &sendrawtransaction), + make_pair("getblockindex", &getblockindex), }; map mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); @@ -2020,6 +2074,8 @@ "getwork", "getmemorypool", "dumpblock", + "eatblock", + "getblockindex", }; set setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0])); diff -uNr a/bitcoin/src/main.cpp b/bitcoin/src/main.cpp --- a/bitcoin/src/main.cpp 1d1d30ea6ea4bb23d6f24216f94f7cb47e7575995adb8b833bbb95b082bbedda90983be2ad3a28be4b8fa6dffb0926e906a596b90044c64145c6cc4dd0900eb9 +++ b/bitcoin/src/main.cpp a30a8ae3e233c6f2b132532b85cedd41dc75defb30309abc5a58cd6d7c9c50b0880c88a6ba7b3440d590e21e29b0b90901b2959ac12c8558bb6ad50ab4d995e6 @@ -741,7 +741,8 @@ printf("InvalidChainFound: invalid block=%s height=%d work=%s\n", pindexNew->GetBlockHash().ToString().c_str(), pindexNew->nHeight, pindexNew->bnChainWork.ToString().c_str()); printf("InvalidChainFound: current best=%s height=%d work=%s\n", hashBestChain.ToString().c_str(), nBestHeight, bnBestChainWork.ToString().c_str()); if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6) - printf("InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n"); + // message partially duplicated in GetWarnings + printf("InvalidChainFound: WARNING: Received invalid chain with greater proof-of-work. Displayed transactions may not be correct! Your database or other nodes may be corrupted.\n"); } @@ -1638,6 +1639,7 @@ // Longer invalid proof-of-work chain if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6) + // message partially duplicated in InvalidChainFound strStatusBar = strRPC = "WARNING: Received invalid chain with greater proof-of-work. Displayed transactions may not be correct! Your database or other nodes may be corrupted."; if (strFor == "statusbar")