From dce8360e44d5330cc9f9d09c9b09ac9237237204 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Mar 2015 05:34:06 -0700 Subject: Reduce checkpoints' effect on consensus. Instead of only checking height to decide whether to disable script checks, actually check whether a block is an ancestor of a checkpoint, up to which headers have been validated. This means that we don't have to prevent accepting a side branch anymore - it will be safe, just less fast to do. We still need to prevent being fed a multitude of low-difficulty headers filling up our memory. The mechanism for that is unchanged for now: once a checkpoint is reached with headers, no headers chain branching off before that point are allowed anymore. --- src/chain.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/chain.cpp') diff --git a/src/chain.cpp b/src/chain.cpp index 719256106..5b8ce076c 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -82,9 +82,10 @@ CBlockIndex* CBlockIndex::GetAncestor(int height) while (heightWalk > height) { int heightSkip = GetSkipHeight(heightWalk); int heightSkipPrev = GetSkipHeight(heightWalk - 1); - if (heightSkip == height || - (heightSkip > height && !(heightSkipPrev < heightSkip - 2 && - heightSkipPrev >= height))) { + if (pindexWalk->pskip != NULL && + (heightSkip == height || + (heightSkip > height && !(heightSkipPrev < heightSkip - 2 && + heightSkipPrev >= height)))) { // Only follow pskip if pprev->pskip isn't better than pskip->pprev. pindexWalk = pindexWalk->pskip; heightWalk = heightSkip; -- cgit v1.2.3 From 50262d89531692473ff557c1061aee22aa4cca1c Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Tue, 18 Nov 2014 22:16:32 +0100 Subject: Allow block announcements with headers This replaces using inv messages to announce new blocks, when a peer requests (via the new "sendheaders" message) that blocks be announced with headers instead of inv's. Since headers-first was introduced, peers send getheaders messages in response to an inv, which requires generating a block locator that is large compared to the size of the header being requested, and requires an extra round-trip before a reorg can be relayed. Save time by tracking headers that a peer is likely to know about, and send a headers chain that would connect to a peer's known headers, unless the chain would be too big, in which case we revert to sending an inv instead. Based off of @sipa's commit to announce all blocks in a reorg via inv, which has been squashed into this commit. Rebased-by: Pieter Wuille --- src/chain.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/chain.cpp') diff --git a/src/chain.cpp b/src/chain.cpp index 5b8ce076c..3450ed6c3 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -51,6 +51,9 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { } const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { + if (pindex == NULL) { + return NULL; + } if (pindex->nHeight > Height()) pindex = pindex->GetAncestor(Height()); while (pindex && !Contains(pindex)) -- cgit v1.2.3 From e86756193ebdbf71504e2a1a8db43e38d57f9673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Mon, 30 Nov 2015 00:46:49 +0100 Subject: MOVEONLY: non-consensus: from pow to chain: - GetBlockProof - GetBlockProofEquivalentTime --- src/chain.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/chain.cpp') diff --git a/src/chain.cpp b/src/chain.cpp index 3450ed6c3..32f6480f8 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -110,3 +110,35 @@ void CBlockIndex::BuildSkip() if (pprev) pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); } + +arith_uint256 GetBlockProof(const CBlockIndex& block) +{ + arith_uint256 bnTarget; + bool fNegative; + bool fOverflow; + bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); + if (fNegative || fOverflow || bnTarget == 0) + return 0; + // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 + // as it's too large for a arith_uint256. However, as 2**256 is at least as large + // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, + // or ~bnTarget / (nTarget+1) + 1. + return (~bnTarget / (bnTarget + 1)) + 1; +} + +int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params) +{ + arith_uint256 r; + int sign = 1; + if (to.nChainWork > from.nChainWork) { + r = to.nChainWork - from.nChainWork; + } else { + r = from.nChainWork - to.nChainWork; + sign = -1; + } + r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip); + if (r.bits() > 63) { + return sign * std::numeric_limits::max(); + } + return sign * r.GetLow64(); +} -- cgit v1.2.3 From 84c13e759dbb0de282e2c8ce43d77f4d52fda6d9 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 26 Apr 2016 14:34:40 +0200 Subject: chain: Add assertion in case of missing records in index db --- src/chain.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/chain.cpp') diff --git a/src/chain.cpp b/src/chain.cpp index 32f6480f8..77e924e70 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -93,6 +93,7 @@ CBlockIndex* CBlockIndex::GetAncestor(int height) pindexWalk = pindexWalk->pskip; heightWalk = heightSkip; } else { + assert(pindexWalk->pprev); pindexWalk = pindexWalk->pprev; heightWalk--; } -- cgit v1.2.3 From cb08fdbf78685b55029768524ca867772711c32b Mon Sep 17 00:00:00 2001 From: Pedro Branco Date: Thu, 16 Jun 2016 15:57:48 +0100 Subject: Add importmulti rpc call --- src/chain.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/chain.cpp') diff --git a/src/chain.cpp b/src/chain.cpp index 77e924e70..1e611906d 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -61,6 +61,13 @@ const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { return pindex; } +CBlockIndex* CChain::FindLatestBefore(int64_t nTime) const +{ + std::vector::const_iterator lower = std::lower_bound(vChain.begin(), vChain.end(), nTime, + [](CBlockIndex* pBlock, const int64_t& time) -> bool { return pBlock->GetBlockTime() < time; }); + return (lower == vChain.end() ? NULL : *lower); +} + /** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ int static inline InvertLowestOne(int n) { return n & (n - 1); } -- cgit v1.2.3 From 27765b6403cece54320374b37afb01a0cfe571c3 Mon Sep 17 00:00:00 2001 From: isle2983 Date: Sat, 31 Dec 2016 11:01:21 -0700 Subject: Increment MIT Licence copyright header year on files modified in 2016 Edited via: $ contrib/devtools/copyright_header.py update . --- src/chain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/chain.cpp') diff --git a/src/chain.cpp b/src/chain.cpp index 1e611906d..3cd7b3392 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -- cgit v1.2.3 From 997a98a674df70a2192e8d8b91c631e5c241509d Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Sun, 8 Jan 2017 04:05:14 +0000 Subject: Replace FindLatestBefore used by importmuti with FindEarliestAtLeast. In spite of the name FindLatestBefore used std::lower_bound to try to find the earliest block with a nTime greater or equal to the the requested value. But lower_bound uses bisection and requires the input to be ordered with respect to the comparison operation. Block times are not well ordered. I don't know what lower_bound is permitted to do when the data is not sufficiently ordered, but it's probably not good. (I could construct an implementation which would infinite loop...) To resolve the issue this commit introduces a maximum-so-far to the block indexes and searches that. For clarity the function is renamed to reflect what it actually does. An issue that remains is that there is no grace period in importmulti: If a address is created at time T and a send is immediately broadcast and included by a miner with a slow clock there may not yet have been any block with at least time T. The normal rescan has a grace period of 7200 seconds, but importmulti does not. --- src/chain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/chain.cpp') diff --git a/src/chain.cpp b/src/chain.cpp index 3cd7b3392..0f4d422b9 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -61,10 +61,10 @@ const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { return pindex; } -CBlockIndex* CChain::FindLatestBefore(int64_t nTime) const +CBlockIndex* CChain::FindEarliestAtLeast(int64_t nTime) const { std::vector::const_iterator lower = std::lower_bound(vChain.begin(), vChain.end(), nTime, - [](CBlockIndex* pBlock, const int64_t& time) -> bool { return pBlock->GetBlockTime() < time; }); + [](CBlockIndex* pBlock, const int64_t& time) -> bool { return pBlock->GetBlockTimeMax() < time; }); return (lower == vChain.end() ? NULL : *lower); } -- cgit v1.2.3 From b7b48c8bbdf7a90861610b035d8b0a247ef78c45 Mon Sep 17 00:00:00 2001 From: Karl-Johan Alm Date: Fri, 27 Jan 2017 17:43:41 +0900 Subject: Refactor: Remove using namespace from src/*.cpp. --- src/chain.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/chain.cpp') diff --git a/src/chain.cpp b/src/chain.cpp index 0f4d422b9..a5b369c4f 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -5,8 +5,6 @@ #include "chain.h" -using namespace std; - /** * CChain implementation */ -- cgit v1.2.3 From bc8cca48968dfa3f60b5eae6a2b92bdd2870eee3 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Sun, 13 Aug 2017 13:31:12 +0100 Subject: Merge AuxPoW support from Namecore Changes are as below: Wrap CBlockHeader::nVersion into a new class (CBlockVersion). This allows to take care of interpreting the field into a base version, auxpow flag and the chain ID. Update getauxblock.py for new 'generate' RPC call. Add 'auxpow' to block JSON. Accept auxpow as PoW verification. Add unit tests for auxpow verification. Add check for memory-layout of CBlockVersion. Weaken auxpow chain ID checks for the testnet. Allow Params() to overrule when to check the auxpow chain ID and for legacy blocks. Use this to disable the checks on testnet. Introduce CPureBlockHeader. Split the block header part that is used by auxpow and the "real" block header (that uses auxpow) to resolve the cyclic dependency between the two. Differentiate between uint256 and arith_uint256. This change was done upstream, modify the auxpow code. Add missing lock in auxpow_tests. Fix REST header check for auxpow headers. Those can be longer, thus take that into account. Also perform the check actually on an auxpow header. Correctly set the coinbase for getauxblock results. Call IncrementExtraNonce in getauxblock so that the coinbase is actually initialised with the stuff it should be. (BIP30 block height and COINBASE_FLAGS.) Implement getauxblock plus regression test. Turn auxpow test into FIXTURE test. This allows using of the Params() calls. Move CMerkleTx code to auxpow.cpp. Otherwise we get linker errors when building without wallet. Fix rebase with BIP66. Update the code to handle BIP66's nVersion=3. Enforce that auxpow parent blocks have no auxpow block version. This is for compatibility with namecoind. See also https://github.com/namecoin/namecoin/pull/199. Move auxpow-related parameters to Consensus::Params. --- src/chain.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/chain.cpp') diff --git a/src/chain.cpp b/src/chain.cpp index a5b369c4f..e42d6497f 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -4,6 +4,34 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chain.h" +#include "validation.h" + +using namespace std; + +/* Moved here from the header, because we need auxpow and the logic + becomes more involved. */ +CBlockHeader CBlockIndex::GetBlockHeader(const Consensus::Params& consensusParams) const +{ + CBlockHeader block; + + /* The CBlockIndex object's block header is missing the auxpow. + So if this is an auxpow block, read it from disk instead. We only + have to read the actual *header*, not the full block. */ + if (block.IsAuxpow()) + { + ReadBlockHeaderFromDisk(block, this, consensusParams); + return block; + } + + block.nVersion = nVersion; + if (pprev) + block.hashPrevBlock = pprev->GetBlockHash(); + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block; +} /** * CChain implementation -- cgit v1.2.3 From 3c060b31fe26a753723b0ef1acf414ef18ddfb8e Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Thu, 11 Jan 2018 21:04:33 +0000 Subject: Load AuxPoW blocks from index correctly (#1443) Load AuxPoW blocks from index correctly, by setting the version on the block before trying to check if it's AuxPoW. Previously the AuxPoW part of the block was never loaded because the check always failed. --- src/chain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/chain.cpp') diff --git a/src/chain.cpp b/src/chain.cpp index e42d6497f..2ce98818f 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -14,6 +14,8 @@ CBlockHeader CBlockIndex::GetBlockHeader(const Consensus::Params& consensusParam { CBlockHeader block; + block.nVersion = nVersion; + /* The CBlockIndex object's block header is missing the auxpow. So if this is an auxpow block, read it from disk instead. We only have to read the actual *header*, not the full block. */ @@ -23,7 +25,6 @@ CBlockHeader CBlockIndex::GetBlockHeader(const Consensus::Params& consensusParam return block; } - block.nVersion = nVersion; if (pprev) block.hashPrevBlock = pprev->GetBlockHash(); block.hashMerkleRoot = hashMerkleRoot; -- cgit v1.2.3