Merge #19809: log: Prefix log messages with function name and source code location if -logsourcelocations is set

b4511e2e2ed1a6077ae6826a9ee6b7a311293d08 log: Prefix log messages with function name if -logsourcelocations is set (practicalswift)

Pull request description:

  Prefix log messages with function name if `-logfunctionnames` is set.

  Yes, exactly like `-logthreadnames` but for function names instead of thread names :)

  This is a small developer ergonomics improvement: I've found this to be a cheap/simple way to correlate log output and originating function.

  For me it beats the ordinary cycle of 1.) try to figure out a regexp matching the static part of the dynamic log message, 2.) `git grep -E 'Using .* MiB out of .* requested for signature cache'`, 3.) `mcedit filename.cpp` (`openemacs filename.cpp` works too!) and 4.) search for log message and scroll up to find the function name :)

  Without any logging parameters:

  ```
  $ src/bitcoind -regtest
  2020-08-25T03:29:04Z Using RdRand as an additional entropy source
  2020-08-25T03:29:04Z Using 16 MiB out of 32/2 requested for signature cache, able to store 524288 elements
  2020-08-25T03:29:04Z Using 16 MiB out of 32/2 requested for script execution cache, able to store 524288 elements
  2020-08-25T03:29:04Z Loaded best chain: hashBestChain=0fff88f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e22ff height=0 date=2011-02-02T23:16:42Z progress=1.000000
  2020-08-25T03:29:04Z block tree size = 1
  2020-08-25T03:29:04Z nBestHeight = 0
  2020-08-25T03:29:04Z Imported mempool transactions from disk: 0 succeeded, 0 failed, 0 expired, 0 already there, 0 waiting for initial broadcast
  2020-08-25T03:29:04Z 0 addresses found from DNS seeds
  ```

  With `-logthreadnames` and `-logfunctionnames`:

  ```
  $ src/bitcoind -regtest -logthreadnames -logfunctionnames
  2020-08-25T03:29:04Z [init] [ReportHardwareRand] Using RdRand as an additional entropy source
  2020-08-25T03:29:04Z [init] [InitSignatureCache] Using 16 MiB out of 32/2 requested for signature cache, able to store 524288 elements
  2020-08-25T03:29:04Z [init] [InitScriptExecutionCache] Using 16 MiB out of 32/2 requested for script execution cache, able to store 524288 elements
  2020-08-25T03:29:04Z [init] [LoadChainTip] Loaded best chain: hashBestChain=0fff88f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e22ff height=0 date=2011-02-02T23:16:42Z progress=1.000000
  2020-08-25T03:29:04Z [init] [AppInitMain] block tree size = 1
  2020-08-25T03:29:04Z [init] [AppInitMain] nBestHeight = 0
  2020-08-25T03:29:04Z [loadblk] [LoadMempool] Imported mempool transactions from disk: 0 succeeded, 0 failed, 0 expired, 0 already there, 0 waiting for initial broadcast
  2020-08-25T03:29:04Z [dnsseed] [ThreadDNSAddressSeed] 0 addresses found from DNS seeds
  ```

ACKs for top commit:
  laanwj:
    Code review ACK b4511e2e2ed1a6077ae6826a9ee6b7a311293d08
  MarcoFalke:
    review ACK b4511e2e2ed1a6077ae6826a9ee6b7a311293d08 🌃

Tree-SHA512: d100f5364630c323f31d275259864c597f7725e462d5f4bdedcc7033ea616d7fc0d16ef1b2af557e692f4deea73c6773ccfc681589e7bf6ba970b9ec169040c7
This commit is contained in:
Wladimir J. van der Laan 2021-02-18 14:20:42 +01:00 committed by Konstantin Akimov
parent 43a94f0580
commit 4774e1e8f6
No known key found for this signature in database
GPG Key ID: 2176C4A5D01EA524
12 changed files with 104 additions and 69 deletions

View File

@ -4,8 +4,11 @@
#include <batchedlogger.h> #include <batchedlogger.h>
CBatchedLogger::CBatchedLogger(BCLog::LogFlags _category, const std::string& _header) : CBatchedLogger::CBatchedLogger(BCLog::LogFlags _category, const std::string& logging_function, const std::string& source_file, int source_line) :
accept(LogAcceptCategory(_category)), header(_header) accept(LogAcceptCategory(_category)),
m_logging_function(logging_function),
m_source_file(source_file),
m_source_line(source_line)
{ {
} }
@ -19,6 +22,6 @@ void CBatchedLogger::Flush()
if (!accept || msg.empty()) { if (!accept || msg.empty()) {
return; return;
} }
LogInstance().LogPrintStr(strprintf("%s:\n%s", header, msg)); LogInstance().LogPrintStr(msg, m_logging_function, m_source_file, m_source_line);
msg.clear(); msg.clear();
} }

View File

@ -11,10 +11,12 @@ class CBatchedLogger
{ {
private: private:
bool accept; bool accept;
std::string header; std::string m_logging_function;;
std::string m_source_file;
const int m_source_line;
std::string msg; std::string msg;
public: public:
CBatchedLogger(BCLog::LogFlags _category, const std::string& _header); CBatchedLogger(BCLog::LogFlags _category, const std::string& logging_function, const std::string& m_source_file, int m_source_line);
virtual ~CBatchedLogger(); virtual ~CBatchedLogger();
template<typename... Args> template<typename... Args>

View File

@ -719,6 +719,7 @@ void SetupServerArgs(NodeContext& node)
argsman.AddArg("-debugexclude=<category>", strprintf("Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except the specified category. This option can be specified multiple times to exclude multiple categories."), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-debugexclude=<category>", strprintf("Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except the specified category. This option can be specified multiple times to exclude multiple categories."), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-disablegovernance", strprintf("Disable governance validation (0-1, default: %u)", 0), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-disablegovernance", strprintf("Disable governance validation (0-1, default: %u)", 0), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-logips", strprintf("Include IP addresses in debug output (default: %u)", DEFAULT_LOGIPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logips", strprintf("Include IP addresses in debug output (default: %u)", DEFAULT_LOGIPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-logsourcelocations", strprintf("Prepend debug output with name of the originating source location (source file, line number and function name) (default: %u)", DEFAULT_LOGSOURCELOCATIONS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
#ifdef HAVE_THREAD_LOCAL #ifdef HAVE_THREAD_LOCAL
argsman.AddArg("-logtimestamps", strprintf("Prepend debug output with timestamp (default: %u)", DEFAULT_LOGTIMESTAMPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logtimestamps", strprintf("Prepend debug output with timestamp (default: %u)", DEFAULT_LOGTIMESTAMPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
@ -1084,6 +1085,8 @@ void InitLogging(const ArgsManager& args)
#ifdef HAVE_THREAD_LOCAL #ifdef HAVE_THREAD_LOCAL
LogInstance().m_log_threadnames = args.GetBoolArg("-logthreadnames", DEFAULT_LOGTHREADNAMES); LogInstance().m_log_threadnames = args.GetBoolArg("-logthreadnames", DEFAULT_LOGTHREADNAMES);
#endif #endif
LogInstance().m_log_sourcelocations = args.GetBoolArg("-logsourcelocations", DEFAULT_LOGSOURCELOCATIONS);
fLogIPs = args.GetBoolArg("-logips", DEFAULT_LOGIPS); fLogIPs = args.GetBoolArg("-logips", DEFAULT_LOGIPS);
std::string version_string = FormatFullVersion(); std::string version_string = FormatFullVersion();

View File

@ -27,18 +27,11 @@ CFinalCommitment::CFinalCommitment(const Consensus::LLMQParams& params, const ui
{ {
} }
template<typename... Types>
void LogPrintfFinalCommitment(Types... out) {
if (LogAcceptCategory(BCLog::LLMQ)) {
LogInstance().LogPrintStr(strprintf("CFinalCommitment::%s -- %s", __func__, tinyformat::format(out...)));
}
}
bool CFinalCommitment::Verify(CDeterministicMNManager& dmnman, gsl::not_null<const CBlockIndex*> pQuorumBaseBlockIndex, bool checkSigs) const bool CFinalCommitment::Verify(CDeterministicMNManager& dmnman, gsl::not_null<const CBlockIndex*> pQuorumBaseBlockIndex, bool checkSigs) const
{ {
const auto& llmq_params_opt = Params().GetLLMQ(llmqType); const auto& llmq_params_opt = Params().GetLLMQ(llmqType);
if (!llmq_params_opt.has_value()) { if (!llmq_params_opt.has_value()) {
LogPrintfFinalCommitment("q[%s] invalid llmqType=%d\n", quorumHash.ToString(), ToUnderlying(llmqType)); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid llmqType=%d\n", quorumHash.ToString(), ToUnderlying(llmqType));
return false; return false;
} }
const auto& llmq_params = llmq_params_opt.value(); const auto& llmq_params = llmq_params_opt.value();
@ -46,17 +39,17 @@ bool CFinalCommitment::Verify(CDeterministicMNManager& dmnman, gsl::not_null<con
const uint16_t expected_nversion{CFinalCommitment::GetVersion(IsQuorumRotationEnabled(llmq_params, pQuorumBaseBlockIndex), const uint16_t expected_nversion{CFinalCommitment::GetVersion(IsQuorumRotationEnabled(llmq_params, pQuorumBaseBlockIndex),
DeploymentActiveAfter(pQuorumBaseBlockIndex, Params().GetConsensus(), Consensus::DEPLOYMENT_V19))}; DeploymentActiveAfter(pQuorumBaseBlockIndex, Params().GetConsensus(), Consensus::DEPLOYMENT_V19))};
if (nVersion == 0 || nVersion != expected_nversion) { if (nVersion == 0 || nVersion != expected_nversion) {
LogPrintfFinalCommitment("q[%s] invalid nVersion=%d expectednVersion\n", quorumHash.ToString(), nVersion, expected_nversion); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid nVersion=%d expectednVersion\n", quorumHash.ToString(), nVersion, expected_nversion);
return false; return false;
} }
if (pQuorumBaseBlockIndex->GetBlockHash() != quorumHash) { if (pQuorumBaseBlockIndex->GetBlockHash() != quorumHash) {
LogPrintfFinalCommitment("q[%s] invalid quorumHash\n", quorumHash.ToString()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid quorumHash\n", quorumHash.ToString());
return false; return false;
} }
if ((pQuorumBaseBlockIndex->nHeight % llmq_params.dkgInterval) != quorumIndex) { if ((pQuorumBaseBlockIndex->nHeight % llmq_params.dkgInterval) != quorumIndex) {
LogPrintfFinalCommitment("q[%s] invalid quorumIndex=%d\n", quorumHash.ToString(), quorumIndex); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid quorumIndex=%d\n", quorumHash.ToString(), quorumIndex);
return false; return false;
} }
@ -65,27 +58,27 @@ bool CFinalCommitment::Verify(CDeterministicMNManager& dmnman, gsl::not_null<con
} }
if (CountValidMembers() < llmq_params.minSize) { if (CountValidMembers() < llmq_params.minSize) {
LogPrintfFinalCommitment("q[%s] invalid validMembers count. validMembersCount=%d\n", quorumHash.ToString(), CountValidMembers()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid validMembers count. validMembersCount=%d\n", quorumHash.ToString(), CountValidMembers());
return false; return false;
} }
if (CountSigners() < llmq_params.minSize) { if (CountSigners() < llmq_params.minSize) {
LogPrintfFinalCommitment("q[%s] invalid signers count. signersCount=%d\n", quorumHash.ToString(), CountSigners()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid signers count. signersCount=%d\n", quorumHash.ToString(), CountSigners());
return false; return false;
} }
if (!quorumPublicKey.IsValid()) { if (!quorumPublicKey.IsValid()) {
LogPrintfFinalCommitment("q[%s] invalid quorumPublicKey\n", quorumHash.ToString()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid quorumPublicKey\n", quorumHash.ToString());
return false; return false;
} }
if (quorumVvecHash.IsNull()) { if (quorumVvecHash.IsNull()) {
LogPrintfFinalCommitment("q[%s] invalid quorumVvecHash\n", quorumHash.ToString()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid quorumVvecHash\n", quorumHash.ToString());
return false; return false;
} }
if (!membersSig.IsValid()) { if (!membersSig.IsValid()) {
LogPrintfFinalCommitment("q[%s] invalid membersSig\n", quorumHash.ToString()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid membersSig\n", quorumHash.ToString());
return false; return false;
} }
if (!quorumSig.IsValid()) { if (!quorumSig.IsValid()) {
LogPrintfFinalCommitment("q[%s] invalid vvecSig\n"); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid vvecSig\n");
return false; return false;
} }
auto members = utils::GetAllQuorumMembers(llmqType, dmnman, pQuorumBaseBlockIndex); auto members = utils::GetAllQuorumMembers(llmqType, dmnman, pQuorumBaseBlockIndex);
@ -96,16 +89,16 @@ bool CFinalCommitment::Verify(CDeterministicMNManager& dmnman, gsl::not_null<con
ss << "v[" << i << "]=" << validMembers[i]; ss << "v[" << i << "]=" << validMembers[i];
ss2 << "s[" << i << "]=" << signers[i]; ss2 << "s[" << i << "]=" << signers[i];
} }
LogPrintfFinalCommitment("CFinalCommitment::%s mns[%d] validMembers[%s] signers[%s]\n", __func__, members.size(), ss.str(), ss2.str()); LogPrint(BCLog::LLMQ, "CFinalCommitment::%s mns[%d] validMembers[%s] signers[%s]\n", __func__, members.size(), ss.str(), ss2.str());
} }
for (const auto i : irange::range(members.size(), size_t(llmq_params.size))) { for (const auto i : irange::range(members.size(), size_t(llmq_params.size))) {
if (validMembers[i]) { if (validMembers[i]) {
LogPrintfFinalCommitment("q[%s] invalid validMembers bitset. bit %d should not be set\n", quorumHash.ToString(), i); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid validMembers bitset. bit %d should not be set\n", quorumHash.ToString(), i);
return false; return false;
} }
if (signers[i]) { if (signers[i]) {
LogPrintfFinalCommitment("q[%s] invalid signers bitset. bit %d should not be set\n", quorumHash.ToString(), i); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid signers bitset. bit %d should not be set\n", quorumHash.ToString(), i);
return false; return false;
} }
} }
@ -118,7 +111,7 @@ bool CFinalCommitment::Verify(CDeterministicMNManager& dmnman, gsl::not_null<con
for (const auto &mn: members) { for (const auto &mn: members) {
ss3 << mn->proTxHash.ToString().substr(0, 4) << " | "; ss3 << mn->proTxHash.ToString().substr(0, 4) << " | ";
} }
LogPrintfFinalCommitment("CFinalCommitment::%s members[%s] quorumPublicKey[%s] commitmentHash[%s]\n", LogPrint(BCLog::LLMQ, "CFinalCommitment::%s members[%s] quorumPublicKey[%s] commitmentHash[%s]\n",
__func__, ss3.str(), quorumPublicKey.ToString(), commitmentHash.ToString()); __func__, ss3.str(), quorumPublicKey.ToString(), commitmentHash.ToString());
} }
std::vector<CBLSPublicKey> memberPubKeys; std::vector<CBLSPublicKey> memberPubKeys;
@ -130,17 +123,17 @@ bool CFinalCommitment::Verify(CDeterministicMNManager& dmnman, gsl::not_null<con
} }
if (!membersSig.VerifySecureAggregated(memberPubKeys, commitmentHash)) { if (!membersSig.VerifySecureAggregated(memberPubKeys, commitmentHash)) {
LogPrintfFinalCommitment("q[%s] invalid aggregated members signature\n", quorumHash.ToString()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid aggregated members signature\n", quorumHash.ToString());
return false; return false;
} }
if (!quorumSig.VerifyInsecure(quorumPublicKey, commitmentHash)) { if (!quorumSig.VerifyInsecure(quorumPublicKey, commitmentHash)) {
LogPrintfFinalCommitment("q[%s] invalid quorum signature\n", quorumHash.ToString()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid quorum signature\n", quorumHash.ToString());
return false; return false;
} }
} }
LogPrintfFinalCommitment("q[%s] VALID\n", quorumHash.ToString()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] VALID QUORUM\n", quorumHash.ToString());
return true; return true;
} }
@ -149,7 +142,7 @@ bool CFinalCommitment::VerifyNull() const
{ {
const auto& llmq_params_opt = Params().GetLLMQ(llmqType); const auto& llmq_params_opt = Params().GetLLMQ(llmqType);
if (!llmq_params_opt.has_value()) { if (!llmq_params_opt.has_value()) {
LogPrintfFinalCommitment("q[%s]invalid llmqType=%d\n", quorumHash.ToString(), ToUnderlying(llmqType)); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s]invalid llmqType=%d\n", quorumHash.ToString(), ToUnderlying(llmqType));
return false; return false;
} }
@ -163,11 +156,11 @@ bool CFinalCommitment::VerifyNull() const
bool CFinalCommitment::VerifySizes(const Consensus::LLMQParams& params) const bool CFinalCommitment::VerifySizes(const Consensus::LLMQParams& params) const
{ {
if (signers.size() != size_t(params.size)) { if (signers.size() != size_t(params.size)) {
LogPrintfFinalCommitment("q[%s] invalid signers.size=%d\n", quorumHash.ToString(), signers.size()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid signers.size=%d\n", quorumHash.ToString(), signers.size());
return false; return false;
} }
if (validMembers.size() != size_t(params.size)) { if (validMembers.size() != size_t(params.size)) {
LogPrintfFinalCommitment("q[%s] invalid signers.size=%d\n", quorumHash.ToString(), signers.size()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- q[%s] invalid signers.size=%d\n", quorumHash.ToString(), signers.size());
return false; return false;
} }
return true; return true;
@ -177,14 +170,14 @@ bool CheckLLMQCommitment(CDeterministicMNManager& dmnman, const CTransaction& tx
{ {
const auto opt_qcTx = GetTxPayload<CFinalCommitmentTxPayload>(tx); const auto opt_qcTx = GetTxPayload<CFinalCommitmentTxPayload>(tx);
if (!opt_qcTx) { if (!opt_qcTx) {
LogPrintfFinalCommitment("h[%d] GetTxPayload failed\n", pindexPrev->nHeight); LogPrint(BCLog::LLMQ, "CFinalCommitment -- h[%d] GetTxPayload LLMQCommitment failed\n", pindexPrev->nHeight);
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-payload"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-payload");
} }
auto& qcTx = *opt_qcTx; auto& qcTx = *opt_qcTx;
const auto& llmq_params_opt = Params().GetLLMQ(qcTx.commitment.llmqType); const auto& llmq_params_opt = Params().GetLLMQ(qcTx.commitment.llmqType);
if (!llmq_params_opt.has_value()) { if (!llmq_params_opt.has_value()) {
LogPrintfFinalCommitment("h[%d] GetLLMQ failed for llmqType[%d]\n", pindexPrev->nHeight, ToUnderlying(qcTx.commitment.llmqType)); LogPrint(BCLog::LLMQ, "CFinalCommitment -- h[%d] GetLLMQ failed for llmqType[%d]\n", pindexPrev->nHeight, ToUnderlying(qcTx.commitment.llmqType));
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-commitment-type"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-commitment-type");
} }
@ -193,17 +186,17 @@ bool CheckLLMQCommitment(CDeterministicMNManager& dmnman, const CTransaction& tx
for (const auto i: irange::range(llmq_params_opt->size)) { for (const auto i: irange::range(llmq_params_opt->size)) {
ss << "v[" << i << "]=" << qcTx.commitment.validMembers[i]; ss << "v[" << i << "]=" << qcTx.commitment.validMembers[i];
} }
LogPrintfFinalCommitment("%s llmqType[%d] validMembers[%s] signers[]\n", __func__, LogPrint(BCLog::LLMQ, "CFinalCommitment -- %s llmqType[%d] validMembers[%s] signers[]\n", __func__,
int(qcTx.commitment.llmqType), ss.str()); int(qcTx.commitment.llmqType), ss.str());
} }
if (qcTx.nVersion == 0 || qcTx.nVersion > CFinalCommitmentTxPayload::CURRENT_VERSION) { if (qcTx.nVersion == 0 || qcTx.nVersion > CFinalCommitmentTxPayload::CURRENT_VERSION) {
LogPrintfFinalCommitment("h[%d] invalid qcTx.nVersion[%d]\n", pindexPrev->nHeight, qcTx.nVersion); LogPrint(BCLog::LLMQ, "CFinalCommitment -- h[%d] invalid qcTx.nVersion[%d]\n", pindexPrev->nHeight, qcTx.nVersion);
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-version"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-version");
} }
if (qcTx.nHeight != uint32_t(pindexPrev->nHeight + 1)) { if (qcTx.nHeight != uint32_t(pindexPrev->nHeight + 1)) {
LogPrintfFinalCommitment("h[%d] invalid qcTx.nHeight[%d]\n", pindexPrev->nHeight, qcTx.nHeight); LogPrint(BCLog::LLMQ, "CFinalCommitment -- h[%d] invalid qcTx.nHeight[%d]\n", pindexPrev->nHeight, qcTx.nHeight);
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-height"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-height");
} }
@ -220,18 +213,18 @@ bool CheckLLMQCommitment(CDeterministicMNManager& dmnman, const CTransaction& tx
if (qcTx.commitment.IsNull()) { if (qcTx.commitment.IsNull()) {
if (!qcTx.commitment.VerifyNull()) { if (!qcTx.commitment.VerifyNull()) {
LogPrintfFinalCommitment("h[%d] invalid qcTx.commitment[%s] VerifyNull failed\n", pindexPrev->nHeight, qcTx.commitment.quorumHash.ToString()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- h[%d] invalid qcTx.commitment[%s] VerifyNull failed\n", pindexPrev->nHeight, qcTx.commitment.quorumHash.ToString());
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-invalid-null"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-invalid-null");
} }
return true; return true;
} }
if (!qcTx.commitment.Verify(dmnman, pQuorumBaseBlockIndex, false)) { if (!qcTx.commitment.Verify(dmnman, pQuorumBaseBlockIndex, false)) {
LogPrintfFinalCommitment("h[%d] invalid qcTx.commitment[%s] Verify failed\n", pindexPrev->nHeight, qcTx.commitment.quorumHash.ToString()); LogPrint(BCLog::LLMQ, "CFinalCommitment -- h[%d] invalid qcTx.commitment[%s] Verify failed\n", pindexPrev->nHeight, qcTx.commitment.quorumHash.ToString());
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-invalid"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-invalid");
} }
LogPrintfFinalCommitment("h[%d] CheckLLMQCommitment VALID\n", pindexPrev->nHeight); LogPrint(BCLog::LLMQ, "CFinalCommitment -- h[%d] CheckLLMQCommitment VALID\n", pindexPrev->nHeight);
return true; return true;
} }

View File

@ -35,10 +35,10 @@ namespace llmq
class CDKGLogger : public CBatchedLogger class CDKGLogger : public CBatchedLogger
{ {
public: public:
CDKGLogger(const CDKGSession& _quorumDkg, std::string_view _func) : CDKGLogger(const CDKGSession& _quorumDkg, std::string_view _func, int source_line) :
CDKGLogger(_quorumDkg.params.name, _quorumDkg.quorumIndex, _quorumDkg.m_quorum_base_block_index->GetBlockHash(), _quorumDkg.m_quorum_base_block_index->nHeight, _quorumDkg.AreWeMember(), _func){}; CDKGLogger(_quorumDkg.params.name, _quorumDkg.quorumIndex, _quorumDkg.m_quorum_base_block_index->GetBlockHash(), _quorumDkg.m_quorum_base_block_index->nHeight, _quorumDkg.AreWeMember(), _func, source_line){};
CDKGLogger(std::string_view _llmqTypeName, int _quorumIndex, const uint256& _quorumHash, int _height, bool _areWeMember, std::string_view _func) : CDKGLogger(std::string_view _llmqTypeName, int _quorumIndex, const uint256& _quorumHash, int _height, bool _areWeMember, std::string_view _func, int source_line) :
CBatchedLogger(BCLog::LLMQ_DKG, strprintf("QuorumDKG(type=%s, quorumIndex=%d, height=%d, member=%d, func=%s)", _llmqTypeName, _quorumIndex, _height, _areWeMember, _func)){}; CBatchedLogger(BCLog::LLMQ_DKG, strprintf("QuorumDKG(type=%s, qIndex=%d, h=%d, member=%d)", _llmqTypeName, _quorumIndex, _height, _areWeMember), __FILE__, source_line){};
}; };
static std::array<std::atomic<double>, ToUnderlying(DKGError::type::_COUNT)> simDkgErrorMap{}; static std::array<std::atomic<double>, ToUnderlying(DKGError::type::_COUNT)> simDkgErrorMap{};
@ -100,7 +100,7 @@ bool CDKGSession::Init(gsl::not_null<const CBlockIndex*> _pQuorumBaseBlockIndex,
} }
} }
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
if (LogAcceptCategory(BCLog::LLMQ) && IsQuorumRotationEnabled(params, m_quorum_base_block_index)) { if (LogAcceptCategory(BCLog::LLMQ) && IsQuorumRotationEnabled(params, m_quorum_base_block_index)) {
int cycleQuorumBaseHeight = m_quorum_base_block_index->nHeight - quorumIndex; int cycleQuorumBaseHeight = m_quorum_base_block_index->nHeight - quorumIndex;
@ -140,7 +140,7 @@ bool CDKGSession::Init(gsl::not_null<const CBlockIndex*> _pQuorumBaseBlockIndex,
void CDKGSession::Contribute(CDKGPendingMessages& pendingMessages) void CDKGSession::Contribute(CDKGPendingMessages& pendingMessages)
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
if (!AreWeMember()) { if (!AreWeMember()) {
return; return;
@ -161,7 +161,7 @@ void CDKGSession::Contribute(CDKGPendingMessages& pendingMessages)
void CDKGSession::SendContributions(CDKGPendingMessages& pendingMessages) void CDKGSession::SendContributions(CDKGPendingMessages& pendingMessages)
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
assert(AreWeMember()); assert(AreWeMember());
@ -214,7 +214,7 @@ void CDKGSession::SendContributions(CDKGPendingMessages& pendingMessages)
// only performs cheap verifications, but not the signature of the message. this is checked with batched verification // only performs cheap verifications, but not the signature of the message. this is checked with batched verification
bool CDKGSession::PreVerifyMessage(const CDKGContribution& qc, bool& retBan) const bool CDKGSession::PreVerifyMessage(const CDKGContribution& qc, bool& retBan) const
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
retBan = false; retBan = false;
@ -262,7 +262,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan)
{ {
LOCK(cs_pending); LOCK(cs_pending);
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
retBan = false; retBan = false;
@ -357,7 +357,7 @@ void CDKGSession::VerifyPendingContributions()
{ {
AssertLockHeld(cs_pending); AssertLockHeld(cs_pending);
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
cxxtimer::Timer t1(true); cxxtimer::Timer t1(true);
@ -418,7 +418,7 @@ void CDKGSession::VerifyAndComplain(CDKGPendingMessages& pendingMessages)
VerifyPendingContributions(); VerifyPendingContributions();
} }
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
// we check all members if they sent us their contributions // we check all members if they sent us their contributions
// we consider members as bad if they missed to send anything or if they sent multiple // we consider members as bad if they missed to send anything or if they sent multiple
@ -454,7 +454,7 @@ void CDKGSession::VerifyConnectionAndMinProtoVersions() const
return; return;
} }
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
std::unordered_map<uint256, int, StaticSaltedHasher> protoMap; std::unordered_map<uint256, int, StaticSaltedHasher> protoMap;
connman.ForEachNode([&](const CNode* pnode) { connman.ForEachNode([&](const CNode* pnode) {
@ -489,7 +489,7 @@ void CDKGSession::VerifyConnectionAndMinProtoVersions() const
void CDKGSession::SendComplaint(CDKGPendingMessages& pendingMessages) void CDKGSession::SendComplaint(CDKGPendingMessages& pendingMessages)
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
assert(AreWeMember()); assert(AreWeMember());
@ -532,7 +532,7 @@ void CDKGSession::SendComplaint(CDKGPendingMessages& pendingMessages)
// only performs cheap verifications, but not the signature of the message. this is checked with batched verification // only performs cheap verifications, but not the signature of the message. this is checked with batched verification
bool CDKGSession::PreVerifyMessage(const CDKGComplaint& qc, bool& retBan) const bool CDKGSession::PreVerifyMessage(const CDKGComplaint& qc, bool& retBan) const
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
retBan = false; retBan = false;
@ -574,7 +574,7 @@ bool CDKGSession::PreVerifyMessage(const CDKGComplaint& qc, bool& retBan) const
void CDKGSession::ReceiveMessage(const CDKGComplaint& qc, bool& retBan) void CDKGSession::ReceiveMessage(const CDKGComplaint& qc, bool& retBan)
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
retBan = false; retBan = false;
@ -641,7 +641,7 @@ void CDKGSession::VerifyAndJustify(CDKGPendingMessages& pendingMessages)
return; return;
} }
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
std::set<uint256> justifyFor; std::set<uint256> justifyFor;
@ -678,7 +678,7 @@ void CDKGSession::VerifyAndJustify(CDKGPendingMessages& pendingMessages)
void CDKGSession::SendJustification(CDKGPendingMessages& pendingMessages, const std::set<uint256>& forMembers) void CDKGSession::SendJustification(CDKGPendingMessages& pendingMessages, const std::set<uint256>& forMembers)
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
assert(AreWeMember()); assert(AreWeMember());
@ -727,7 +727,7 @@ void CDKGSession::SendJustification(CDKGPendingMessages& pendingMessages, const
// only performs cheap verifications, but not the signature of the message. this is checked with batched verification // only performs cheap verifications, but not the signature of the message. this is checked with batched verification
bool CDKGSession::PreVerifyMessage(const CDKGJustification& qj, bool& retBan) const bool CDKGSession::PreVerifyMessage(const CDKGJustification& qj, bool& retBan) const
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
retBan = false; retBan = false;
@ -785,7 +785,7 @@ bool CDKGSession::PreVerifyMessage(const CDKGJustification& qj, bool& retBan) co
void CDKGSession::ReceiveMessage(const CDKGJustification& qj, bool& retBan) void CDKGSession::ReceiveMessage(const CDKGJustification& qj, bool& retBan)
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
retBan = false; retBan = false;
@ -883,7 +883,7 @@ void CDKGSession::VerifyAndCommit(CDKGPendingMessages& pendingMessages)
return; return;
} }
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
std::vector<size_t> badMembers; std::vector<size_t> badMembers;
badMembers.reserve(members.size()); badMembers.reserve(members.size());
@ -924,7 +924,7 @@ void CDKGSession::VerifyAndCommit(CDKGPendingMessages& pendingMessages)
void CDKGSession::SendCommitment(CDKGPendingMessages& pendingMessages) void CDKGSession::SendCommitment(CDKGPendingMessages& pendingMessages)
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
assert(AreWeMember()); assert(AreWeMember());
@ -1039,7 +1039,7 @@ void CDKGSession::SendCommitment(CDKGPendingMessages& pendingMessages)
// only performs cheap verifications, but not the signature of the message. this is checked with batched verification // only performs cheap verifications, but not the signature of the message. this is checked with batched verification
bool CDKGSession::PreVerifyMessage(const CDKGPrematureCommitment& qc, bool& retBan) const bool CDKGSession::PreVerifyMessage(const CDKGPrematureCommitment& qc, bool& retBan) const
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
retBan = false; retBan = false;
@ -1100,7 +1100,7 @@ bool CDKGSession::PreVerifyMessage(const CDKGPrematureCommitment& qc, bool& retB
void CDKGSession::ReceiveMessage(const CDKGPrematureCommitment& qc, bool& retBan) void CDKGSession::ReceiveMessage(const CDKGPrematureCommitment& qc, bool& retBan)
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
retBan = false; retBan = false;
@ -1183,7 +1183,7 @@ std::vector<CFinalCommitment> CDKGSession::FinalizeCommitments()
return {}; return {};
} }
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
using Key = std::vector<bool>; using Key = std::vector<bool>;
std::map<Key, std::vector<CDKGPrematureCommitment>> commitmentsMap; std::map<Key, std::vector<CDKGPrematureCommitment>> commitmentsMap;
@ -1309,7 +1309,7 @@ void CDKGSession::MarkBadMember(size_t idx)
void CDKGSession::RelayInvToParticipants(const CInv& inv) const void CDKGSession::RelayInvToParticipants(const CInv& inv) const
{ {
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__, __LINE__);
std::stringstream ss; std::stringstream ss;
for (const auto& r : relayMembers) { for (const auto& r : relayMembers) {
ss << r.ToString().substr(0, 4) << " | "; ss << r.ToString().substr(0, 4) << " | ";

View File

@ -6,6 +6,7 @@
#include <logging.h> #include <logging.h>
#include <util/system.h> #include <util/system.h>
#include <util/threadnames.h> #include <util/threadnames.h>
#include <util/string.h>
#include <util/time.h> #include <util/time.h>
#include <algorithm> #include <algorithm>
@ -269,11 +270,15 @@ namespace BCLog {
} }
} // namespace BCLog } // namespace BCLog
void BCLog::Logger::LogPrintStr(const std::string& str) void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, const int source_line)
{ {
StdLockGuard scoped_lock(m_cs); StdLockGuard scoped_lock(m_cs);
std::string str_prefixed = LogEscapeMessage(str); std::string str_prefixed = LogEscapeMessage(str);
if (m_log_sourcelocations && m_started_new_line) {
str_prefixed.insert(0, "[" + RemovePrefix(source_file, "./") + ":" + ToString(source_line) + "] [" + logging_function + "] ");
}
if (m_log_threadnames && m_started_new_line) { if (m_log_threadnames && m_started_new_line) {
// 16 chars total, "dash-" is 5 of them and another 1 is a NUL terminator // 16 chars total, "dash-" is 5 of them and another 1 is a NUL terminator
str_prefixed.insert(0, "[" + strprintf("%10s", util::ThreadGetInternalName()) + "] "); str_prefixed.insert(0, "[" + strprintf("%10s", util::ThreadGetInternalName()) + "] ");

View File

@ -22,6 +22,7 @@ static const bool DEFAULT_LOGTIMEMICROS = false;
static const bool DEFAULT_LOGIPS = false; static const bool DEFAULT_LOGIPS = false;
static const bool DEFAULT_LOGTIMESTAMPS = true; static const bool DEFAULT_LOGTIMESTAMPS = true;
static const bool DEFAULT_LOGTHREADNAMES = false; static const bool DEFAULT_LOGTHREADNAMES = false;
static const bool DEFAULT_LOGSOURCELOCATIONS = false;
extern const char * const DEFAULT_DEBUGLOGFILE; extern const char * const DEFAULT_DEBUGLOGFILE;
extern bool fLogThreadNames; extern bool fLogThreadNames;
@ -117,12 +118,13 @@ namespace BCLog {
bool m_log_timestamps = DEFAULT_LOGTIMESTAMPS; bool m_log_timestamps = DEFAULT_LOGTIMESTAMPS;
bool m_log_time_micros = DEFAULT_LOGTIMEMICROS; bool m_log_time_micros = DEFAULT_LOGTIMEMICROS;
bool m_log_threadnames = DEFAULT_LOGTHREADNAMES; bool m_log_threadnames = DEFAULT_LOGTHREADNAMES;
bool m_log_sourcelocations = DEFAULT_LOGSOURCELOCATIONS;
fs::path m_file_path; fs::path m_file_path;
std::atomic<bool> m_reopen_file{false}; std::atomic<bool> m_reopen_file{false};
/** Send a string to the log output */ /** Send a string to the log output */
void LogPrintStr(const std::string& str); void LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, const int source_line);
/** Returns whether logs will be written to any output */ /** Returns whether logs will be written to any output */
bool Enabled() const bool Enabled() const
@ -203,7 +205,7 @@ std::string SafeStringFormat(const std::string& fmt, const Args&... args)
// peer can fill up a user's disk with debug.log entries. // peer can fill up a user's disk with debug.log entries.
template <typename... Args> template <typename... Args>
static inline void LogPrintf(const char* fmt, const Args&... args) static inline void LogPrintf_(const std::string& logging_function, const std::string& source_file, const int source_line, const char* fmt, const Args&... args)
{ {
if (LogInstance().Enabled()) { if (LogInstance().Enabled()) {
std::string log_msg; std::string log_msg;
@ -213,10 +215,12 @@ static inline void LogPrintf(const char* fmt, const Args&... args)
/* Original format string will have newline so don't add one here */ /* Original format string will have newline so don't add one here */
log_msg = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + fmt; log_msg = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + fmt;
} }
LogInstance().LogPrintStr(log_msg); LogInstance().LogPrintStr(log_msg, logging_function, source_file, source_line);
} }
} }
#define LogPrintf(...) LogPrintf_(__func__, __FILE__, __LINE__, __VA_ARGS__)
// Use a macro instead of a function for conditional logging to prevent // Use a macro instead of a function for conditional logging to prevent
// evaluating arguments when logging for the category is not enabled. // evaluating arguments when logging for the category is not enabled.
#define LogPrint(category, ...) \ #define LogPrint(category, ...) \

View File

@ -161,6 +161,7 @@ FUZZ_TARGET(string)
(void)ParseNonRFCJSONValue(random_string_1); (void)ParseNonRFCJSONValue(random_string_1);
} catch (const std::runtime_error&) { } catch (const std::runtime_error&) {
} }
(void)RemovePrefix(random_string_1, random_string_2);
(void)ResolveErrMsg(random_string_1, random_string_2); (void)ResolveErrMsg(random_string_1, random_string_2);
try { try {
(void)RPCConvertNamedValues(random_string_1, random_string_vector); (void)RPCConvertNamedValues(random_string_1, random_string_vector);

View File

@ -142,6 +142,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
{ {
"dummy", "dummy",
"-printtoconsole=0", "-printtoconsole=0",
"-logsourcelocations",
"-logtimemicros", "-logtimemicros",
"-logthreadnames", "-logthreadnames",
"-debug", "-debug",

View File

@ -2635,4 +2635,17 @@ BOOST_AUTO_TEST_CASE(message_hash)
BOOST_CHECK_NE(message_hash1, signature_hash); BOOST_CHECK_NE(message_hash1, signature_hash);
} }
BOOST_AUTO_TEST_CASE(remove_prefix)
{
BOOST_CHECK_EQUAL(RemovePrefix("./util/system.h", "./"), "util/system.h");
BOOST_CHECK_EQUAL(RemovePrefix("foo", "foo"), "");
BOOST_CHECK_EQUAL(RemovePrefix("foo", "fo"), "o");
BOOST_CHECK_EQUAL(RemovePrefix("foo", "f"), "oo");
BOOST_CHECK_EQUAL(RemovePrefix("foo", ""), "foo");
BOOST_CHECK_EQUAL(RemovePrefix("fo", "foo"), "fo");
BOOST_CHECK_EQUAL(RemovePrefix("f", "foo"), "f");
BOOST_CHECK_EQUAL(RemovePrefix("", "foo"), "");
BOOST_CHECK_EQUAL(RemovePrefix("", ""), "");
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -39,6 +39,14 @@ void ReplaceAll(std::string& in_out, const std::string& search, const std::strin
return str.substr(front, end - front + 1); return str.substr(front, end - front + 1);
} }
[[nodiscard]] inline std::string RemovePrefix(const std::string& str, const std::string& prefix)
{
if (str.substr(0, prefix.size()) == prefix) {
return str.substr(prefix.size());
}
return str;
}
/** /**
* Join a list of items * Join a list of items
* *

View File

@ -118,6 +118,8 @@ class TestNode():
if self.version_is_at_least(120100): if self.version_is_at_least(120100):
self.args.append("-logthreadnames") self.args.append("-logthreadnames")
if self.version_is_at_least(21000000):
self.args.append("-logsourcelocations")
self.cli = TestNodeCLI(bitcoin_cli, self.datadir) self.cli = TestNodeCLI(bitcoin_cli, self.datadir)
self.use_cli = use_cli self.use_cli = use_cli