Skip to content

Commit

Permalink
rewind tracked height on chaintip update and cache ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
sdmg15 committed May 17, 2024
1 parent 2bb3b3b commit 8d7dda8
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 21 deletions.
26 changes: 14 additions & 12 deletions src/coldreward/coldrewardtracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ void ColdRewardTracker::endPersistedTransaction()
}

const std::vector<std::pair<ColdRewardTracker::AddressType, CAmount>> ColdRewardTracker::getBalances() {
const std::map<AddressType, std::vector<BlockHeightRange>> ranges = allRangesGetter();
const std::map<AddressType, std::vector<BlockHeightRange>> ranges = getAllRanges();
std::vector<std::pair<AddressType, CAmount>> result;

for(const auto& r: ranges) {
CAmount balance = balanceGetter(r.first);
CAmount balance = getBalance(r.first);
auto add = std::string(r.first.begin(), r.first.end());
LogPrintf("%s Tracking addr %s with balance %i \n", __func__, add, balance);
result.push_back(std::make_pair(r.first, balance));
Expand Down Expand Up @@ -142,22 +142,19 @@ boost::optional<int> ColdRewardTracker::GetLastCheckpoint(const std::map<int, ui
}
}

unsigned ColdRewardTracker::ExtractRewardMultiplierFromRanges(int currentBlockHeight, const std::vector<BlockHeightRange>& addressRanges)
unsigned ColdRewardTracker::ExtractRewardMultiplierFromRanges(int currentBlockHeight, const std::vector<BlockHeightRange>& ar)
{

std::vector<unsigned> rewardMultipliers;

const auto& ar = addressRanges;

for(unsigned i = 0; i < ar.size(); i++) {
const unsigned idx = ar.size() - i - 1;
// Now we're getting the elig addr every block
// AssertTrue(currentBlockHeight > ar[idx].getStart(), std::string(__func__), "You can't get the reward for the past");
// AssertTrue(currentBlockHeight > ar[idx].getEnd(), std::string(__func__), "You can't get the reward for the past");
// AssertTrue(currentBlockHeight >= ar[idx].getStart(), std::string(__func__), "You can't get the reward for the past");
// AssertTrue(currentBlockHeight >= ar[idx].getEnd(), std::string(__func__), "You can't get the reward for the past");

// collect all reward multipliers that are > 0 over the last periods, to figure out the final reward
const int startDistance = currentBlockHeight - ar[idx].getStart();
const int endDistance = currentBlockHeight - ar[idx].getEnd();
const int endDistance = currentBlockHeight - ar[idx].getEnd();

if(ar[idx].getRewardMultiplier() > 0) {
// collect all changes in balance
Expand Down Expand Up @@ -196,7 +193,7 @@ unsigned ColdRewardTracker::ExtractRewardMultiplierFromRanges(int currentBlockHe

std::vector<std::pair<ColdRewardTracker::AddressType, unsigned>> ColdRewardTracker::getEligibleAddresses(int currentBlockHeight)
{
const std::map<AddressType, std::vector<BlockHeightRange>> ranges = allRangesGetter();
const std::map<AddressType, std::vector<BlockHeightRange>> ranges = getAllRanges();
std::vector<std::pair<AddressType, unsigned>> result;

for(const auto& r: ranges) {
Expand Down Expand Up @@ -255,7 +252,7 @@ void ColdRewardTracker::addAddressTransaction(int blockHeight, const AddressType
// we add a [blockHeight, blockHeight] range as a marker that the balance has crossed a threshold multiple
ranges.push_back(BlockHeightRange(blockHeight, blockHeight, currentMultiplier, ranges.back().getRewardMultiplier()));
} else {
LogPrintf("%s Previous range value [%d, %d]\n", __func__, ranges.back().getStart(), ranges.back().getEnd());
LogPrintf("%s Previous range value for [%s] is [%d, %d]\n", __func__, std::string(address.begin(), address.end()), ranges.back().getStart(), ranges.back().getEnd());
ranges.back().newEnd(blockHeight);
}
}
Expand Down Expand Up @@ -356,7 +353,12 @@ void ColdRewardTracker::setAllRangesGetter(const std::function<std::map<AddressT
allRangesGetter = func;
}

const std::map<ColdRewardTracker::AddressType, std::vector<BlockHeightRange>>& ColdRewardTracker::getAllRanges() const
const std::map<ColdRewardTracker::AddressType, std::vector<BlockHeightRange>>& ColdRewardTracker::getAllRanges()
{
if (!addressesRanges.empty()) {
return addressesRanges;
}

addressesRanges = allRangesGetter();
return addressesRanges;
}
2 changes: 1 addition & 1 deletion src/coldreward/coldrewardtracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class ColdRewardTracker

void setAllRangesGetter(const std::function<std::map<AddressType, std::vector<BlockHeightRange>>()>& func);

const std::map<AddressType, std::vector<BlockHeightRange>>& getAllRanges() const;
const std::map<AddressType, std::vector<BlockHeightRange>>& getAllRanges();
const std::vector<std::pair<AddressType, CAmount>> getBalances();

void setGvrThreshold(const CAmount& amount) {
Expand Down
2 changes: 1 addition & 1 deletion src/txdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ bool CBlockTreeDB::WriteRewardTrackerUndo(const ColdRewardUndo& rewardUndo)

bool CBlockTreeDB::WriteLastTrackedHeight(std::int64_t lastHeight) {
CDBBatch batch(*this);
LogPrintf("%s Writting last tracked height %d\n", __func__, lastHeight);
LogPrintf("%s Writing last tracked height %d\n", __func__, lastHeight);

batch.Write(std::make_pair(DB_LAST_TRACKED_HEIGHT, 0), lastHeight);
return WriteBatch(batch);
Expand Down
68 changes: 62 additions & 6 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2386,7 +2386,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
!pblocktree->WriteLastTrackedHeight(pindex->pprev->nHeight)) {
return DISCONNECT_FAILED;
} else {
LogPrintf("%s Writting last tracked height %d\n", __func__, pindex->pprev->nHeight);
LogPrintf("%s Writing last tracked height %d\n", __func__, pindex->pprev->nHeight);
}

}
Expand Down Expand Up @@ -3338,6 +3338,16 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
} else {
// The staker was not eligible so the carried forward has to be set
// The carried forward is set since there were no gvr output
LogPrintf("THE STAKER OF THE BLOCK IS %s\n", EncodeDestination(stakerAddrDest));
LogPrintf("THE SIZE OF THE ELIG MAP IS %d\n", eligibleAddresses.size());

for (auto& elig: eligibleAddresses) {
LogPrintf("ELIGIBLE ADRR WERE (ADDR=%s, MUL=%d)\n", std::string(elig.first.begin(), elig.first.end()), elig.second);
}

eligibleAddresses = rewardTracker.getEligibleAddresses(pindex->nHeight);
LogPrintf("THE SIZE OF THE ELIG MAP AFTER RETRY IS %d\n", eligibleAddresses.size());

if (!txCoinstake->GetGvrFundCfwd(ngvrCfwdCheck)) {
LogPrintf("ERROR: %s: Coinstake gvr cfwd must be set.\n", __func__);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cs-cfwd");
Expand Down Expand Up @@ -3390,20 +3400,24 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,

std::int64_t readHeight;

if (pindex->nHeight >= 1 && pindex->nHeight >= consensus.automatedGvrActivationHeight && !pblocktree->ReadLastTrackedHeight(readHeight)) {
if (pindex->nHeight == 1 || pindex->nHeight == consensus.automatedGvrActivationHeight) {
readHeight = 0;
} else {
if (pindex->nHeight >= 1 && pindex->nHeight >= consensus.automatedGvrActivationHeight) {

if (!pblocktree->ReadLastTrackedHeight(readHeight)) {
LogPrintf("%s Impossible to read last tracked height attempted height %s\n", __func__, pindex->nHeight);
return false;
}
if (pindex->nHeight == 1 || pindex->nHeight == consensus.automatedGvrActivationHeight) {
readHeight = 0;
}
}


// Track the inputs/outputs for any balance changes
// Track out/in only after verifydb is done

if (!fVerifyingDB) {
if (readHeight < pindex->nHeight && pindex->nHeight >= consensus.automatedGvrActivationHeight) {
LogPrintf("TRACKING CURRENT HEIGHT %d AND READ HEIGHT = %d\n", pindex->nHeight, readHeight);
if (pindex->nHeight >= consensus.automatedGvrActivationHeight) {

LogPrintf("%s Last tracked Height %d, Current connecting height %d\n", __func__, readHeight, pindex->nHeight);

Expand Down Expand Up @@ -3788,6 +3802,7 @@ std::map<AddressType, std::vector<BlockHeightRange>> allRangesGetter() {

while (pcursor->Valid()) {
if (ShutdownRequested()) {
LogPrintf("SHUTDOWN REQUESTED RETURNING EMPTY BLOCK RANGES");
return std::map<AddressType, std::vector<BlockHeightRange>>();
}
std::pair<char, AddressType> key;
Expand All @@ -3801,6 +3816,10 @@ std::map<AddressType, std::vector<BlockHeightRange>> allRangesGetter() {
break;
}
}

if (ranges.empty()) {
LogPrintf("RETRIEVED FOR SOME REASONS EMPTY RANGES FROM DB");
}
return ranges;
}

Expand Down Expand Up @@ -6459,6 +6478,43 @@ bool CChainState::LoadChainTip(const CChainParams& chainparams)
m_chain.SetTip(pindex);
PruneBlockIndexCandidates();

std::int64_t readHeight;
int currentHeight = m_chain.Height();
ColdRewardUndo undoData;
ColdRewardTracker& tracker = initColdReward();

LogPrintf("REMOVING COLD REWARD DURING STARTUP %d\n", currentHeight);
if (!pblocktree->ReadLastTrackedHeight(readHeight)) {
LogPrintf("Can't read last tracked height from disk");
}

LogPrintf("READ HEIGHT AFTER STARTUP IS %d\n", readHeight);

if (currentHeight >= 1 && currentHeight >= chainparams.GetConsensus().automatedGvrActivationHeight) {
if (currentHeight == 1 || currentHeight == chainparams.GetConsensus().automatedGvrActivationHeight) {
readHeight = 0;
}

pblocktree->ReadRewardTrackerUndo(undoData, 1);

while (readHeight > currentHeight) {
for(const auto& output: undoData.outputs.at(readHeight)) {
const auto addr = std::string(output.first.begin(), output.first.end());
LogPrintf("%s Remove tracked output %d of addr %s \n", __func__, output.second, addr);
rewardTracker.removeAddressTransaction(readHeight, output.first, output.second);
}

for(const auto& input: undoData.inputs.at(readHeight)) {
const auto addr = std::string(input.first.begin(), input.first.end());
LogPrintf("%s Remove tracked input %d of addr %s \n", __func__, input.second, addr);
rewardTracker.removeAddressTransaction(readHeight, input.first, - input.second);
}
readHeight--;
}

pblocktree->WriteLastTrackedHeight(readHeight);
}

tip = m_chain.Tip();
LogPrintf("Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
tip->GetBlockHash().ToString(),
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/rpchdwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6726,7 +6726,7 @@ static UniValue debugwallet(const JSONRPCRequest &request)
bool clear_stakes_seen = false;
bool downgrade_wallets = false;
bool exit_ibd = false;
CAmount max_frozen_output_spendable = pwallet->GetLastBlockHeight() >= Params().GetConsensus().nBlockRewardCorrectionHeight ?
CAmount max_frozen_output_spendable = ::ChainActive().Height() >= Params().GetConsensus().nBlockRewardCorrectionHeight ?
Params().GetConsensus().m_max_tainted_value_out_increased : Params().GetConsensus().m_max_tainted_value_out;
int64_t time_now = GetAdjustedTime();

Expand Down

0 comments on commit 8d7dda8

Please sign in to comment.