Skip to content

Commit

Permalink
Merge pull request #24 from MattF42/foundation-fee
Browse files Browse the repository at this point in the history
Foundation fee
  • Loading branch information
MattF42 committed Jan 15, 2024
2 parents f356744 + 215db1c commit 076f3a8
Show file tree
Hide file tree
Showing 12 changed files with 264 additions and 142 deletions.
8 changes: 4 additions & 4 deletions configure.ac
@@ -1,11 +1,11 @@
dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 2)
define(_CLIENT_VERSION_MINOR, 3)
define(_CLIENT_VERSION_REVISION, 1)
define(_CLIENT_VERSION_BUILD, 3)
define(_CLIENT_VERSION_MINOR, 4)
define(_CLIENT_VERSION_REVISION, 4)
define(_CLIENT_VERSION_BUILD, 2)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2023)
define(_COPYRIGHT_YEAR, 2024)
AC_INIT([PEPEPOW Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/PEPEPOWpay/PEPEPOW/issues],[PEPEPOWcore])
AC_CONFIG_SRCDIR([src/validation.cpp])
AC_CONFIG_HEADERS([src/config/PEPEPOW-config.h])
Expand Down
2 changes: 1 addition & 1 deletion src/chainparams.cpp
Expand Up @@ -128,7 +128,7 @@ class CMainParams : public CChainParams {
consensus.nBudgetPaymentsCycleBlocks = 16616; // ~(60*24*30)/2.6, actual number of blocks per month is 200700 / 12 = 16725
consensus.nBudgetPaymentsWindowBlocks = 100;
consensus.nBudgetProposalEstablishingTime = 60*60*24;
consensus.nSuperblockStartBlock = 614820; // The block at which 12.1 goes live (end of final 12.0 budget cycle)
consensus.nSuperblockStartBlock = 120000; // Was previously 614820 inherited from Dash - surprised it worked at all prior to that - Foztor Jan 24
consensus.nSuperblockCycle = 16616; // ~(60*24*30)/2.6, actual number of blocks per month is 200700 / 12 = 16725
consensus.nGovernanceMinQuorum = 10;
consensus.nGovernanceFilterElements = 20000;
Expand Down
193 changes: 97 additions & 96 deletions src/masternode-payments.cpp
Expand Up @@ -39,95 +39,64 @@ bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockRewar

bool isBlockRewardValueMet = (block.vtx[0].GetValueOut() <= blockReward);
if(fDebug) LogPrintf("block.vtx[0].GetValueOut() %lld <= blockReward %lld\n", block.vtx[0].GetValueOut(), blockReward);

// Not in PEPEPOW It's just a hack
// superblocks started
// But not DASH superblocks as we know them
/*
* if(nPrevHeight >= FOUNDATION_HEIGHT){
* if(nPrevHeight % 1000 == 998) {
* nSubsidy = nSubsidy * 5;
* }else if(nPrevHeight % 100 == 87) {
* nSubsidy = nSubsidy * 2;
* }
* }
*/

// 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: make sure SPORK_13_OLD_SUPERBLOCK_FLAG is disabled when 12.1 starts to go live
if(masternodeSync.IsSynced() && !sporkManager.IsSporkActive(SPORK_13_OLD_SUPERBLOCK_FLAG)) {
// no budget blocks should be accepted here, if SPORK_13_OLD_SUPERBLOCK_FLAG is disabled
LogPrint("gobject", "IsBlockValueValid -- Client synced but budget spork 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, budgets are disabled",
nBlockHeight, block.vtx[0].GetValueOut(), blockReward);
}
if(nBlockHeight < FOUNDATION_HEIGHT) {
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",
nBlockHeight, block.vtx[0].GetValueOut(), blockReward);
}
return isBlockRewardValueMet;
}
LogPrint("gobject", "IsBlockValueValid -- WARNING: Skipping budget block value checks, accepting block\n");
// TODO: reprocess blocks to make sure they are legit?
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 budget cycle window",
nBlockHeight, block.vtx[0].GetValueOut(), blockReward);
}
return isBlockRewardValueMet;
}

// superblocks started
// But not DASH superblocks as we know them - from validation.cpp where the reward is defined....
/*
* if(nPrevHeight >= FOUNDATION_HEIGHT){
* if(nPrevHeight % 1000 == 998) {
* nSubsidy = nSubsidy * 5;
* }else if(nPrevHeight % 100 == 87) {
* nSubsidy = nSubsidy * 2;
* }
* }
*/

CAmount nSuperblockMaxValue = blockReward + CSuperblock::GetPaymentsLimit(nBlockHeight);
bool isSuperblockMaxValueMet = (block.vtx[0].GetValueOut() <= nSuperblockMaxValue);

LogPrint("gobject", "block.vtx[0].GetValueOut() %lld <= nSuperblockMaxValue %lld\n", block.vtx[0].GetValueOut(), nSuperblockMaxValue);

if(!masternodeSync.IsSynced()) {
// not enough data but at least it must NOT exceed superblock max value
if(CSuperblock::IsValidBlockHeight(nBlockHeight)) {
if(fDebug) LogPrintf("IsBlockPayeeValid -- WARNING: Client not synced, 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",
nBlockHeight, block.vtx[0].GetValueOut(), blockReward);
}
// it MUST be a regular block otherwise
return isBlockRewardValueMet;
}

// we are synced, let's try to check as much data as we can

if(sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED)) {
if(CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) {
if(CSuperblockManager::IsValid(block.vtx[0], nBlockHeight, blockReward)) {
LogPrint("gobject", "IsBlockValueValid -- Valid superblock at height %d: %s", nBlockHeight, block.vtx[0].ToString());
// all checks are done in CSuperblock::IsValid, nothing to do here
return true;
}

// triggered but invalid? that's weird
LogPrintf("IsBlockValueValid -- ERROR: Invalid superblock detected at height %d: %s", 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;
}
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
LogPrint("gobject", "IsBlockValueValid -- Superblocks are disabled, no superblocks allowed\n");
if(!isBlockRewardValueMet) {
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);
}
}

// it MUST be a regular block
return isBlockRewardValueMet;

// Superblocks are live
if( nBlockHeight % 100 == 88 ) { // Double reward
LogPrintf("IsBlockValueValid -- Double SUPERBLOCK_EXPECTED at height %d: %s", nBlockHeight, block.vtx[0].ToString());
blockReward = blockReward * 2;
}
if( nBlockHeight % 1000 == 999 ) { // 5 times reward
LogPrintf("IsBlockValueValid -- Quintuple SUPERBLOCK_EXPECTED at height %d: %s", nBlockHeight, block.vtx[0].ToString());
blockReward = blockReward * 5;
}
isBlockRewardValueMet = (block.vtx[0].GetValueOut() <= blockReward);
if(!isBlockRewardValueMet) {
strErrorRet = strprintf("coinbase PAYS_TOO_MUCH at height %d (actual=%d vs limit=%d), exceeded block reward, and it is not a superblock",
nBlockHeight, block.vtx[0].GetValueOut(), blockReward);
}
return isBlockRewardValueMet;
}

bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward)
Expand Down Expand Up @@ -238,21 +207,33 @@ std::string GetRequiredPaymentsString(int nBlockHeight)
}

void CMasternodePayments::FillBloc(CMutableTransaction& txNew, int nBlockHeight, CAmount blockReward){
// This is where we pay the foundation Fee as of 2.4
//

if(Params().NetworkIDString() == CBaseChainParams::REGTEST) {
static const char* jijin[] = {
"ydZdAomNCF3y5oX45vY9g34attJv2RSenG",
};
CAmount found = GetFoundationPayment(nBlockHeight,0);
LogPrintf("CMasternodePayments::FilBloc -- StartFoundation: nBlockHeight=%d, amount=%s addres: %s\n", nBlockHeight, found,jijin[0]);
txNew.vout[0].nValue = txNew.vout[0].nValue - found;
int pos = 0;
LogPrint("mnpayments", "*********************** -- jijin address: %s\n",jijin[pos]);
CScript FOUNDER_19_SCRIPT = GetScriptForDestination(CBitcoinAddress(jijin[pos]).Get());
txNew.vout.push_back(CTxOut(found, CScript(FOUNDER_19_SCRIPT.begin(), FOUNDER_19_SCRIPT.end())));
} else {
static const char* jijin[] = {
"PHjJrmyDGCAjQFsbiucsC1Ex1nPbu8hgiC",
};
CAmount found = GetFoundationPayment(nBlockHeight,1);
LogPrintf("CMasternodePayments::FilBloc -- StartFoundation: nBlockHeight=%d, amount=%s addres: %s\n", nBlockHeight, found,jijin[0]);
txNew.vout[0].nValue = txNew.vout[0].nValue - found;
int pos = 0;
// LogPrint("mnpayments", "*********************** -- jijin address: %s\n",jijin[pos]);
CScript FOUNDER_19_SCRIPT = GetScriptForDestination(CBitcoinAddress(jijin[pos]).Get());
txNew.vout.push_back(CTxOut(found, CScript(FOUNDER_19_SCRIPT.begin(), FOUNDER_19_SCRIPT.end())));
}

if(nBlockHeight < FOUNDATION_HEIGHT)
{
return;
}

// CAmount found = FOUNDATION_RATE*GetBlockSubsidy(0,nBlockHeight-1,Params().GetConsensus(), false) / 100;
CAmount found = FOUNDATION;
txNew.vout[0].nValue = txNew.vout[0].nValue - found;


int pos = 0;
LogPrint("mnpayments", "*********************** -- jijin address: %s\n",jijin[pos]);
CScript FOUNDER_19_SCRIPT = GetScriptForDestination(CBitcoinAddress(jijin[pos]).Get());
txNew.vout.push_back(CTxOut(found, CScript(FOUNDER_19_SCRIPT.begin(), FOUNDER_19_SCRIPT.end())));
}

void CMasternodePayments::Clear()
Expand Down Expand Up @@ -294,7 +275,15 @@ void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, int nBlockH
masternode_info_t mnInfo;
if(!mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount, mnInfo)) {
// ...and we can't calculate it on our own
LogPrintf("CMasternodePayments::FillBlockPayee -- Failed to detect masternode to pay\n");
LogPrintf("CMasternodePayments::FillBlockPayee Height: %d -- Failed to detect masternode to pay\n",nBlockHeight);
// We need to take the MN share of the DevFee off the mining reward here, otherwise the payment budget will be exceeded
int nMainNet = 1;
if(Params().NetworkIDString() == CBaseChainParams::REGTEST) {
nMainNet = 0;
};
CAmount foundationPayment = GetFoundationPayment(nBlockHeight,nMainNet);
txNew.vout[0].nValue = blockReward - foundationPayment;
//
return;
}
// fill payee with locally calculated winner and hope for the best
Expand All @@ -303,18 +292,30 @@ void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, int nBlockH

// GET MASTERNODE PAYMENT VARIABLES SETUP
CAmount masternodePayment = GetMasternodePayment(nBlockHeight, blockReward);

// split reward between miner ...
txNew.vout[0].nValue -= masternodePayment;
// ... and masternode
int nMainNet = 1;
if(Params().NetworkIDString() == CBaseChainParams::REGTEST) {
nMainNet = 0;
};
CAmount foundationPayment = GetFoundationPayment(nBlockHeight,nMainNet);

// split reward between miner ... masternode .. and foundation

if (masternodePayment > 0) {
// masternodePayment -= foundationPayment/2; /* This is done in GetMasternodePayment now */
// txNew.vout[0].nValue = masternodePayment;
txNew.vout[0].nValue = blockReward - (masternodePayment + foundationPayment);
} else {
txNew.vout[0].nValue = blockReward - foundationPayment;
}
txoutMasternodeRet = CTxOut(masternodePayment, payee);
txNew.vout.push_back(txoutMasternodeRet);
// .. and foundation

CTxDestination address1;
ExtractDestination(payee, address1);
CBitcoinAddress address2(address1);

LogPrintf("CMasternodePayments::FillBlockPayee -- Masternode payment %lld to %s\n", masternodePayment, address2.ToString());
// LogPrintf("CMasternodePayments::FillBlockPayee -- Reward Calculation: nBlockHeight=%d, miner=%d MN=%d DevFee=%d\n", nBlockHeight, txNew.vout[0].nValue, masternodePayment, found);
LogPrintf("CMasternodePayments::FillBlockPayee -- Height: %d - Masternode / Mining /Foundation payment %lld / %lld / %lld to MN %s\n", nBlockHeight, masternodePayment, txNew.vout[0].nValue, foundationPayment, address2.ToString());
}

int CMasternodePayments::GetMinMasternodePaymentsProto() {
Expand Down
17 changes: 12 additions & 5 deletions src/masternode-payments.h
Expand Up @@ -18,11 +18,18 @@ class CMasternodeBlockPayees;

static const int MNPAYMENTS_SIGNATURES_REQUIRED = 6;
static const int MNPAYMENTS_SIGNATURES_TOTAL = 10;
static const char* jijin[] = {
"PTbZKW5hgUM5Cwn1UiHNx9QkYwchvbMueQ",
};

static const int FOUNDATION_HEIGHT = 129600;
/*
if(Params().NetworkIDString() == CBaseChainParams::REGTEST) {
static const char* jijin[] = {
"PEXdvFRuYY55CfLWHoE7fnsVf5eTfxJeBu",
}; } else {
static const char* jijin[] = {
"PEXdvFRuYY55CfLWHoE7fnsVf5eTfxJeBu",
}
*/


static const int FOUNDATION_HEIGHT = 129600; // This is when "Superblocks" started on PEPEPOW. They don't actually use the dash superblock capability.....
static const int64_t FOUNDATION_RATE = 0;
static const int64_t FOUNDATION = 1000 * COIN; // 1% to Foundation

Expand Down
8 changes: 6 additions & 2 deletions src/masternodeman.cpp
Expand Up @@ -528,8 +528,12 @@ bool CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight, bool f
int64_t seconds = (int64_t)(mnpair.second.lastPing.sigTime - mnpair.second.sigTime);
LogPrint("masternode", "CMasternodeMan::GetNextMasternodeInQueueForPayment --seconds=i", seconds);
if(seconds < CMasternodeMan::FIVE_DAY) {
LogPrint("masternode", "CMasternodeMan::GetNextMasternodeInQueueForPayment -- masternode: addr=%s, not yet mature\n", mnpair.second.addr.ToString());
continue;
if(Params().NetworkIDString() == CBaseChainParams::REGTEST) {
LogPrintf("Regtest so skipping MN age requirements\n");
} else {
LogPrint("masternode", "CMasternodeMan::GetNextMasternodeInQueueForPayment -- masternode: addr=%s, not yet mature\n", mnpair.second.addr.ToString());
continue;
}
}
LogPrint("masternode", "CMasternodeMan::GetNextMasternodeInQueueForPayment -- masternode: addr=%s, is mature\n", mnpair.second.addr.ToString());

Expand Down
11 changes: 11 additions & 0 deletions src/net_processing.cpp
Expand Up @@ -1157,6 +1157,17 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom->fDisconnect = true;
return false;
}
if (sporkManager.IsSporkActive(SPORK_15_REQUIRE_FOUNDATION_FEE)) {
if (nVersion < MIN_PEER_SPORK_15)
{
// disconnect from peers older than this proto version
LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, nVersion);
connman.PushMessageWithVersion(pfrom, INIT_PROTO_VERSION, NetMsgType::REJECT, strCommand, REJECT_OBSOLETE,
strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
pfrom->fDisconnect = true;
return false;
}
}

if (nVersion == 10300)
nVersion = 300;
Expand Down
46 changes: 34 additions & 12 deletions src/rpc/mining.cpp
Expand Up @@ -747,21 +747,43 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
// 2.2.1.6 25th August 2023 - Foztor
// Pools that use getblocktemplate get confused, we should have removed this as part of 2.2 anyway.
// Thanks to PinPin @zergpool for helping to find this.
//
// 2.4.1.0 Jan 2024 - Foztor
// We choose to re-introduce the Foundation Fee.....

// UniValue foundationArray(UniValue::VARR);
// int h = pindexPrev->nHeight+1;
// int pos = 0;

// CBitcoinAddress address2(jijin[pos]);
// CScript FOUNDER_19_1_SCRIPT = GetScriptForDestination(address2.Get());
// UniValue entry(UniValue::VOBJ);
// entry.push_back(Pair("payee", address2.ToString().c_str()));
// entry.push_back(Pair("script", HexStr(FOUNDER_19_1_SCRIPT.begin(), FOUNDER_19_1_SCRIPT.end())));
// entry.push_back(Pair("amount", FOUNDATION));
// foundationArray.push_back(entry);
UniValue foundationArray(UniValue::VARR);
int h = pindexPrev->nHeight+1;
int pos = 0;

static const char* jijin[] = {
"PHjJrmyDGCAjQFsbiucsC1Ex1nPbu8hgiC",
};
static const char* jijin2[] = {
"ydZdAomNCF3y5oX45vY9g34attJv2RSenG",
};

if(Params().NetworkIDString() == CBaseChainParams::REGTEST) {
CBitcoinAddress addressF(jijin2[pos]);
CScript FOUNDER_19_1_SCRIPT = GetScriptForDestination(addressF.Get());
CAmount foundationPayment = GetFoundationPayment(h,0);
UniValue entry(UniValue::VOBJ);
entry.push_back(Pair("payee", addressF.ToString().c_str()));
entry.push_back(Pair("script", HexStr(FOUNDER_19_1_SCRIPT.begin(), FOUNDER_19_1_SCRIPT.end())));
entry.push_back(Pair("amount", foundationPayment));
foundationArray.push_back(entry);
} else {
CBitcoinAddress addressF(jijin[pos]);
CScript FOUNDER_19_1_SCRIPT = GetScriptForDestination(addressF.Get());
CAmount foundationPayment = GetFoundationPayment(h,1);
UniValue entry(UniValue::VOBJ);
entry.push_back(Pair("payee", addressF.ToString().c_str()));
entry.push_back(Pair("script", HexStr(FOUNDER_19_1_SCRIPT.begin(), FOUNDER_19_1_SCRIPT.end())));
entry.push_back(Pair("amount", foundationPayment));
foundationArray.push_back(entry);
}


// result.push_back(Pair("foundation", foundationArray));
result.push_back(Pair("foundation", foundationArray));
// End of removal of foundation from getblocktemplate in 2.2.1.6

return result;
Expand Down

0 comments on commit 076f3a8

Please sign in to comment.