Skip to content

Commit 9d38d10

Browse files
laanwjsidhujag
authored and
sidhujag
committed
Merge bitcoin#16688: log: Add validation interface logging
f9abf4a Add logging for CValidationInterface events (Jeffrey Czyz) 6edebac Refactor FormatStateMessage for clarity (Jeffrey Czyz) 72f3227 Format CValidationState properly in all cases (Jeffrey Czyz) 428ac70 Add VALIDATION to BCLog::LogFlags (Jeffrey Czyz) Pull request description: Add logging of `CValidationInterface` callbacks using a new `VALIDATIONINTERFACE` log flag (see bitcoin#12994). A separate flag is desirable as the logging can be noisy and thus may need to be disabled without affecting other logging. This could help debug issues where there may be race conditions at play, such as bitcoin#12978. ACKs for top commit: jnewbery: ACK f9abf4a hebasto: ACK f9abf4a ariard: ACK f9abf4a, only changes since 0cadb12 are replacing log indication `VALIDATIONINTERFACE` by `VALIDATION` and avoiding a forward declaration with a new include ryanofsky: Code review ACK f9abf4a. Just suggested changes since last review (thanks!) Tree-SHA512: 3e0f6e2c8951cf46fbad3ff440971d95d526df2a52a2e4d6452a82785c63d53accfdabae66b0b30e2fe0b00737f8d5cb717edbad1460b63acb11a72c8f5d4236
1 parent fb566d4 commit 9d38d10

File tree

5 files changed

+67
-16
lines changed

5 files changed

+67
-16
lines changed

src/logging.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ const CLogCategoryDesc LogCategories[] =
162162
{BCLog::COINDB, "coindb"},
163163
{BCLog::QT, "qt"},
164164
{BCLog::LEVELDB, "leveldb"},
165+
{BCLog::VALIDATION, "validation"},
165166
// SYSCOIN
166167
{BCLog::MN, "masternode"},
167168
{BCLog::GOBJECT, "gobject"},

src/logging.h

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ namespace BCLog {
5454
COINDB = (1 << 18),
5555
QT = (1 << 19),
5656
LEVELDB = (1 << 20),
57+
VALIDATION = (1 << 21),
5758
// SYSCOIN
5859
MN = (1 << 22),
5960
GOBJECT = (1 << 23),

src/util/validation.cpp

+10-4
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@
88
#include <consensus/validation.h>
99
#include <tinyformat.h>
1010

11-
/** Convert ValidationState to a human-readable message for logging */
1211
std::string FormatStateMessage(const ValidationState &state)
1312
{
14-
return strprintf("%s%s",
15-
state.GetRejectReason(),
16-
state.GetDebugMessage().empty() ? "" : ", "+state.GetDebugMessage());
13+
if (state.IsValid()) {
14+
return "Valid";
15+
}
16+
17+
const std::string debug_message = state.GetDebugMessage();
18+
if (!debug_message.empty()) {
19+
return strprintf("%s, %s", state.GetRejectReason(), debug_message);
20+
}
21+
22+
return state.GetRejectReason();
1723
}
1824

1925
const std::string strMessageMagic = "Bitcoin Signed Message:\n";

src/validationinterface.cpp

+54-12
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@
55

66
#include <validationinterface.h>
77

8+
#include <chain.h>
9+
#include <consensus/validation.h>
10+
#include <logging.h>
811
#include <primitives/block.h>
12+
#include <primitives/transaction.h>
913
#include <scheduler.h>
14+
#include <util/validation.h>
1015

1116
#include <future>
1217
#include <unordered_map>
@@ -121,53 +126,90 @@ void SyncWithValidationInterfaceQueue() {
121126
promise.get_future().wait();
122127
}
123128

129+
// Use a macro instead of a function for conditional logging to prevent
130+
// evaluating arguments when logging is not enabled.
131+
//
132+
// NOTE: The lambda captures all local variables by value.
133+
#define ENQUEUE_AND_LOG_EVENT(event, fmt, name, ...) \
134+
do { \
135+
auto local_name = (name); \
136+
LOG_EVENT("Enqueuing " fmt, local_name, __VA_ARGS__); \
137+
m_internals->m_schedulerClient.AddToProcessQueue([=] { \
138+
LOG_EVENT(fmt, local_name, __VA_ARGS__); \
139+
event(); \
140+
}); \
141+
} while (0)
142+
143+
#define LOG_EVENT(fmt, ...) \
144+
LogPrint(BCLog::VALIDATION, fmt "\n", __VA_ARGS__)
124145

125146
void CMainSignals::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {
126147
// Dependencies exist that require UpdatedBlockTip events to be delivered in the order in which
127148
// the chain actually updates. One way to ensure this is for the caller to invoke this signal
128149
// in the same critical section where the chain is updated
129150

130-
m_internals->m_schedulerClient.AddToProcessQueue([pindexNew, pindexFork, fInitialDownload, this] {
151+
auto event = [pindexNew, pindexFork, fInitialDownload, this] {
131152
m_internals->UpdatedBlockTip(pindexNew, pindexFork, fInitialDownload);
132-
});
153+
};
154+
ENQUEUE_AND_LOG_EVENT(event, "%s: new block hash=%s fork block hash=%s (in IBD=%s)", __func__,
155+
pindexNew->GetBlockHash().ToString(),
156+
pindexFork ? pindexFork->GetBlockHash().ToString() : "null",
157+
fInitialDownload);
133158
}
134159

135160
void CMainSignals::TransactionAddedToMempool(const CTransactionRef &ptx) {
136-
m_internals->m_schedulerClient.AddToProcessQueue([ptx, this] {
161+
auto event = [ptx, this] {
137162
m_internals->TransactionAddedToMempool(ptx);
138-
});
163+
};
164+
ENQUEUE_AND_LOG_EVENT(event, "%s: txid=%s wtxid=%s", __func__,
165+
ptx->GetHash().ToString(),
166+
ptx->GetWitnessHash().ToString());
139167
}
140168

141169
void CMainSignals::TransactionRemovedFromMempool(const CTransactionRef &ptx) {
142-
m_internals->m_schedulerClient.AddToProcessQueue([ptx, this] {
170+
auto event = [ptx, this] {
143171
m_internals->TransactionRemovedFromMempool(ptx);
144-
});
172+
};
173+
ENQUEUE_AND_LOG_EVENT(event, "%s: txid=%s wtxid=%s", __func__,
174+
ptx->GetHash().ToString(),
175+
ptx->GetWitnessHash().ToString());
145176
}
146177

147178
void CMainSignals::BlockConnected(const std::shared_ptr<const CBlock> &pblock, const CBlockIndex *pindex, const std::shared_ptr<const std::vector<CTransactionRef>>& pvtxConflicted) {
148-
m_internals->m_schedulerClient.AddToProcessQueue([pblock, pindex, pvtxConflicted, this] {
179+
auto event = [pblock, pindex, pvtxConflicted, this] {
149180
m_internals->BlockConnected(pblock, pindex, *pvtxConflicted);
150-
});
181+
};
182+
ENQUEUE_AND_LOG_EVENT(event, "%s: block hash=%s block height=%d", __func__,
183+
pblock->GetHash().ToString(),
184+
pindex->nHeight);
151185
}
152186

153187
void CMainSignals::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex)
154188
{
155-
m_internals->m_schedulerClient.AddToProcessQueue([pblock, pindex, this] {
189+
auto event = [pblock, pindex, this] {
156190
m_internals->BlockDisconnected(pblock, pindex);
157-
});
191+
};
192+
ENQUEUE_AND_LOG_EVENT(event, "%s: block hash=%s block height=%d", __func__,
193+
pblock->GetHash().ToString(),
194+
pindex->nHeight);
158195
}
159196

160197
void CMainSignals::ChainStateFlushed(const CBlockLocator &locator) {
161-
m_internals->m_schedulerClient.AddToProcessQueue([locator, this] {
198+
auto event = [locator, this] {
162199
m_internals->ChainStateFlushed(locator);
163-
});
200+
};
201+
ENQUEUE_AND_LOG_EVENT(event, "%s: block hash=%s", __func__,
202+
locator.IsNull() ? "null" : locator.vHave.front().ToString());
164203
}
165204

166205
void CMainSignals::BlockChecked(const CBlock& block, const BlockValidationState& state) {
206+
LOG_EVENT("%s: block hash=%s state=%s", __func__,
207+
block.GetHash().ToString(), FormatStateMessage(state));
167208
m_internals->BlockChecked(block, state);
168209
}
169210

170211
void CMainSignals::NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock> &block) {
212+
LOG_EVENT("%s: block hash=%s", __func__, block->GetHash().ToString());
171213
m_internals->NewPoWValidBlock(pindex, block);
172214
}
173215
// SYSCOIN

test/lint/lint-format-strings.py

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
("src/index/base.cpp", "FatalError(const char* fmt, const Args&... args)"),
1818
("src/netbase.cpp", "LogConnectFailure(bool manual_connection, const char* fmt, const Args&... args)"),
1919
("src/util/system.cpp", "strprintf(_(COPYRIGHT_HOLDERS).translated, COPYRIGHT_HOLDERS_SUBSTITUTION)"),
20+
("src/validationinterface.cpp", "LogPrint(BCLog::VALIDATION, fmt \"\\n\", __VA_ARGS__)"),
2021
("src/wallet/wallet.h", "WalletLogPrintf(std::string fmt, Params... parameters)"),
2122
("src/wallet/wallet.h", "LogPrintf((\"%s \" + fmt).c_str(), GetDisplayName(), parameters...)"),
2223
("src/logging.h", "LogPrintf(const char* fmt, const Args&... args)"),

0 commit comments

Comments
 (0)