mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
Refactor MN payee logic in preparation for DIP3 (#2215)
* Refactor block payee filling/validation 1. Move out old budget validation into it's own function (IsOldBudgetBlockValueValid) 2. Refactor IsBlockValueValid to bail out early instead of using deep nested if/else blocks. IMHO, I feel that this makes the code much easier to read and less error prone. 3. Refactor/rename CreateSuperblock and CMasternodePayments::FillBlockPayee to be getters without actually modifying the coinbase TX. The coinbase is now only modified from the global FillBlockPayments function. Makes later changes in DIP3 easier (allowing superblock and MN rewards in same block) * Use __func__ for logging in block payee code * Fix code style nit
This commit is contained in:
parent
d946f21bd9
commit
4d3518fe04
@ -366,14 +366,14 @@ bool CSuperblockManager::GetBestSuperblock(CSuperblock_sptr& pSuperblockRet, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Superblock Payments
|
* Get Superblock Payments
|
||||||
*
|
*
|
||||||
* - Create the correct payment structure for a given superblock
|
* - Returns payments for superblock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void CSuperblockManager::CreateSuperblock(CMutableTransaction& txNewRet, int nBlockHeight, std::vector<CTxOut>& voutSuperblockRet)
|
bool CSuperblockManager::GetSuperblockPayments(int nBlockHeight, std::vector<CTxOut>& voutSuperblockRet)
|
||||||
{
|
{
|
||||||
DBG( std::cout << "CSuperblockManager::CreateSuperblock Start" << std::endl; );
|
DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Start" << std::endl; );
|
||||||
|
|
||||||
LOCK(governance.cs);
|
LOCK(governance.cs);
|
||||||
|
|
||||||
@ -381,18 +381,18 @@ void CSuperblockManager::CreateSuperblock(CMutableTransaction& txNewRet, int nBl
|
|||||||
|
|
||||||
CSuperblock_sptr pSuperblock;
|
CSuperblock_sptr pSuperblock;
|
||||||
if(!CSuperblockManager::GetBestSuperblock(pSuperblock, nBlockHeight)) {
|
if(!CSuperblockManager::GetBestSuperblock(pSuperblock, nBlockHeight)) {
|
||||||
LogPrint("gobject", "CSuperblockManager::CreateSuperblock -- Can't find superblock for height %d\n", nBlockHeight);
|
LogPrint("gobject", "CSuperblockManager::GetSuperblockPayments -- Can't find superblock for height %d\n", nBlockHeight);
|
||||||
DBG( std::cout << "CSuperblockManager::CreateSuperblock Failed to get superblock for height, returning" << std::endl; );
|
DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Failed to get superblock for height, returning" << std::endl; );
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure it's empty, just in case
|
// make sure it's empty, just in case
|
||||||
voutSuperblockRet.clear();
|
voutSuperblockRet.clear();
|
||||||
|
|
||||||
// CONFIGURE SUPERBLOCK OUTPUTS
|
// GET SUPERBLOCK OUTPUTS
|
||||||
|
|
||||||
// Superblock payments are appended to the end of the coinbase vout vector
|
// Superblock payments will be appended to the end of the coinbase vout vector
|
||||||
DBG( std::cout << "CSuperblockManager::CreateSuperblock Number payments: " << pSuperblock->CountPayments() << std::endl; );
|
DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Number payments: " << pSuperblock->CountPayments() << std::endl; );
|
||||||
|
|
||||||
// TODO: How many payments can we add before things blow up?
|
// TODO: How many payments can we add before things blow up?
|
||||||
// Consider at least following limits:
|
// Consider at least following limits:
|
||||||
@ -400,13 +400,12 @@ void CSuperblockManager::CreateSuperblock(CMutableTransaction& txNewRet, int nBl
|
|||||||
// - max "budget" available
|
// - max "budget" available
|
||||||
for(int i = 0; i < pSuperblock->CountPayments(); i++) {
|
for(int i = 0; i < pSuperblock->CountPayments(); i++) {
|
||||||
CGovernancePayment payment;
|
CGovernancePayment payment;
|
||||||
DBG( std::cout << "CSuperblockManager::CreateSuperblock i = " << i << std::endl; );
|
DBG( std::cout << "CSuperblockManager::GetSuperblockPayments i = " << i << std::endl; );
|
||||||
if(pSuperblock->GetPayment(i, payment)) {
|
if(pSuperblock->GetPayment(i, payment)) {
|
||||||
DBG( std::cout << "CSuperblockManager::CreateSuperblock Payment found " << std::endl; );
|
DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Payment found " << std::endl; );
|
||||||
// SET COINBASE OUTPUT TO SUPERBLOCK SETTING
|
// SET COINBASE OUTPUT TO SUPERBLOCK SETTING
|
||||||
|
|
||||||
CTxOut txout = CTxOut(payment.nAmount, payment.script);
|
CTxOut txout = CTxOut(payment.nAmount, payment.script);
|
||||||
txNewRet.vout.push_back(txout);
|
|
||||||
voutSuperblockRet.push_back(txout);
|
voutSuperblockRet.push_back(txout);
|
||||||
|
|
||||||
// PRINT NICE LOG OUTPUT FOR SUPERBLOCK PAYMENT
|
// PRINT NICE LOG OUTPUT FOR SUPERBLOCK PAYMENT
|
||||||
@ -417,15 +416,17 @@ void CSuperblockManager::CreateSuperblock(CMutableTransaction& txNewRet, int nBl
|
|||||||
|
|
||||||
// TODO: PRINT NICE N.N DASH OUTPUT
|
// TODO: PRINT NICE N.N DASH OUTPUT
|
||||||
|
|
||||||
DBG( std::cout << "CSuperblockManager::CreateSuperblock Before LogPrintf call, nAmount = " << payment.nAmount << std::endl; );
|
DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Before LogPrintf call, nAmount = " << payment.nAmount << std::endl; );
|
||||||
LogPrintf("NEW Superblock : output %d (addr %s, amount %d)\n", i, address2.ToString(), payment.nAmount);
|
LogPrintf("NEW Superblock : output %d (addr %s, amount %d)\n", i, address2.ToString(), payment.nAmount);
|
||||||
DBG( std::cout << "CSuperblockManager::CreateSuperblock After LogPrintf call " << std::endl; );
|
DBG( std::cout << "CSuperblockManager::GetSuperblockPayments After LogPrintf call " << std::endl; );
|
||||||
} else {
|
} else {
|
||||||
DBG( std::cout << "CSuperblockManager::CreateSuperblock Payment not found " << std::endl; );
|
DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Payment not found " << std::endl; );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG( std::cout << "CSuperblockManager::CreateSuperblock End" << std::endl; );
|
DBG( std::cout << "CSuperblockManager::GetSuperblockPayments End" << std::endl; );
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSuperblockManager::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward)
|
bool CSuperblockManager::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward)
|
||||||
@ -679,7 +680,7 @@ bool CSuperblock::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount b
|
|||||||
|
|
||||||
int nOutputs = txNew.vout.size();
|
int nOutputs = txNew.vout.size();
|
||||||
int nPayments = CountPayments();
|
int nPayments = CountPayments();
|
||||||
int nMinerPayments = nOutputs - nPayments;
|
int nMinerAndMasternodePayments = nOutputs - nPayments;
|
||||||
|
|
||||||
LogPrint("gobject", "CSuperblock::IsValid nOutputs = %d, nPayments = %d, GetDataAsHexString = %s\n",
|
LogPrint("gobject", "CSuperblock::IsValid nOutputs = %d, nPayments = %d, GetDataAsHexString = %s\n",
|
||||||
nOutputs, nPayments, GetGovernanceObject()->GetDataAsHexString());
|
nOutputs, nPayments, GetGovernanceObject()->GetDataAsHexString());
|
||||||
@ -687,7 +688,7 @@ bool CSuperblock::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount b
|
|||||||
// We require an exact match (including order) between the expected
|
// We require an exact match (including order) between the expected
|
||||||
// superblock payments and the payments actually in the block.
|
// superblock payments and the payments actually in the block.
|
||||||
|
|
||||||
if(nMinerPayments < 0) {
|
if(nMinerAndMasternodePayments < 0) {
|
||||||
// This means the block cannot have all the superblock payments
|
// This means the block cannot have all the superblock payments
|
||||||
// so it is not valid.
|
// so it is not valid.
|
||||||
// TODO: could that be that we just hit coinbase size limit?
|
// TODO: could that be that we just hit coinbase size limit?
|
||||||
@ -703,7 +704,7 @@ bool CSuperblock::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount b
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// miner should not get more than he would usually get
|
// miner and masternodes should not get more than they would usually get
|
||||||
CAmount nBlockValue = txNew.GetValueOut();
|
CAmount nBlockValue = txNew.GetValueOut();
|
||||||
if(nBlockValue > blockReward + nPaymentsTotalAmount) {
|
if(nBlockValue > blockReward + nPaymentsTotalAmount) {
|
||||||
LogPrintf("CSuperblock::IsValid -- ERROR: Block invalid, block value limit exceeded: block %lld, limit %lld\n", nBlockValue, blockReward + nPaymentsTotalAmount);
|
LogPrintf("CSuperblock::IsValid -- ERROR: Block invalid, block value limit exceeded: block %lld, limit %lld\n", nBlockValue, blockReward + nPaymentsTotalAmount);
|
||||||
|
@ -67,7 +67,7 @@ public:
|
|||||||
|
|
||||||
static bool IsSuperblockTriggered(int nBlockHeight);
|
static bool IsSuperblockTriggered(int nBlockHeight);
|
||||||
|
|
||||||
static void CreateSuperblock(CMutableTransaction& txNewRet, int nBlockHeight, std::vector<CTxOut>& voutSuperblockRet);
|
static bool GetSuperblockPayments(int nBlockHeight, std::vector<CTxOut>& voutSuperblockRet);
|
||||||
static void ExecuteBestSuperblock(int nBlockHeight);
|
static void ExecuteBestSuperblock(int nBlockHeight);
|
||||||
|
|
||||||
static std::string GetRequiredPaymentsString(int nBlockHeight);
|
static std::string GetRequiredPaymentsString(int nBlockHeight);
|
||||||
|
@ -23,6 +23,45 @@ CCriticalSection cs_vecPayees;
|
|||||||
CCriticalSection cs_mapMasternodeBlocks;
|
CCriticalSection cs_mapMasternodeBlocks;
|
||||||
CCriticalSection cs_mapMasternodePaymentVotes;
|
CCriticalSection cs_mapMasternodePaymentVotes;
|
||||||
|
|
||||||
|
bool IsOldBudgetBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockReward, std::string& strErrorRet) {
|
||||||
|
const Consensus::Params& consensusParams = Params().GetConsensus();
|
||||||
|
|
||||||
|
if (nBlockHeight >= consensusParams.nSuperblockStartBlock) {
|
||||||
|
// switched to new budget system (superblocks)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isBlockRewardValueMet = (block.vtx[0]->GetValueOut() <= blockReward);
|
||||||
|
|
||||||
|
// we are still using budgets, but we have no data about them anymore,
|
||||||
|
// all we know is predefined budget cycle and window
|
||||||
|
|
||||||
|
int nOffset = nBlockHeight % consensusParams.nBudgetPaymentsCycleBlocks;
|
||||||
|
if(nBlockHeight >= consensusParams.nBudgetPaymentsStartBlock &&
|
||||||
|
nOffset < consensusParams.nBudgetPaymentsWindowBlocks) {
|
||||||
|
// NOTE: old budget system is disabled since 12.1
|
||||||
|
if(masternodeSync.IsSynced()) {
|
||||||
|
// no old budget blocks should be accepted here on mainnet,
|
||||||
|
// testnet/devnet/regtest should produce regular blocks only
|
||||||
|
LogPrint("gobject", "%s -- WARNING: Client synced but old budget system is disabled, checking block value against block reward\n", __func__);
|
||||||
|
if(!isBlockRewardValueMet) {
|
||||||
|
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, old budgets are disabled",
|
||||||
|
nBlockHeight, block.vtx[0]->GetValueOut(), blockReward);
|
||||||
|
}
|
||||||
|
return isBlockRewardValueMet;
|
||||||
|
}
|
||||||
|
// when not synced, rely on online nodes (all networks)
|
||||||
|
LogPrint("gobject", "%s -- WARNING: Skipping old budget block value checks, accepting block\n", __func__);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// LogPrint("gobject", "%s -- Block is not in budget cycle window, checking block value against block reward\n", __func__);
|
||||||
|
if(!isBlockRewardValueMet) {
|
||||||
|
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, block is not in old budget cycle window",
|
||||||
|
nBlockHeight, block.vtx[0]->GetValueOut(), blockReward);
|
||||||
|
}
|
||||||
|
return isBlockRewardValueMet;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IsBlockValueValid
|
* IsBlockValueValid
|
||||||
*
|
*
|
||||||
@ -38,105 +77,82 @@ bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockRewar
|
|||||||
{
|
{
|
||||||
strErrorRet = "";
|
strErrorRet = "";
|
||||||
|
|
||||||
bool isBlockRewardValueMet = (block.vtx[0]->GetValueOut() <= blockReward);
|
if (!IsOldBudgetBlockValueValid(block, nBlockHeight, blockReward, strErrorRet)) {
|
||||||
if(fDebug) LogPrintf("block.vtx[0]->GetValueOut() %lld <= blockReward %lld\n", block.vtx[0]->GetValueOut(), blockReward);
|
return false;
|
||||||
|
|
||||||
// we are still using budgets, but we have no data about them anymore,
|
|
||||||
// all we know is predefined budget cycle and window
|
|
||||||
|
|
||||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
|
||||||
|
|
||||||
if(nBlockHeight < consensusParams.nSuperblockStartBlock) {
|
|
||||||
int nOffset = nBlockHeight % consensusParams.nBudgetPaymentsCycleBlocks;
|
|
||||||
if(nBlockHeight >= consensusParams.nBudgetPaymentsStartBlock &&
|
|
||||||
nOffset < consensusParams.nBudgetPaymentsWindowBlocks) {
|
|
||||||
// NOTE: old budget system is disabled since 12.1
|
|
||||||
if(masternodeSync.IsSynced()) {
|
|
||||||
// no old budget blocks should be accepted here on mainnet,
|
|
||||||
// testnet/devnet/regtest should produce regular blocks only
|
|
||||||
LogPrint("gobject", "IsBlockValueValid -- WARNING: Client synced but old budget system is disabled, checking block value against block reward\n");
|
|
||||||
if(!isBlockRewardValueMet) {
|
|
||||||
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, old budgets are disabled",
|
|
||||||
nBlockHeight, block.vtx[0]->GetValueOut(), blockReward);
|
|
||||||
}
|
|
||||||
return isBlockRewardValueMet;
|
|
||||||
}
|
|
||||||
// when not synced, rely on online nodes (all networks)
|
|
||||||
LogPrint("gobject", "IsBlockValueValid -- WARNING: Skipping old budget block value checks, accepting block\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// LogPrint("gobject", "IsBlockValueValid -- Block is not in budget cycle window, checking block value against block reward\n");
|
|
||||||
if(!isBlockRewardValueMet) {
|
|
||||||
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, block is not in old budget cycle window",
|
|
||||||
nBlockHeight, block.vtx[0]->GetValueOut(), blockReward);
|
|
||||||
}
|
|
||||||
return isBlockRewardValueMet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// superblocks started
|
bool isBlockRewardValueMet = (block.vtx[0]->GetValueOut() <= blockReward);
|
||||||
|
if(fDebug) LogPrintf("block.vtx[0]->GetValueOut() %lld <= blockReward %lld\n", block.vtx[0]->GetValueOut(), blockReward);
|
||||||
|
|
||||||
CAmount nSuperblockMaxValue = blockReward + CSuperblock::GetPaymentsLimit(nBlockHeight);
|
CAmount nSuperblockMaxValue = blockReward + CSuperblock::GetPaymentsLimit(nBlockHeight);
|
||||||
bool isSuperblockMaxValueMet = (block.vtx[0]->GetValueOut() <= nSuperblockMaxValue);
|
bool isSuperblockMaxValueMet = (block.vtx[0]->GetValueOut() <= nSuperblockMaxValue);
|
||||||
|
|
||||||
LogPrint("gobject", "block.vtx[0]->GetValueOut() %lld <= nSuperblockMaxValue %lld\n", block.vtx[0]->GetValueOut(), nSuperblockMaxValue);
|
LogPrint("gobject", "block.vtx[0]->GetValueOut() %lld <= nSuperblockMaxValue %lld\n", block.vtx[0]->GetValueOut(), nSuperblockMaxValue);
|
||||||
|
|
||||||
if(!masternodeSync.IsSynced() || fLiteMode) {
|
if (!CSuperblock::IsValidBlockHeight(nBlockHeight)) {
|
||||||
// not enough data but at least it must NOT exceed superblock max value
|
// can't possibly be a superblock, so lets just check for block reward limits
|
||||||
if(CSuperblock::IsValidBlockHeight(nBlockHeight)) {
|
if (!isBlockRewardValueMet) {
|
||||||
if(fDebug) LogPrintf("IsBlockPayeeValid -- WARNING: Not enough data, checking superblock max bounds only\n");
|
|
||||||
if(!isSuperblockMaxValueMet) {
|
|
||||||
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded superblock max value",
|
|
||||||
nBlockHeight, block.vtx[0]->GetValueOut(), nSuperblockMaxValue);
|
|
||||||
}
|
|
||||||
return isSuperblockMaxValueMet;
|
|
||||||
}
|
|
||||||
if(!isBlockRewardValueMet) {
|
|
||||||
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, only regular blocks are allowed at this height",
|
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, only regular blocks are allowed at this height",
|
||||||
nBlockHeight, block.vtx[0]->GetValueOut(), blockReward);
|
nBlockHeight, block.vtx[0]->GetValueOut(), blockReward);
|
||||||
}
|
}
|
||||||
// it MUST be a regular block otherwise
|
|
||||||
return isBlockRewardValueMet;
|
return isBlockRewardValueMet;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we are synced, let's try to check as much data as we can
|
// bail out in case superblock limits were exceeded
|
||||||
|
if (!isSuperblockMaxValueMet) {
|
||||||
|
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded superblock max value",
|
||||||
|
nBlockHeight, block.vtx[0]->GetValueOut(), nSuperblockMaxValue);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED)) {
|
if(!masternodeSync.IsSynced() || fLiteMode) {
|
||||||
if(CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) {
|
if(fDebug) LogPrintf("%s -- WARNING: Not enough data, checked superblock max bounds only\n", __func__);
|
||||||
if(CSuperblockManager::IsValid(*block.vtx[0], nBlockHeight, blockReward)) {
|
// not enough data for full checks but at least we know that the superblock limits were honored.
|
||||||
LogPrint("gobject", "IsBlockValueValid -- Valid superblock at height %d: %s", nBlockHeight, block.vtx[0]->ToString());
|
// We rely on the network to have followed the correct chain in this case
|
||||||
// all checks are done in CSuperblock::IsValid, nothing to do here
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// triggered but invalid? that's weird
|
// we are synced and possibly on a superblock now
|
||||||
LogPrintf("IsBlockValueValid -- ERROR: Invalid superblock detected at height %d: %s", nBlockHeight, block.vtx[0]->ToString());
|
|
||||||
// should NOT allow invalid superblocks, when superblocks are enabled
|
if (!sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED)) {
|
||||||
strErrorRet = strprintf("invalid superblock detected at height %d", nBlockHeight);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LogPrint("gobject", "IsBlockValueValid -- No triggered superblock detected at height %d\n", nBlockHeight);
|
|
||||||
if(!isBlockRewardValueMet) {
|
|
||||||
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, no triggered superblock detected",
|
|
||||||
nBlockHeight, block.vtx[0]->GetValueOut(), blockReward);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// should NOT allow superblocks at all, when superblocks are disabled
|
// should NOT allow superblocks at all, when superblocks are disabled
|
||||||
LogPrint("gobject", "IsBlockValueValid -- Superblocks are disabled, no superblocks allowed\n");
|
// revert to block reward limits in this case
|
||||||
|
LogPrint("gobject", "%s -- Superblocks are disabled, no superblocks allowed\n", __func__);
|
||||||
if(!isBlockRewardValueMet) {
|
if(!isBlockRewardValueMet) {
|
||||||
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, superblocks are disabled",
|
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, superblocks are disabled",
|
||||||
nBlockHeight, block.vtx[0]->GetValueOut(), blockReward);
|
nBlockHeight, block.vtx[0]->GetValueOut(), blockReward);
|
||||||
}
|
}
|
||||||
|
return isBlockRewardValueMet;
|
||||||
}
|
}
|
||||||
|
|
||||||
// it MUST be a regular block
|
if (!CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) {
|
||||||
return isBlockRewardValueMet;
|
// we are on a valid superblock height but a superblock was not triggered
|
||||||
|
// revert to block reward limits in this case
|
||||||
|
if(!isBlockRewardValueMet) {
|
||||||
|
strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, no triggered superblock detected",
|
||||||
|
nBlockHeight, block.vtx[0]->GetValueOut(), blockReward);
|
||||||
|
}
|
||||||
|
return isBlockRewardValueMet;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this actually also checks for correct payees and not only amount
|
||||||
|
if (!CSuperblockManager::IsValid(*block.vtx[0], nBlockHeight, blockReward)) {
|
||||||
|
// triggered but invalid? that's weird
|
||||||
|
LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s", __func__, nBlockHeight, block.vtx[0]->ToString());
|
||||||
|
// should NOT allow invalid superblocks, when superblocks are enabled
|
||||||
|
strErrorRet = strprintf("invalid superblock detected at height %d", nBlockHeight);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we got a valid superblock
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward)
|
bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward)
|
||||||
{
|
{
|
||||||
if(!masternodeSync.IsSynced() || fLiteMode) {
|
if(!masternodeSync.IsSynced() || fLiteMode) {
|
||||||
//there is no budget data to use to check anything, let's just accept the longest chain
|
//there is no budget data to use to check anything, let's just accept the longest chain
|
||||||
if(fDebug) LogPrintf("IsBlockPayeeValid -- WARNING: Not enough data, skipping block payee checks\n");
|
if(fDebug) LogPrintf("%s -- WARNING: Not enough data, skipping block payee checks\n", __func__);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +165,7 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount bloc
|
|||||||
// NOTE: old budget system is disabled since 12.1 and we should never enter this branch
|
// NOTE: old budget system is disabled since 12.1 and we should never enter this branch
|
||||||
// anymore when sync is finished (on mainnet). We have no old budget data but these blocks
|
// anymore when sync is finished (on mainnet). We have no old budget data but these blocks
|
||||||
// have tons of confirmations and can be safely accepted without payee verification
|
// have tons of confirmations and can be safely accepted without payee verification
|
||||||
LogPrint("gobject", "IsBlockPayeeValid -- WARNING: Client synced but old budget system is disabled, accepting any payee\n");
|
LogPrint("gobject", "%s -- WARNING: Client synced but old budget system is disabled, accepting any payee\n", __func__);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,33 +175,33 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount bloc
|
|||||||
if(sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED)) {
|
if(sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED)) {
|
||||||
if(CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) {
|
if(CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) {
|
||||||
if(CSuperblockManager::IsValid(txNew, nBlockHeight, blockReward)) {
|
if(CSuperblockManager::IsValid(txNew, nBlockHeight, blockReward)) {
|
||||||
LogPrint("gobject", "IsBlockPayeeValid -- Valid superblock at height %d: %s", nBlockHeight, txNew.ToString());
|
LogPrint("gobject", "%s -- Valid superblock at height %d: %s", __func__, nBlockHeight, txNew.ToString());
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s", __func__, nBlockHeight, txNew.ToString());
|
||||||
|
// should NOT allow such superblocks, when superblocks are enabled
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
LogPrintf("IsBlockPayeeValid -- ERROR: Invalid superblock detected at height %d: %s", nBlockHeight, txNew.ToString());
|
LogPrint("gobject", "%s -- No triggered superblock detected at height %d\n", __func__, nBlockHeight);
|
||||||
// should NOT allow such superblocks, when superblocks are enabled
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
// continue validation, should pay MN
|
|
||||||
LogPrint("gobject", "IsBlockPayeeValid -- No triggered superblock detected at height %d\n", nBlockHeight);
|
|
||||||
} else {
|
} else {
|
||||||
// should NOT allow superblocks at all, when superblocks are disabled
|
// should NOT allow superblocks at all, when superblocks are disabled
|
||||||
LogPrint("gobject", "IsBlockPayeeValid -- Superblocks are disabled, no superblocks allowed\n");
|
LogPrint("gobject", "%s -- Superblocks are disabled, no superblocks allowed\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// IF THIS ISN'T A SUPERBLOCK OR SUPERBLOCK IS INVALID, IT SHOULD PAY A MASTERNODE DIRECTLY
|
// If this isn't a superblock or spork15 is activated, check for correct masternode payment
|
||||||
if(mnpayments.IsTransactionValid(txNew, nBlockHeight)) {
|
if(mnpayments.IsTransactionValid(txNew, nBlockHeight, blockReward)) {
|
||||||
LogPrint("mnpayments", "IsBlockPayeeValid -- Valid masternode payment at height %d: %s", nBlockHeight, txNew.ToString());
|
LogPrint("mnpayments", "%s -- Valid masternode payment at height %d: %s", __func__, nBlockHeight, txNew.ToString());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)) {
|
if(sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)) {
|
||||||
LogPrintf("IsBlockPayeeValid -- ERROR: Invalid masternode payment detected at height %d: %s", nBlockHeight, txNew.ToString());
|
LogPrintf("%s -- ERROR: Invalid masternode payment detected at height %d: %s", __func__, nBlockHeight, txNew.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("IsBlockPayeeValid -- WARNING: Masternode payment enforcement is disabled, accepting any payee\n");
|
LogPrintf("%s -- WARNING: Masternode payment enforcement is disabled, accepting any payee\n", __func__);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,14 +211,33 @@ void FillBlockPayments(CMutableTransaction& txNew, int nBlockHeight, CAmount blo
|
|||||||
// (height should be validated inside)
|
// (height should be validated inside)
|
||||||
if(sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED) &&
|
if(sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED) &&
|
||||||
CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) {
|
CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) {
|
||||||
LogPrint("gobject", "FillBlockPayments -- triggered superblock creation at height %d\n", nBlockHeight);
|
LogPrint("gobject", "%s -- triggered superblock creation at height %d\n", __func__, nBlockHeight);
|
||||||
CSuperblockManager::CreateSuperblock(txNew, nBlockHeight, voutSuperblockRet);
|
CSuperblockManager::GetSuperblockPayments(nBlockHeight, voutSuperblockRet);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILL BLOCK PAYEE WITH MASTERNODE PAYMENT OTHERWISE
|
// TODO this is a placeholder until DIP3 is merged, which will allow superblock payments and MN reward payments
|
||||||
mnpayments.FillBlockPayee(txNew, nBlockHeight, blockReward, txoutMasternodeRet);
|
// in the same block. We set this to false for now, which means that we'll always get into the next if statement
|
||||||
LogPrint("mnpayments", "FillBlockPayments -- nBlockHeight %d blockReward %lld txoutMasternodeRet %s txNew %s",
|
// when a superblock payment is present
|
||||||
|
bool allowSuperblockAndMNReward = false;
|
||||||
|
|
||||||
|
// don't allow payments to superblocks AND masternodes before spork15 activation
|
||||||
|
if (!voutSuperblockRet.empty() && !allowSuperblockAndMNReward) {
|
||||||
|
txNew.vout.insert(txNew.vout.end(), voutSuperblockRet.begin(), voutSuperblockRet.end());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mnpayments.GetMasternodeTxOut(nBlockHeight, blockReward, txoutMasternodeRet)) {
|
||||||
|
// no idea whom to pay (MN list empty?), lets hope for the best
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
txNew.vout.emplace_back(txoutMasternodeRet);
|
||||||
|
txNew.vout.insert(txNew.vout.end(), voutSuperblockRet.begin(), voutSuperblockRet.end());
|
||||||
|
|
||||||
|
// subtract MN payment from miner reward
|
||||||
|
txNew.vout[0].nValue -= txoutMasternodeRet.nValue;
|
||||||
|
|
||||||
|
LogPrint("mnpayments", "%s -- nBlockHeight %d blockReward %lld txoutMasternodeRet %s txNew %s", __func__,
|
||||||
nBlockHeight, blockReward, txoutMasternodeRet.ToString(), txNew.ToString());
|
nBlockHeight, blockReward, txoutMasternodeRet.ToString(), txNew.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,10 +279,10 @@ bool CMasternodePayments::UpdateLastVote(const CMasternodePaymentVote& vote)
|
|||||||
/**
|
/**
|
||||||
* FillBlockPayee
|
* FillBlockPayee
|
||||||
*
|
*
|
||||||
* Fill Masternode ONLY payment block
|
* Get masternode payment tx output
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, int nBlockHeight, CAmount blockReward, CTxOut& txoutMasternodeRet) const
|
bool CMasternodePayments::GetMasternodeTxOut(int nBlockHeight, CAmount blockReward, CTxOut& txoutMasternodeRet) const
|
||||||
{
|
{
|
||||||
// make sure it's not filled yet
|
// make sure it's not filled yet
|
||||||
txoutMasternodeRet = CTxOut();
|
txoutMasternodeRet = CTxOut();
|
||||||
@ -260,8 +295,8 @@ void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, int nBlockH
|
|||||||
masternode_info_t mnInfo;
|
masternode_info_t mnInfo;
|
||||||
if(!mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount, mnInfo)) {
|
if(!mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount, mnInfo)) {
|
||||||
// ...and we can't calculate it on our own
|
// ...and we can't calculate it on our own
|
||||||
LogPrintf("CMasternodePayments::FillBlockPayee -- Failed to detect masternode to pay\n");
|
LogPrintf("CMasternodePayments::%s -- Failed to detect masternode to pay\n", __func__);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
// fill payee with locally calculated winner and hope for the best
|
// fill payee with locally calculated winner and hope for the best
|
||||||
payee = GetScriptForDestination(mnInfo.keyIDCollateralAddress);
|
payee = GetScriptForDestination(mnInfo.keyIDCollateralAddress);
|
||||||
@ -269,18 +304,15 @@ void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, int nBlockH
|
|||||||
|
|
||||||
// GET MASTERNODE PAYMENT VARIABLES SETUP
|
// GET MASTERNODE PAYMENT VARIABLES SETUP
|
||||||
CAmount masternodePayment = GetMasternodePayment(nBlockHeight, blockReward);
|
CAmount masternodePayment = GetMasternodePayment(nBlockHeight, blockReward);
|
||||||
|
|
||||||
// split reward between miner ...
|
|
||||||
txNew.vout[0].nValue -= masternodePayment;
|
|
||||||
// ... and masternode
|
|
||||||
txoutMasternodeRet = CTxOut(masternodePayment, payee);
|
txoutMasternodeRet = CTxOut(masternodePayment, payee);
|
||||||
txNew.vout.push_back(txoutMasternodeRet);
|
|
||||||
|
|
||||||
CTxDestination address1;
|
CTxDestination address1;
|
||||||
ExtractDestination(payee, address1);
|
ExtractDestination(payee, address1);
|
||||||
CBitcoinAddress address2(address1);
|
CBitcoinAddress address2(address1);
|
||||||
|
|
||||||
LogPrintf("CMasternodePayments::FillBlockPayee -- Masternode payment %lld to %s\n", masternodePayment, address2.ToString());
|
LogPrintf("CMasternodePayments::%s -- Masternode payment %lld to %s\n", __func__, masternodePayment, address2.ToString());
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CMasternodePayments::GetMinMasternodePaymentsProto() const {
|
int CMasternodePayments::GetMinMasternodePaymentsProto() const {
|
||||||
@ -445,12 +477,12 @@ bool CMasternodePaymentVote::Sign()
|
|||||||
uint256 hash = GetSignatureHash();
|
uint256 hash = GetSignatureHash();
|
||||||
|
|
||||||
if(!CHashSigner::SignHash(hash, activeMasternodeInfo.keyMasternode, vchSig)) {
|
if(!CHashSigner::SignHash(hash, activeMasternodeInfo.keyMasternode, vchSig)) {
|
||||||
LogPrintf("CMasternodePaymentVote::Sign -- SignHash() failed\n");
|
LogPrintf("CMasternodePaymentVote::%s -- SignHash() failed\n", __func__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CHashSigner::VerifyHash(hash, activeMasternodeInfo.keyIDMasternode, vchSig, strError)) {
|
if (!CHashSigner::VerifyHash(hash, activeMasternodeInfo.keyIDMasternode, vchSig, strError)) {
|
||||||
LogPrintf("CMasternodePaymentVote::Sign -- VerifyHash() failed, error: %s\n", strError);
|
LogPrintf("CMasternodePaymentVote::%s -- VerifyHash() failed, error: %s\n", __func__, strError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -459,12 +491,12 @@ bool CMasternodePaymentVote::Sign()
|
|||||||
ScriptToAsmStr(payee);
|
ScriptToAsmStr(payee);
|
||||||
|
|
||||||
if(!CMessageSigner::SignMessage(strMessage, vchSig, activeMasternodeInfo.keyMasternode)) {
|
if(!CMessageSigner::SignMessage(strMessage, vchSig, activeMasternodeInfo.keyMasternode)) {
|
||||||
LogPrintf("CMasternodePaymentVote::Sign -- SignMessage() failed\n");
|
LogPrintf("CMasternodePaymentVote::%s -- SignMessage() failed\n", __func__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!CMessageSigner::VerifyMessage(activeMasternodeInfo.keyIDMasternode, vchSig, strMessage, strError)) {
|
if(!CMessageSigner::VerifyMessage(activeMasternodeInfo.keyIDMasternode, vchSig, strMessage, strError)) {
|
||||||
LogPrintf("CMasternodePaymentVote::Sign -- VerifyMessage() failed, error: %s\n", strError);
|
LogPrintf("CMasternodePaymentVote::%s -- VerifyMessage() failed, error: %s\n", __func__, strError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -518,7 +550,7 @@ bool CMasternodePayments::AddOrUpdatePaymentVote(const CMasternodePaymentVote& v
|
|||||||
auto it = mapMasternodeBlocks.emplace(vote.nBlockHeight, CMasternodeBlockPayees(vote.nBlockHeight)).first;
|
auto it = mapMasternodeBlocks.emplace(vote.nBlockHeight, CMasternodeBlockPayees(vote.nBlockHeight)).first;
|
||||||
it->second.AddPayee(vote);
|
it->second.AddPayee(vote);
|
||||||
|
|
||||||
LogPrint("mnpayments", "CMasternodePayments::AddOrUpdatePaymentVote -- added, hash=%s\n", nVoteHash.ToString());
|
LogPrint("mnpayments", "CMasternodePayments::%s -- added, hash=%s\n", __func__, nVoteHash.ToString());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -551,7 +583,7 @@ bool CMasternodeBlockPayees::GetBestPayee(CScript& payeeRet) const
|
|||||||
LOCK(cs_vecPayees);
|
LOCK(cs_vecPayees);
|
||||||
|
|
||||||
if(vecPayees.empty()) {
|
if(vecPayees.empty()) {
|
||||||
LogPrint("mnpayments", "CMasternodeBlockPayees::GetBestPayee -- ERROR: couldn't find any payee\n");
|
LogPrint("mnpayments", "CMasternodeBlockPayees::%s -- ERROR: couldn't find any payee\n", __func__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,7 +608,7 @@ bool CMasternodeBlockPayees::HasPayeeWithVotes(const CScript& payeeIn, int nVote
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint("mnpayments", "CMasternodeBlockPayees::HasPayeeWithVotes -- ERROR: couldn't find any payee with %d+ votes\n", nVotesReq);
|
LogPrint("mnpayments", "CMasternodeBlockPayees::%s -- ERROR: couldn't find any payee with %d+ votes\n", __func__, nVotesReq);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,7 +636,7 @@ bool CMasternodeBlockPayees::IsTransactionValid(const CTransaction& txNew) const
|
|||||||
if (payee.GetVoteCount() >= MNPAYMENTS_SIGNATURES_REQUIRED) {
|
if (payee.GetVoteCount() >= MNPAYMENTS_SIGNATURES_REQUIRED) {
|
||||||
for (const auto& txout : txNew.vout) {
|
for (const auto& txout : txNew.vout) {
|
||||||
if (payee.GetPayee() == txout.scriptPubKey && nMasternodePayment == txout.nValue) {
|
if (payee.GetPayee() == txout.scriptPubKey && nMasternodePayment == txout.nValue) {
|
||||||
LogPrint("mnpayments", "CMasternodeBlockPayees::IsTransactionValid -- Found required payment\n");
|
LogPrint("mnpayments", "CMasternodeBlockPayees::%s -- Found required payment\n", __func__);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -621,7 +653,7 @@ bool CMasternodeBlockPayees::IsTransactionValid(const CTransaction& txNew) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("CMasternodeBlockPayees::IsTransactionValid -- ERROR: Missing required payment, possible payees: '%s', amount: %f DASH\n", strPayeesPossible, (float)nMasternodePayment/COIN);
|
LogPrintf("CMasternodeBlockPayees::%s -- ERROR: Missing required payment, possible payees: '%s', amount: %f DASH\n", __func__, strPayeesPossible, (float)nMasternodePayment/COIN);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,10 +689,9 @@ std::string CMasternodePayments::GetRequiredPaymentsString(int nBlockHeight) con
|
|||||||
return it == mapMasternodeBlocks.end() ? "Unknown" : it->second.GetRequiredPaymentsString();
|
return it == mapMasternodeBlocks.end() ? "Unknown" : it->second.GetRequiredPaymentsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlockHeight) const
|
bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) const
|
||||||
{
|
{
|
||||||
LOCK(cs_mapMasternodeBlocks);
|
LOCK(cs_mapMasternodeBlocks);
|
||||||
|
|
||||||
const auto it = mapMasternodeBlocks.find(nBlockHeight);
|
const auto it = mapMasternodeBlocks.find(nBlockHeight);
|
||||||
return it == mapMasternodeBlocks.end() ? true : it->second.IsTransactionValid(txNew);
|
return it == mapMasternodeBlocks.end() ? true : it->second.IsTransactionValid(txNew);
|
||||||
}
|
}
|
||||||
@ -678,14 +709,14 @@ void CMasternodePayments::CheckAndRemove()
|
|||||||
CMasternodePaymentVote vote = (*it).second;
|
CMasternodePaymentVote vote = (*it).second;
|
||||||
|
|
||||||
if(nCachedBlockHeight - vote.nBlockHeight > nLimit) {
|
if(nCachedBlockHeight - vote.nBlockHeight > nLimit) {
|
||||||
LogPrint("mnpayments", "CMasternodePayments::CheckAndRemove -- Removing old Masternode payment: nBlockHeight=%d\n", vote.nBlockHeight);
|
LogPrint("mnpayments", "CMasternodePayments::%s -- Removing old Masternode payment: nBlockHeight=%d\n", __func__, vote.nBlockHeight);
|
||||||
mapMasternodePaymentVotes.erase(it++);
|
mapMasternodePaymentVotes.erase(it++);
|
||||||
mapMasternodeBlocks.erase(vote.nBlockHeight);
|
mapMasternodeBlocks.erase(vote.nBlockHeight);
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogPrintf("CMasternodePayments::CheckAndRemove -- %s\n", ToString());
|
LogPrintf("CMasternodePayments::%s -- %s\n", __func__, ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::string& strError, CConnman& connman) const
|
bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::string& strError, CConnman& connman) const
|
||||||
@ -723,7 +754,7 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s
|
|||||||
int nRank;
|
int nRank;
|
||||||
|
|
||||||
if(!mnodeman.GetMasternodeRank(masternodeOutpoint, nRank, nBlockHeight - 101, nMinRequiredProtocol)) {
|
if(!mnodeman.GetMasternodeRank(masternodeOutpoint, nRank, nBlockHeight - 101, nMinRequiredProtocol)) {
|
||||||
LogPrint("mnpayments", "CMasternodePaymentVote::IsValid -- Can't calculate rank for masternode %s\n",
|
LogPrint("mnpayments", "CMasternodePaymentVote::%s -- Can't calculate rank for masternode %s\n", __func__,
|
||||||
masternodeOutpoint.ToStringShort());
|
masternodeOutpoint.ToStringShort());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -736,7 +767,7 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s
|
|||||||
if(nRank > MNPAYMENTS_SIGNATURES_TOTAL*2 && nBlockHeight > nValidationHeight) {
|
if(nRank > MNPAYMENTS_SIGNATURES_TOTAL*2 && nBlockHeight > nValidationHeight) {
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
strError = strprintf("Masternode %s is not in the top %d (%d)", masternodeOutpoint.ToStringShort(), MNPAYMENTS_SIGNATURES_TOTAL*2, nRank);
|
strError = strprintf("Masternode %s is not in the top %d (%d)", masternodeOutpoint.ToStringShort(), MNPAYMENTS_SIGNATURES_TOTAL*2, nRank);
|
||||||
LogPrintf("CMasternodePaymentVote::IsValid -- Error: %s\n", strError);
|
LogPrintf("CMasternodePaymentVote::%s -- Error: %s\n", __func__, strError);
|
||||||
Misbehaving(pnode->GetId(), 20);
|
Misbehaving(pnode->GetId(), 20);
|
||||||
}
|
}
|
||||||
// Still invalid however
|
// Still invalid however
|
||||||
@ -760,30 +791,30 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight, CConnman& connman)
|
|||||||
int nRank;
|
int nRank;
|
||||||
|
|
||||||
if (!mnodeman.GetMasternodeRank(activeMasternodeInfo.outpoint, nRank, nBlockHeight - 101, GetMinMasternodePaymentsProto())) {
|
if (!mnodeman.GetMasternodeRank(activeMasternodeInfo.outpoint, nRank, nBlockHeight - 101, GetMinMasternodePaymentsProto())) {
|
||||||
LogPrint("mnpayments", "CMasternodePayments::ProcessBlock -- Unknown Masternode\n");
|
LogPrint("mnpayments", "CMasternodePayments::%s -- Unknown Masternode\n", __func__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nRank > MNPAYMENTS_SIGNATURES_TOTAL) {
|
if (nRank > MNPAYMENTS_SIGNATURES_TOTAL) {
|
||||||
LogPrint("mnpayments", "CMasternodePayments::ProcessBlock -- Masternode not in the top %d (%d)\n", MNPAYMENTS_SIGNATURES_TOTAL, nRank);
|
LogPrint("mnpayments", "CMasternodePayments::%s -- Masternode not in the top %d (%d)\n", __func__, MNPAYMENTS_SIGNATURES_TOTAL, nRank);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// LOCATE THE NEXT MASTERNODE WHICH SHOULD BE PAID
|
// LOCATE THE NEXT MASTERNODE WHICH SHOULD BE PAID
|
||||||
|
|
||||||
LogPrintf("CMasternodePayments::ProcessBlock -- Start: nBlockHeight=%d, masternode=%s\n", nBlockHeight, activeMasternodeInfo.outpoint.ToStringShort());
|
LogPrintf("CMasternodePayments::%s -- Start: nBlockHeight=%d, masternode=%s\n", __func__, nBlockHeight, activeMasternodeInfo.outpoint.ToStringShort());
|
||||||
|
|
||||||
// pay to the oldest MN that still had no payment but its input is old enough and it was active long enough
|
// pay to the oldest MN that still had no payment but its input is old enough and it was active long enough
|
||||||
int nCount = 0;
|
int nCount = 0;
|
||||||
masternode_info_t mnInfo;
|
masternode_info_t mnInfo;
|
||||||
|
|
||||||
if (!mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount, mnInfo)) {
|
if (!mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount, mnInfo)) {
|
||||||
LogPrintf("CMasternodePayments::ProcessBlock -- ERROR: Failed to find masternode to pay\n");
|
LogPrintf("CMasternodePayments::%s -- ERROR: Failed to find masternode to pay\n", __func__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("CMasternodePayments::ProcessBlock -- Masternode found by GetNextMasternodeInQueueForPayment(): %s\n", mnInfo.outpoint.ToStringShort());
|
LogPrintf("CMasternodePayments::%s -- Masternode found by GetNextMasternodeInQueueForPayment(): %s\n", __func__, mnInfo.outpoint.ToStringShort());
|
||||||
|
|
||||||
|
|
||||||
CScript payee = GetScriptForDestination(mnInfo.keyIDCollateralAddress);
|
CScript payee = GetScriptForDestination(mnInfo.keyIDCollateralAddress);
|
||||||
@ -794,13 +825,13 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight, CConnman& connman)
|
|||||||
ExtractDestination(payee, address1);
|
ExtractDestination(payee, address1);
|
||||||
CBitcoinAddress address2(address1);
|
CBitcoinAddress address2(address1);
|
||||||
|
|
||||||
LogPrintf("CMasternodePayments::ProcessBlock -- vote: payee=%s, nBlockHeight=%d\n", address2.ToString(), nBlockHeight);
|
LogPrintf("CMasternodePayments::%s -- vote: payee=%s, nBlockHeight=%d\n", address2.ToString(), nBlockHeight);
|
||||||
|
|
||||||
// SIGN MESSAGE TO NETWORK WITH OUR MASTERNODE KEYS
|
// SIGN MESSAGE TO NETWORK WITH OUR MASTERNODE KEYS
|
||||||
|
|
||||||
LogPrintf("CMasternodePayments::ProcessBlock -- Signing vote\n");
|
LogPrintf("CMasternodePayments::%s -- Signing vote\n", __func__);
|
||||||
if (voteNew.Sign()) {
|
if (voteNew.Sign()) {
|
||||||
LogPrintf("CMasternodePayments::ProcessBlock -- AddOrUpdatePaymentVote()\n");
|
LogPrintf("CMasternodePayments::%s -- AddOrUpdatePaymentVote()\n", __func__);
|
||||||
|
|
||||||
if (AddOrUpdatePaymentVote(voteNew)) {
|
if (AddOrUpdatePaymentVote(voteNew)) {
|
||||||
voteNew.Relay(connman);
|
voteNew.Relay(connman);
|
||||||
@ -817,13 +848,13 @@ void CMasternodePayments::CheckBlockVotes(int nBlockHeight)
|
|||||||
|
|
||||||
CMasternodeMan::rank_pair_vec_t mns;
|
CMasternodeMan::rank_pair_vec_t mns;
|
||||||
if (!mnodeman.GetMasternodeRanks(mns, nBlockHeight - 101, GetMinMasternodePaymentsProto())) {
|
if (!mnodeman.GetMasternodeRanks(mns, nBlockHeight - 101, GetMinMasternodePaymentsProto())) {
|
||||||
LogPrintf("CMasternodePayments::CheckBlockVotes -- nBlockHeight=%d, GetMasternodeRanks failed\n", nBlockHeight);
|
LogPrintf("CMasternodePayments::%s -- nBlockHeight=%d, GetMasternodeRanks failed\n", __func__, nBlockHeight);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string debugStr;
|
std::string debugStr;
|
||||||
|
|
||||||
debugStr += strprintf("CMasternodePayments::CheckBlockVotes -- nBlockHeight=%d,\n Expected voting MNs:\n", nBlockHeight);
|
debugStr += strprintf("CMasternodePayments::%s -- nBlockHeight=%d,\n Expected voting MNs:\n", __func__, nBlockHeight);
|
||||||
|
|
||||||
LOCK2(cs_mapMasternodeBlocks, cs_mapMasternodePaymentVotes);
|
LOCK2(cs_mapMasternodeBlocks, cs_mapMasternodePaymentVotes);
|
||||||
|
|
||||||
@ -885,7 +916,7 @@ void CMasternodePaymentVote::Relay(CConnman& connman) const
|
|||||||
{
|
{
|
||||||
// Do not relay until fully synced
|
// Do not relay until fully synced
|
||||||
if(!masternodeSync.IsSynced()) {
|
if(!masternodeSync.IsSynced()) {
|
||||||
LogPrint("mnpayments", "CMasternodePayments::Relay -- won't relay until fully synced\n");
|
LogPrint("mnpayments", "CMasternodePayments::%s -- won't relay until fully synced\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -974,7 +1005,7 @@ void CMasternodePayments::Sync(CNode* pnode, CConnman& connman) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("CMasternodePayments::Sync -- Sent %d votes to peer=%d\n", nInvCount, pnode->id);
|
LogPrintf("CMasternodePayments::%s -- Sent %d votes to peer=%d\n", __func__, nInvCount, pnode->id);
|
||||||
CNetMsgMaker msgMaker(pnode->GetSendVersion());
|
CNetMsgMaker msgMaker(pnode->GetSendVersion());
|
||||||
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::SYNCSTATUSCOUNT, MASTERNODE_SYNC_MNW, nInvCount));
|
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::SYNCSTATUSCOUNT, MASTERNODE_SYNC_MNW, nInvCount));
|
||||||
}
|
}
|
||||||
@ -999,7 +1030,7 @@ void CMasternodePayments::RequestLowDataPaymentBlocks(CNode* pnode, CConnman& co
|
|||||||
vToFetch.push_back(CInv(MSG_MASTERNODE_PAYMENT_BLOCK, pindex->GetBlockHash()));
|
vToFetch.push_back(CInv(MSG_MASTERNODE_PAYMENT_BLOCK, pindex->GetBlockHash()));
|
||||||
// We should not violate GETDATA rules
|
// We should not violate GETDATA rules
|
||||||
if(vToFetch.size() == MAX_INV_SZ) {
|
if(vToFetch.size() == MAX_INV_SZ) {
|
||||||
LogPrintf("CMasternodePayments::RequestLowDataPaymentBlocks -- asking peer=%d for %d blocks\n", pnode->id, MAX_INV_SZ);
|
LogPrintf("CMasternodePayments::%s -- asking peer=%d for %d blocks\n", __func__, pnode->id, MAX_INV_SZ);
|
||||||
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETDATA, vToFetch));
|
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETDATA, vToFetch));
|
||||||
// Start filling new batch
|
// Start filling new batch
|
||||||
vToFetch.clear();
|
vToFetch.clear();
|
||||||
@ -1045,7 +1076,7 @@ void CMasternodePayments::RequestLowDataPaymentBlocks(CNode* pnode, CConnman& co
|
|||||||
}
|
}
|
||||||
// We should not violate GETDATA rules
|
// We should not violate GETDATA rules
|
||||||
if(vToFetch.size() == MAX_INV_SZ) {
|
if(vToFetch.size() == MAX_INV_SZ) {
|
||||||
LogPrintf("CMasternodePayments::RequestLowDataPaymentBlocks -- asking peer=%d for %d payment blocks\n", pnode->id, MAX_INV_SZ);
|
LogPrintf("CMasternodePayments::%s -- asking peer=%d for %d payment blocks\n", __func__, pnode->id, MAX_INV_SZ);
|
||||||
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETDATA, vToFetch));
|
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETDATA, vToFetch));
|
||||||
// Start filling new batch
|
// Start filling new batch
|
||||||
vToFetch.clear();
|
vToFetch.clear();
|
||||||
@ -1053,7 +1084,7 @@ void CMasternodePayments::RequestLowDataPaymentBlocks(CNode* pnode, CConnman& co
|
|||||||
}
|
}
|
||||||
// Ask for the rest of it
|
// Ask for the rest of it
|
||||||
if(!vToFetch.empty()) {
|
if(!vToFetch.empty()) {
|
||||||
LogPrintf("CMasternodePayments::RequestLowDataPaymentBlocks -- asking peer=%d for %d payment blocks\n", pnode->id, vToFetch.size());
|
LogPrintf("CMasternodePayments::%s -- asking peer=%d for %d payment blocks\n", __func__, pnode->id, vToFetch.size());
|
||||||
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETDATA, vToFetch));
|
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETDATA, vToFetch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1085,7 +1116,7 @@ void CMasternodePayments::UpdatedBlockTip(const CBlockIndex *pindex, CConnman& c
|
|||||||
if(!pindex) return;
|
if(!pindex) return;
|
||||||
|
|
||||||
nCachedBlockHeight = pindex->nHeight;
|
nCachedBlockHeight = pindex->nHeight;
|
||||||
LogPrint("mnpayments", "CMasternodePayments::UpdatedBlockTip -- nCachedBlockHeight=%d\n", nCachedBlockHeight);
|
LogPrint("mnpayments", "CMasternodePayments::%s -- nCachedBlockHeight=%d\n", __func__, nCachedBlockHeight);
|
||||||
|
|
||||||
int nFutureBlock = nCachedBlockHeight + 10;
|
int nFutureBlock = nCachedBlockHeight + 10;
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ public:
|
|||||||
void CheckAndRemove();
|
void CheckAndRemove();
|
||||||
|
|
||||||
bool GetBlockPayee(int nBlockHeight, CScript& payeeRet) const;
|
bool GetBlockPayee(int nBlockHeight, CScript& payeeRet) const;
|
||||||
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight) const;
|
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) const;
|
||||||
bool IsScheduled(const masternode_info_t& mnInfo, int nNotBlockHeight) const;
|
bool IsScheduled(const masternode_info_t& mnInfo, int nNotBlockHeight) const;
|
||||||
|
|
||||||
bool UpdateLastVote(const CMasternodePaymentVote& vote);
|
bool UpdateLastVote(const CMasternodePaymentVote& vote);
|
||||||
@ -222,7 +222,7 @@ public:
|
|||||||
int GetMinMasternodePaymentsProto() const;
|
int GetMinMasternodePaymentsProto() const;
|
||||||
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman);
|
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman);
|
||||||
std::string GetRequiredPaymentsString(int nBlockHeight) const;
|
std::string GetRequiredPaymentsString(int nBlockHeight) const;
|
||||||
void FillBlockPayee(CMutableTransaction& txNew, int nBlockHeight, CAmount blockReward, CTxOut& txoutMasternodeRet) const;
|
bool GetMasternodeTxOut(int nBlockHeight, CAmount blockReward, CTxOut& txoutMasternodeRet) const;
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
|
|
||||||
int GetBlockCount() const { return mapMasternodeBlocks.size(); }
|
int GetBlockCount() const { return mapMasternodeBlocks.size(); }
|
||||||
|
Loading…
Reference in New Issue
Block a user