Skip to content

Commit

Permalink
Merge pull request GarlicoinOrg#22 from samwakewatson/patch-2
Browse files Browse the repository at this point in the history
adding rolling checkpointing
  • Loading branch information
retosen committed Aug 28, 2022
2 parents f57f275 + dc26156 commit 874832a
Show file tree
Hide file tree
Showing 20 changed files with 978 additions and 74 deletions.
3 changes: 2 additions & 1 deletion src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ BITCOIN_TESTS =\
test/txvalidationcache_tests.cpp \
test/versionbits_tests.cpp \
test/uint256_tests.cpp \
test/util_tests.cpp
test/util_tests.cpp \
test/finalization_tests.cpp

if ENABLE_WALLET
BITCOIN_TESTS += \
Expand Down
10 changes: 10 additions & 0 deletions src/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,13 @@ const CBlockIndex* LastCommonAncestor(const CBlockIndex* pa, const CBlockIndex*
assert(pa == pb);
return pa;
}

bool AreOnTheSameFork(const CBlockIndex *pa, const CBlockIndex *pb) {
if (pa->nHeight > pb->nHeight) {
pa = pa->GetAncestor(pb->nHeight);
} else if (pb->nHeight > pa->nHeight) {
pb = pb->GetAncestor(pa->nHeight);
}
return pa == pb;

}
18 changes: 17 additions & 1 deletion src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ class CBlockIndex
//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
int32_t nSequenceId;

//! (memory only) block header metadata
uint64_t nTimeReceived = 0;

//! (memory only) Maximum nTime in the chain up to and including this block.
unsigned int nTimeMax;

Expand All @@ -233,11 +236,13 @@ class CBlockIndex
nChainTx = 0;
nStatus = 0;
nSequenceId = 0;
nTimeReceived = 0;
nTimeMax = 0;

nVersion = 0;
hashMerkleRoot = uint256();
nTime = 0;
nTimeReceived = 0;
nBits = 0;
nNonce = 0;
}
Expand Down Expand Up @@ -309,6 +314,16 @@ class CBlockIndex
return (int64_t)nTimeMax;
}

int64_t GetHeaderReceivedTime() const
{
return nTimeReceived;
}

int64_t GetReceivedTimeDiff() const
{
return GetHeaderReceivedTime() - GetBlockTime();
}

static constexpr int nMedianTimeSpan = 11;

int64_t GetMedianTimePast() const
Expand Down Expand Up @@ -369,7 +384,8 @@ arith_uint256 GetBlockProof(const CBlockIndex& block);
int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&);
/** Find the forking point between two chain tips. */
const CBlockIndex* LastCommonAncestor(const CBlockIndex* pa, const CBlockIndex* pb);

/** Check if two block index are on the same fork. */
bool AreOnTheSameFork(const CBlockIndex *pa, const CBlockIndex *pb);

/** Used to marshal pointers into hashes for db storage. */
class CDiskBlockIndex : public CBlockIndex
Expand Down
62 changes: 61 additions & 1 deletion src/consensus/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,62 @@ static const unsigned char REJECT_NONSTANDARD = 0x40;
static const unsigned char REJECT_INSUFFICIENTFEE = 0x42;
static const unsigned char REJECT_CHECKPOINT = 0x43;

/**
* A "reason" why something was invalid, suitable for determining whether the
* provider of the object should be banned/ignored/disconnected/etc. These are
* much more granular than the rejection codes, which may be more useful for
* some other use-cases.
*/
enum class ValidationInvalidReason {
// txn and blocks:
//! not actually invalid
NONE,
//! invalid by consensus rules (excluding any below reasons)
CONSENSUS,
/**
* Invalid by a recent change to consensus rules.
* Currently unused as there are no such consensus rule changes.
*/
RECENT_CONSENSUS_CHANGE,
// Only blocks (or headers):
//! this object was cached as being invalid, but we don't know why
CACHED_INVALID,
//! invalid proof of work or time too old
BLOCK_INVALID_HEADER,
//! the block's data didn't match the data committed to by the PoW
BLOCK_MUTATED,
//! We don't have the previous block the checked one is built on
BLOCK_MISSING_PREV,
//! A block this one builds on is invalid
BLOCK_INVALID_PREV,
//! block timestamp was > 2 hours in the future (or our clock is bad)
BLOCK_TIME_FUTURE,
//! the block failed to meet one of our checkpoints
BLOCK_CHECKPOINT,
//! block finalization problems.
BLOCK_FINALIZATION,
// Only loose txn:
//! didn't meet our local policy rules
TX_NOT_STANDARD,
//! a transaction was missing some of its inputs
TX_MISSING_INPUTS,
//! transaction spends a coinbase too early, or violates locktime/sequence
//! locks
TX_PREMATURE_SPEND,
/**
* Tx already in mempool or conflicts with a tx in the chain
* TODO: Currently this is only used if the transaction already exists in
* the mempool or on chain,
* TODO: ATMP's fMissingInputs and a valid CValidationState being used to
* indicate missing inputs
*/
TX_CONFLICT,
//! violated mempool's fee/size/descendant/etc limits
TX_MEMPOOL_POLICY,

UNKNOWN,
};

/** Capture information about block/transaction validation */
class CValidationState {
private:
Expand All @@ -31,6 +87,7 @@ class CValidationState {
MODE_ERROR, //!< run-time error
} mode;
int nDoS;
ValidationInvalidReason m_reason = ValidationInvalidReason::UNKNOWN;
std::string strRejectReason;
unsigned int chRejectCode;
bool corruptionPossible;
Expand All @@ -53,7 +110,9 @@ class CValidationState {
}
bool Invalid(bool ret = false,
unsigned int _chRejectCode=0, const std::string &_strRejectReason="",
const std::string &_strDebugMessage="") {
const std::string &_strDebugMessage="",
ValidationInvalidReason reasonIn=ValidationInvalidReason::UNKNOWN) {
m_reason = reasonIn;
return DoS(0, ret, _chRejectCode, _strRejectReason, false, _strDebugMessage);
}
bool Error(const std::string& strRejectReasonIn) {
Expand Down Expand Up @@ -84,6 +143,7 @@ class CValidationState {
void SetCorruptionPossible() {
corruptionPossible = true;
}
ValidationInvalidReason GetReason() const { return m_reason; }
unsigned int GetRejectCode() const { return chRejectCode; }
std::string GetRejectReason() const { return strRejectReason; }
std::string GetDebugMessage() const { return strDebugMessage; }
Expand Down
1 change: 1 addition & 0 deletions src/httpserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <sync.h>
#include <ui_interface.h>

#include <deque>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down
2 changes: 2 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,11 +357,13 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
if (showDebug)
strUsage += HelpMessageOpt("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER));
strUsage += HelpMessageOpt("-finalizationdelay=<n>", strprintf(_("Set the minimum amount of time to wait between a block header reception and the block finalization. Unit is seconds (default: %d)"), DEFAULT_MIN_FINALIZATION_DELAY));
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup"));
strUsage += HelpMessageOpt("-debuglogfile=<file>", strprintf(_("Specify location of debug log file: this can be an absolute path or a path relative to the data directory (default: %s)"), DEFAULT_DEBUGLOGFILE));
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE));
strUsage += HelpMessageOpt("-mempoolexpiry=<n>", strprintf(_("Do not keep transactions in the mempool longer than <n> hours (default: %u)"), DEFAULT_MEMPOOL_EXPIRY));
strUsage += HelpMessageOpt("-maxreorgdepth=<n>", strprintf(_("Configure at what depth blocks are considered final (default: %d). Use -1 to disable."), DEFAULT_MAX_REORG_DEPTH));
if (showDebug) {
strUsage += HelpMessageOpt("-minimumchainwork=<hex>", strprintf("Minimum work assumed to exist on a valid chain in hex (default: %s, testnet: %s)", defaultChainParams->GetConsensus().nMinimumChainWork.GetHex(), testnetChainParams->GetConsensus().nMinimumChainWork.GetHex()));
}
Expand Down
8 changes: 4 additions & 4 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1177,15 +1177,15 @@ static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, co
void BitcoinGUI::subscribeToCoreSignals()
{
// Connect signals to client
uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
uiInterface.ThreadSafeQuestion.connect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4));
uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3));
uiInterface.ThreadSafeQuestion.connect(boost::bind(ThreadSafeMessageBox, this, boost::placeholders::_1, boost::placeholders::_3, boost::placeholders::_4));
}

void BitcoinGUI::unsubscribeFromCoreSignals()
{
// Disconnect signals from client
uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
uiInterface.ThreadSafeQuestion.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4));
uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3));
uiInterface.ThreadSafeQuestion.disconnect(boost::bind(ThreadSafeMessageBox, this, boost::placeholders::_1, boost::placeholders::_3, boost::placeholders::_4));
}

void BitcoinGUI::toggleNetworkActive()
Expand Down
20 changes: 10 additions & 10 deletions src/qt/clientmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,23 +316,23 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB
void ClientModel::subscribeToCoreSignals()
{
// Connect signals to client
uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
uiInterface.NotifyNetworkActiveChanged.connect(boost::bind(NotifyNetworkActiveChanged, this, _1));
uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2));
uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, boost::placeholders::_1));
uiInterface.NotifyNetworkActiveChanged.connect(boost::bind(NotifyNetworkActiveChanged, this, boost::placeholders::_1));
uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false));
uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true));
uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, false));
uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, true));
}

void ClientModel::unsubscribeFromCoreSignals()
{
// Disconnect signals from client
uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
uiInterface.NotifyNetworkActiveChanged.disconnect(boost::bind(NotifyNetworkActiveChanged, this, _1));
uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2));
uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, boost::placeholders::_1));
uiInterface.NotifyNetworkActiveChanged.disconnect(boost::bind(NotifyNetworkActiveChanged, this, boost::placeholders::_1));
uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false));
uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true));
uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, false));
uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, true));
}
14 changes: 7 additions & 7 deletions src/qt/splashscreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,29 +181,29 @@ static void ShowProgress(SplashScreen *splash, const std::string &title, int nPr
#ifdef ENABLE_WALLET
void SplashScreen::ConnectWallet(CWallet* wallet)
{
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2, false));
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2, false));
connectedWallets.push_back(wallet);
}
#endif

void SplashScreen::subscribeToCoreSignals()
{
// Connect signals to client
uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1));
uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2, _3));
uiInterface.InitMessage.connect(boost::bind(InitMessage, this, boost::placeholders::_1));
uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3));
#ifdef ENABLE_WALLET
uiInterface.LoadWallet.connect(boost::bind(&SplashScreen::ConnectWallet, this, _1));
uiInterface.LoadWallet.connect(boost::bind(&SplashScreen::ConnectWallet, this, boost::placeholders::_1));
#endif
}

void SplashScreen::unsubscribeFromCoreSignals()
{
// Disconnect signals from client
uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, _1));
uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2, _3));
uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, boost::placeholders::_1));
uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3));
#ifdef ENABLE_WALLET
for (CWallet* const & pwallet : connectedWallets) {
pwallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2, false));
pwallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2, false));
}
#endif
}
Expand Down
8 changes: 4 additions & 4 deletions src/qt/transactiontablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,13 +779,13 @@ static void ShowProgress(TransactionTableModel *ttm, const std::string &title, i
void TransactionTableModel::subscribeToCoreSignals()
{
// Connect signals to wallet
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3));
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2));
}

void TransactionTableModel::unsubscribeFromCoreSignals()
{
// Disconnect signals from wallet
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3));
wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2));
}
20 changes: 10 additions & 10 deletions src/qt/walletmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,21 +501,21 @@ static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly
void WalletModel::subscribeToCoreSignals()
{
// Connect signals to wallet
wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
wallet->NotifyWatchonlyChanged.connect(boost::bind(NotifyWatchonlyChanged, this, _1));
wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, boost::placeholders::_1));
wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3, boost::placeholders::_4, boost::placeholders::_5, boost::placeholders::_6));
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3));
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2));
wallet->NotifyWatchonlyChanged.connect(boost::bind(NotifyWatchonlyChanged, this, boost::placeholders::_1));
}

void WalletModel::unsubscribeFromCoreSignals()
{
// Disconnect signals from wallet
wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
wallet->NotifyWatchonlyChanged.disconnect(boost::bind(NotifyWatchonlyChanged, this, _1));
wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, boost::placeholders::_1));
wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3, boost::placeholders::_4, boost::placeholders::_5, boost::placeholders::_6));
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3));
wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2));
wallet->NotifyWatchonlyChanged.disconnect(boost::bind(NotifyWatchonlyChanged, this, boost::placeholders::_1));
}

// WalletModel::UnlockContext implementation
Expand Down
Loading

0 comments on commit 874832a

Please sign in to comment.