Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix stake modifier persistance #157

Merged
merged 1 commit into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/blsct/pos/pos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion src/blsct/pos/proof_logic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
4 changes: 3 additions & 1 deletion src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down
27 changes: 27 additions & 0 deletions src/navio-staker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ static void SetupCliArgs(ArgsManager& argsman)
argsman.AddArg("-conf=<file>", 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=<dir>", "Specify data directory", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
SetupChainParamsBaseOptions(argsman);
argsman.AddArg("-debug=<category>", "Output debugging information (default: 0).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-debuglogfile=<file|false>", strprintf("Specify log file. Set to false to disable logging to file (default: %s)", DEFAULT_LOGFILE), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-color=<when>", 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);
Expand Down Expand Up @@ -435,11 +436,37 @@ static std::string coinbase_dest;
static bool mustUnlockWallet = false;
static arith_uint256 currentDifficulty;

util::Result<void> SetLoggingCategories(const ArgsManager& args)
{
if (args.IsArgSet("-debug")) {
// Special-case: if -debug=0/-nodebug is set, turn off debugging messages
const std::vector<std::string> 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();
Expand Down
121 changes: 61 additions & 60 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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 <hash>.\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 <hash>.\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);
},
};
}

Expand Down
17 changes: 11 additions & 6 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::pair<int64_t, uint256>> vSortedByTimestamp;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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_;
Expand Down
Loading