diff --git a/src/blsct/pos/pos.cpp b/src/blsct/pos/pos.cpp index 5b26e62753b54..e61ab76a6545c 100644 --- a/src/blsct/pos/pos.cpp +++ b/src/blsct/pos/pos.cpp @@ -83,10 +83,10 @@ bool GetLastStakeModifier(const CBlockIndex* pindex, uint64_t& nStakeModifier, i if (!pindex->GeneratedStakeModifier()) { nStakeModifier = 1; nModifierTime = pindex->GetBlockTime(); - return true; + } else { + nStakeModifier = pindex->nStakeModifier; + nModifierTime = pindex->GetBlockTime(); } - nStakeModifier = pindex->nStakeModifier; - nModifierTime = pindex->GetBlockTime(); return true; } diff --git a/src/blsct/pos/proof_logic.cpp b/src/blsct/pos/proof_logic.cpp index c4e108a528ae5..6bf41fe5116b9 100644 --- a/src/blsct/pos/proof_logic.cpp +++ b/src/blsct/pos/proof_logic.cpp @@ -42,7 +42,7 @@ bool ProofOfStakeLogic::Verify(const CCoinsViewCache& cache, const CBlockIndex* auto kernel_hash = blsct::CalculateKernelHash(pindexPrev, block); auto next_target = blsct::GetNextTargetRequired(pindexPrev, &block, params); - LogPrint(BCLog::POPS, "Verifying PoPS:\n Eta fiat shamir: %s\n Eta phi: %s\n Kernel Hash: %s\n Next Target: %d\n Staked Commitments:%s\n", HexStr(eta_fiat_shamir), HexStr(eta_phi), kernel_hash.ToString(), next_target, staked_commitments.GetString()); + LogPrint(BCLog::POPS, "Verifying PoPS:\n Prev block %s\n Eta fiat shamir: %s\n Eta phi: %s\n Kernel Hash: %s\n Next Target: %d\n Staked Commitments:%s\n", pindexPrev->GetBlockHash().ToString(), HexStr(eta_fiat_shamir), HexStr(eta_phi), kernel_hash.ToString(), next_target, staked_commitments.GetString()); auto res = block.posProof.Verify(staked_commitments, eta_fiat_shamir, eta_phi, kernel_hash, next_target); diff --git a/src/chain.h b/src/chain.h index 00fb4354c7d42..5f59d44def53a 100644 --- a/src/chain.h +++ b/src/chain.h @@ -137,6 +137,7 @@ enum BlockStatus : uint32_t { BLOCK_POS_ENTROPY = 512, BLOCK_STAKE_MODIFIER = 1024, BLOCK_KERNEL_HASH = 2048, + BLOCK_STAKE_MODIFIER_SET = 4096, }; /** The block chain is a tree shaped structure starting with the @@ -313,6 +314,7 @@ class CBlockIndex void SetStakeModifier(const uint64_t& nModifier, const bool& fGeneratedStakeModifier) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { AssertLockHeld(::cs_main); + nStatus |= BLOCK_STAKE_MODIFIER_SET; nStakeModifier = nModifier; if (fGeneratedStakeModifier) nStatus |= BLOCK_STAKE_MODIFIER; @@ -475,7 +477,7 @@ class CDiskBlockIndex : public CBlockIndex READWRITE(obj.posProof); else READWRITE(obj.nNonce); - if (obj.nStatus & BLOCK_STAKE_MODIFIER) READWRITE(obj.nStakeModifier); + if (obj.nStatus & BLOCK_STAKE_MODIFIER_SET) READWRITE(obj.nStakeModifier); if (obj.nStatus & BLOCK_KERNEL_HASH) READWRITE(obj.kernelHash); } diff --git a/src/navio-staker.cpp b/src/navio-staker.cpp index 307b94b5aec35..4e68dc399c59b 100644 --- a/src/navio-staker.cpp +++ b/src/navio-staker.cpp @@ -75,6 +75,7 @@ static void SetupCliArgs(ArgsManager& argsman) argsman.AddArg("-conf=", strprintf("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-datadir=", "Specify data directory", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); SetupChainParamsBaseOptions(argsman); + argsman.AddArg("-debug=", "Output debugging information (default: 0).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-debuglogfile=", strprintf("Specify log file. Set to false to disable logging to file (default: %s)", DEFAULT_LOGFILE), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-color=", strprintf("Color setting for CLI output (default: %s). Valid values: always, auto (add color codes when standard output is connected to a terminal and OS is not WIN32), never.", DEFAULT_COLOR_SETTING), ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS); argsman.AddArg("-printtoconsole", "Prints debug to stdout", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); @@ -435,11 +436,37 @@ static std::string coinbase_dest; static bool mustUnlockWallet = false; static arith_uint256 currentDifficulty; +util::Result SetLoggingCategories(const ArgsManager& args) +{ + if (args.IsArgSet("-debug")) { + // Special-case: if -debug=0/-nodebug is set, turn off debugging messages + const std::vector categories = args.GetArgs("-debug"); + + if (std::none_of(categories.begin(), categories.end(), + [](std::string cat) { return cat == "0" || cat == "none"; })) { + for (const auto& cat : categories) { + if (!LogInstance().EnableCategory(cat)) { + return util::Error{strprintf(_("Unsupported logging category %s=%s."), "-debug", cat)}; + } + } + } + } + + // Now remove the logging categories which were explicitly excluded + for (const std::string& cat : args.GetArgs("-debugexclude")) { + if (!LogInstance().DisableCategory(cat)) { + return util::Error{strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat)}; + } + } + return {}; +} + void Setup() { LogInstance().m_print_to_file = !gArgs.IsArgNegated("-debuglogfile"); LogInstance().m_file_path = AbsPathForConfigVal(gArgs, gArgs.GetPathArg("-debuglogfile", DEFAULT_LOGFILE)); LogInstance().m_print_to_console = gArgs.GetBoolArg("-printtoconsole", true); + SetLoggingCategories(gArgs); if (gArgs.GetBoolArg("-stdinrpcpass", false)) { NO_STDIN_ECHO(); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 10c877dbe29c9..ff3bf8a31f87c 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -167,6 +167,7 @@ UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex result.pushKV("nonce", blockindex.nNonce); result.pushKV("bits", strprintf("%08x", blockindex.nBits)); result.pushKV("difficulty", GetDifficulty(blockindex)); + result.pushKV("stakemodifier", blockindex.nStakeModifier); result.pushKV("chainwork", blockindex.nChainWork.GetHex()); result.pushKV("nTx", blockindex.nTx); @@ -523,71 +524,71 @@ static RPCHelpMan getblockhash() static RPCHelpMan getblockheader() { - return RPCHelpMan{"getblockheader", - "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" - "If verbose is true, returns an Object with information about blockheader .\n", - { - {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"}, - {"verbose", RPCArg::Type::BOOL, RPCArg::Default{true}, "true for a json object, false for the hex-encoded data"}, - }, - { - RPCResult{"for verbose = true", - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::STR_HEX, "hash", "the block hash (same as provided)"}, - {RPCResult::Type::NUM, "confirmations", "The number of confirmations, or -1 if the block is not on the main chain"}, - {RPCResult::Type::NUM, "height", "The block height or index"}, - {RPCResult::Type::NUM, "version", "The block version"}, - {RPCResult::Type::STR_HEX, "versionHex", "The block version formatted in hexadecimal"}, - {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"}, - {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME}, - {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME}, - {RPCResult::Type::NUM, "nonce", "The nonce"}, - {RPCResult::Type::STR_HEX, "bits", "The bits"}, - {RPCResult::Type::NUM, "difficulty", "The difficulty"}, - {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain"}, - {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"}, - {RPCResult::Type::STR_HEX, "previousblockhash", /*optional=*/true, "The hash of the previous block (if available)"}, - {RPCResult::Type::STR_HEX, "nextblockhash", /*optional=*/true, "The hash of the next block (if available)"}, - }}, - RPCResult{"for verbose=false", - RPCResult::Type::STR_HEX, "", "A string that is serialized, hex-encoded data for block 'hash'"}, - }, - RPCExamples{ - HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") - + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ - uint256 hash(ParseHashV(request.params[0], "hash")); + return RPCHelpMan{ + "getblockheader", + "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" + "If verbose is true, returns an Object with information about blockheader .\n", + { + {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"}, + {"verbose", RPCArg::Type::BOOL, RPCArg::Default{true}, "true for a json object, false for the hex-encoded data"}, + }, + { + RPCResult{"for verbose = true", + RPCResult::Type::OBJ, + "", + "", + { + {RPCResult::Type::STR_HEX, "hash", "the block hash (same as provided)"}, + {RPCResult::Type::NUM, "confirmations", "The number of confirmations, or -1 if the block is not on the main chain"}, + {RPCResult::Type::NUM, "height", "The block height or index"}, + {RPCResult::Type::NUM, "version", "The block version"}, + {RPCResult::Type::STR_HEX, "versionHex", "The block version formatted in hexadecimal"}, + {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"}, + {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME}, + {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME}, + {RPCResult::Type::NUM, "nonce", "The nonce"}, + {RPCResult::Type::STR_HEX, "bits", "The bits"}, + {RPCResult::Type::NUM, "difficulty", "The difficulty"}, + {RPCResult::Type::NUM, "stakemodifier", "The stake modifier"}, + {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain"}, + {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"}, + {RPCResult::Type::STR_HEX, "previousblockhash", /*optional=*/true, "The hash of the previous block (if available)"}, + {RPCResult::Type::STR_HEX, "nextblockhash", /*optional=*/true, "The hash of the next block (if available)"}, + }}, + RPCResult{"for verbose=false", + RPCResult::Type::STR_HEX, "", "A string that is serialized, hex-encoded data for block 'hash'"}, + }, + RPCExamples{ + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")}, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + uint256 hash(ParseHashV(request.params[0], "hash")); - bool fVerbose = true; - if (!request.params[1].isNull()) - fVerbose = request.params[1].get_bool(); + bool fVerbose = true; + if (!request.params[1].isNull()) + fVerbose = request.params[1].get_bool(); - const CBlockIndex* pblockindex; - const CBlockIndex* tip; - { - ChainstateManager& chainman = EnsureAnyChainman(request.context); - LOCK(cs_main); - pblockindex = chainman.m_blockman.LookupBlockIndex(hash); - tip = chainman.ActiveChain().Tip(); - } + const CBlockIndex* pblockindex; + const CBlockIndex* tip; + { + ChainstateManager& chainman = EnsureAnyChainman(request.context); + LOCK(cs_main); + pblockindex = chainman.m_blockman.LookupBlockIndex(hash); + tip = chainman.ActiveChain().Tip(); + } - if (!pblockindex) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); - } + if (!pblockindex) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + } - if (!fVerbose) - { - DataStream ssBlock{}; - ssBlock << pblockindex->GetBlockHeader(); - std::string strHex = HexStr(ssBlock); - return strHex; - } + if (!fVerbose) { + DataStream ssBlock{}; + ssBlock << pblockindex->GetBlockHeader(); + std::string strHex = HexStr(ssBlock); + return strHex; + } - return blockheaderToJSON(*tip, *pblockindex); -}, + return blockheaderToJSON(*tip, *pblockindex); + }, }; } diff --git a/src/validation.cpp b/src/validation.cpp index 7d94f77d5b3af..9d46fac1bcbb0 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2243,18 +2243,20 @@ static bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nS fGeneratedStakeModifier = false; if (!pindexPrev) { fGeneratedStakeModifier = true; - return false; // "ComputeNextStakeModifier(): Could not find pindexPrev"); // genesis block's modifier is 0 + return error("%s: did not find previous block\n", __func__); // genesis block's modifier is 0 } // First find current stake modifier and its generation block time // if it's not old enough, return the same stake modifier int64_t nModifierTime = 0; - if (!blsct::GetLastStakeModifier(pindexPrev, nStakeModifier, nModifierTime)) - return false; // "ComputeNextStakeModifier: unable to get last modifier"); + if (!blsct::GetLastStakeModifier(pindexPrev, nStakeModifier, nModifierTime)) { + return error("%s: did not find previous modifier\n", __func__); + } // LogPrint("stakemodifier", "ComputeNextStakeModifier: prev modifier=0x%016x time=%s\n", nStakeModifier, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nModifierTime)); - if (nModifierTime / params.nModifierInterval >= pindexPrev->GetBlockTime() / params.nModifierInterval) + if (nModifierTime / params.nModifierInterval >= pindexPrev->GetBlockTime() / params.nModifierInterval) { return true; + } // Sort candidate blocks by timestamp std::vector> vSortedByTimestamp; @@ -2285,7 +2287,8 @@ static bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nS nSelectionIntervalStop += blsct::GetStakeModifierSelectionIntervalSection(nRound, params); // select a block from the candidates of current round if (!SelectBlockFromCandidates(vSortedByTimestamp, mapSelectedBlocks, nSelectionIntervalStop, nStakeModifier, &pindex, params, m_blockman)) - return false; //"ComputeNextStakeModifier: unable to select block at round %d", nRound); + return error("%s: unable to select block at round %d", __func__, nRound); + // write the entropy bit of the selected block nStakeModifierNew |= (((uint64_t)pindex->GetStakeEntropyBit()) << nRound); // add the selected block from candidates to selected list @@ -2440,8 +2443,10 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state, pindex->SetStakeModifier(nStakeModifier, fGeneratedStakeModifier); - if (block.IsProofOfStake()) + if (block.IsProofOfStake()) { pindex->SetKernelHash(blsct::CalculateKernelHash(pindex->pprev, block)); + } + const auto time_2{SteadyClock::now()}; time_pos_calc += time_2 - time_2_;