Skip to content

Commit

Permalink
fix: Move CreditPoolDiff checks out of ProcessSpecialTxsInBlock to us…
Browse files Browse the repository at this point in the history
…e correct block reward
  • Loading branch information
UdjinM6 committed Sep 29, 2023
1 parent c034ff0 commit 2469443
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 34 deletions.
15 changes: 6 additions & 9 deletions src/evo/creditpool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ void CCreditPoolDiff::AddRewardRealloced(const CAmount reward) {
platformReward += reward;
}

bool CCreditPoolDiff::SetTarget(const CTransaction& tx, TxValidationState& state)
bool CCreditPoolDiff::SetTarget(const CTransaction& tx, const std::optional<CAmount> blockReward, TxValidationState& state)
{
CCbTx cbTx;
if (!GetTxPayload(tx, cbTx)) {
Expand All @@ -239,14 +239,11 @@ bool CCreditPoolDiff::SetTarget(const CTransaction& tx, TxValidationState& state

targetBalance = cbTx.creditPoolBalance;


if (!llmq::utils::IsMNRewardReallocationActive(pindex)) return true;

CAmount blockReward = 0;
for (const CTxOut& txout : tx.vout) {
blockReward += txout.nValue;
}
platformReward = MasternodePayments::PlatformShare(GetMasternodePayment(cbTx.nHeight, blockReward, params.BRRHeight));
assert(blockReward.has_value());

platformReward = MasternodePayments::PlatformShare(GetMasternodePayment(cbTx.nHeight, blockReward.value(), params.BRRHeight));
LogPrintf("CreditPool: set target to %lld with MN reward %lld\n", *targetBalance, platformReward);

return true;
Expand Down Expand Up @@ -292,10 +289,10 @@ bool CCreditPoolDiff::Unlock(const CTransaction& tx, TxValidationState& state)
return true;
}

bool CCreditPoolDiff::ProcessTransaction(const CTransaction& tx, TxValidationState& state)
bool CCreditPoolDiff::ProcessTransaction(const CTransaction& tx, const std::optional<CAmount> blockReward, TxValidationState& state)
{
if (tx.nVersion != 3) return true;
if (tx.nType == TRANSACTION_COINBASE) return SetTarget(tx, state);
if (tx.nType == TRANSACTION_COINBASE) return SetTarget(tx, blockReward, state);

if (tx.nType != TRANSACTION_ASSET_LOCK && tx.nType != TRANSACTION_ASSET_UNLOCK) return true;

Expand Down
4 changes: 2 additions & 2 deletions src/evo/creditpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class CCreditPoolDiff {
* to change amount of credit pool
* @return true if transaction can be included in this block
*/
bool ProcessTransaction(const CTransaction& tx, TxValidationState& state);
bool ProcessTransaction(const CTransaction& tx, std::optional<CAmount> blockReward, TxValidationState& state);

/**
* This function should be called by miner for initialization of MasterNode reward
Expand All @@ -102,7 +102,7 @@ class CCreditPoolDiff {
}

private:
bool SetTarget(const CTransaction& tx, TxValidationState& state);
bool SetTarget(const CTransaction& tx, const std::optional<CAmount> blockReward, TxValidationState& state);
bool Lock(const CTransaction& tx, TxValidationState& state);
bool Unlock(const CTransaction& tx, TxValidationState& state);
};
Expand Down
57 changes: 39 additions & 18 deletions src/evo/specialtxman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,8 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, ll
int64_t nTime1 = GetTimeMicros();

const CCreditPool creditPool = creditPoolManager->GetCreditPool(pindex->pprev, consensusParams);
std::optional<CCreditPoolDiff> creditPoolDiff;
if (bool fV20Active_context = llmq::utils::IsV20Active(pindex->pprev); fV20Active_context) {
if (llmq::utils::IsV20Active(pindex->pprev)) {
LogPrintf("%s: CCreditPool is %s\n", __func__, creditPool.ToString());
creditPoolDiff.emplace(creditPool, pindex->pprev, consensusParams);
}

for (const auto& ptr_tx : block.vtx) {
Expand All @@ -158,21 +156,6 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, ll
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(),
strprintf("Process Special Transaction failed (tx hash %s) %s", ptr_tx->GetHash().ToString(), tx_state.GetDebugMessage()));
}
if (creditPoolDiff != std::nullopt && !creditPoolDiff->ProcessTransaction(*ptr_tx, tx_state)) {
assert(tx_state.GetResult() == TxValidationResult::TX_CONSENSUS || tx_state.GetResult() == TxValidationResult::TX_BAD_SPECIAL);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(),
strprintf("Process Special Transaction failed at Credit Pool (tx hash %s) %s", ptr_tx->GetHash().ToString(), tx_state.GetDebugMessage()));
}
}
if (creditPoolDiff != std::nullopt) {
CAmount locked_proposed{0};
if(creditPoolDiff->GetTargetBalance()) locked_proposed = *creditPoolDiff->GetTargetBalance();

CAmount locked_calculated = creditPoolDiff->GetTotalLocked();
if (locked_proposed != locked_calculated) {
LogPrintf("%s: mismatched locked amount in CbTx: %lld against re-calculated: %lld\n", __func__, locked_proposed, locked_calculated);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cbtx-assetlocked-amount");
}
}

int64_t nTime2 = GetTimeMicros();
Expand Down Expand Up @@ -265,3 +248,41 @@ bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq:

return true;
}

bool CheckCreditPoolDiffForBlock(const CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams,
const CAmount blockReward, BlockValidationState& state)
{
AssertLockHeld(cs_main);

try {

if (!llmq::utils::IsV20Active(pindex->pprev)) return true;

const CCreditPool creditPool = creditPoolManager->GetCreditPool(pindex->pprev, consensusParams);
LogPrintf("%s: CCreditPool is %s\n", __func__, creditPool.ToString());
CCreditPoolDiff creditPoolDiff(creditPool, pindex->pprev, consensusParams);

for (const auto& ptr_tx : block.vtx) {
TxValidationState tx_state;
if (!creditPoolDiff.ProcessTransaction(*ptr_tx, blockReward, tx_state)) {
assert(tx_state.GetResult() == TxValidationResult::TX_CONSENSUS || tx_state.GetResult() == TxValidationResult::TX_BAD_SPECIAL);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(),
strprintf("Process Special Transaction failed at Credit Pool (tx hash %s) %s", ptr_tx->GetHash().ToString(), tx_state.GetDebugMessage()));
}
}
CAmount locked_proposed{0};
if (creditPoolDiff.GetTargetBalance()) locked_proposed = *creditPoolDiff.GetTargetBalance();

CAmount locked_calculated = creditPoolDiff.GetTotalLocked();
if (locked_proposed != locked_calculated) {
LogPrintf("%s: mismatched locked amount in CbTx: %lld against re-calculated: %lld\n", __func__, locked_proposed, locked_calculated);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cbtx-assetlocked-amount");
}

} catch (const std::exception& e) {
LogPrintf("%s -- failed: %s\n", __func__, e.what());
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "failed-procspectxsinblock");
}

return true;
}
2 changes: 2 additions & 0 deletions src/evo/specialtxman.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, ll
const Consensus::Params& consensusParams, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots,
BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool CheckCreditPoolDiffForBlock(const CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams,
const CAmount blockReward, BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);

#endif // BITCOIN_EVO_SPECIALTXMAN_H
2 changes: 1 addition & 1 deletion src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
// `state` is local here because used to log info about this specific tx
TxValidationState state;

if (!creditPoolDiff->ProcessTransaction(iter->GetTx(), state)) {
if (!creditPoolDiff->ProcessTransaction(iter->GetTx(), std::nullopt, state)) {
if (fUsingModified) {
mapModifiedTx.get<ancestor_score>().erase(modit);
failedTx.insert(iter);
Expand Down
17 changes: 13 additions & 4 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1974,6 +1974,7 @@ static int64_t nTimeForks = 0;
static int64_t nTimeVerify = 0;
static int64_t nTimeISFilter = 0;
static int64_t nTimeSubsidy = 0;
static int64_t nTimeCreditPool = 0;
static int64_t nTimeValueValid = 0;
static int64_t nTimePayeeValid = 0;
static int64_t nTimeProcessSpecial = 0;
Expand Down Expand Up @@ -2357,23 +2358,31 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
int64_t nTime5_2 = GetTimeMicros(); nTimeSubsidy += nTime5_2 - nTime5_1;
LogPrint(BCLog::BENCHMARK, " - GetBlockSubsidy: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5_2 - nTime5_1), nTimeSubsidy * MICRO, nTimeSubsidy * MILLI / nBlocksTotal);

if (!CheckCreditPoolDiffForBlock(block, pindex, m_params.GetConsensus(), blockReward, state)) {
return error("ConnectBlock(DASH): CheckCreditPoolDiffForBlock for block %s failed with %s",
pindex->GetBlockHash().ToString(), state.ToString());
}

int64_t nTime5_3 = GetTimeMicros(); nTimeCreditPool += nTime5_3 - nTime5_2;
LogPrint(BCLog::BENCHMARK, " - CheckCreditPoolDiffForBlock: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5_3 - nTime5_2), nTimeCreditPool * MICRO, nTimeCreditPool * MILLI / nBlocksTotal);

if (!MasternodePayments::IsBlockValueValid(*sporkManager, *governance, *::masternodeSync, block, pindex->nHeight, blockReward, strError)) {
// NOTE: Do not punish, the node might be missing governance data
LogPrintf("ERROR: ConnectBlock(DASH): %s\n", strError);
return state.Invalid(BlockValidationResult::BLOCK_RESULT_UNSET, "bad-cb-amount");
}

int64_t nTime5_3 = GetTimeMicros(); nTimeValueValid += nTime5_3 - nTime5_2;
LogPrint(BCLog::BENCHMARK, " - IsBlockValueValid: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5_3 - nTime5_2), nTimeValueValid * MICRO, nTimeValueValid * MILLI / nBlocksTotal);
int64_t nTime5_4 = GetTimeMicros(); nTimeValueValid += nTime5_4 - nTime5_3;
LogPrint(BCLog::BENCHMARK, " - IsBlockValueValid: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5_4 - nTime5_3), nTimeValueValid * MICRO, nTimeValueValid * MILLI / nBlocksTotal);

if (!MasternodePayments::IsBlockPayeeValid(*sporkManager, *governance, *block.vtx[0], pindex->nHeight, blockReward)) {
// NOTE: Do not punish, the node might be missing governance data
LogPrintf("ERROR: ConnectBlock(DASH): couldn't find masternode or superblock payments\n");
return state.Invalid(BlockValidationResult::BLOCK_RESULT_UNSET, "bad-cb-payee");
}

int64_t nTime5_4 = GetTimeMicros(); nTimePayeeValid += nTime5_4 - nTime5_3;
LogPrint(BCLog::BENCHMARK, " - IsBlockPayeeValid: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5_4 - nTime5_3), nTimePayeeValid * MICRO, nTimePayeeValid * MILLI / nBlocksTotal);
int64_t nTime5_5 = GetTimeMicros(); nTimePayeeValid += nTime5_5 - nTime5_4;
LogPrint(BCLog::BENCHMARK, " - IsBlockPayeeValid: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5_5 - nTime5_4), nTimePayeeValid * MICRO, nTimePayeeValid * MILLI / nBlocksTotal);

int64_t nTime5 = GetTimeMicros(); nTimeDashSpecific += nTime5 - nTime4;
LogPrint(BCLog::BENCHMARK, " - Dash specific: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5 - nTime4), nTimeDashSpecific * MICRO, nTimeDashSpecific * MILLI / nBlocksTotal);
Expand Down

0 comments on commit 2469443

Please sign in to comment.