Skip to content

Commit

Permalink
Merge pull request #157 from nav-io/fix-stake-modifier
Browse files Browse the repository at this point in the history
Fix stake modifier persistance
  • Loading branch information
aguycalled authored Jul 17, 2024
2 parents 01d7465 + 0c6bcee commit 1d8c9b8
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 71 deletions.
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
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

0 comments on commit 1d8c9b8

Please sign in to comment.