Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tx fee burn prototype #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/chainparams.cpp
Expand Up @@ -73,6 +73,7 @@ class CMainParams : public CChainParams {
consensus.CSVHeight = 419328; // 000000000000000004a1b34462cb8aeebd5799177f7a29cf28f2d1961716b5b5
consensus.SegwitHeight = 481824; // 0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893
consensus.MinBIP9WarningHeight = 483840; // segwit activation height + miner confirmation window
consensus.BurnFeeHeight = 749952;
consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
Expand Down Expand Up @@ -192,6 +193,7 @@ class CTestNetParams : public CChainParams {
consensus.CSVHeight = 770112; // 00000000025e930139bac5c6c31a403776da130831ab85be56578f3fa75369bb
consensus.SegwitHeight = 834624; // 00000000002b980fcd729daaa248fd9316a5200e9b367f4ff2c42453e84201ca
consensus.MinBIP9WarningHeight = 836640; // segwit activation height + miner confirmation window
consensus.BurnFeeHeight = 949536;
consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
Expand Down Expand Up @@ -337,6 +339,7 @@ class SigNetParams : public CChainParams {
consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
consensus.MinBIP9WarningHeight = 0;
consensus.BurnFeeHeight = 2016;
consensus.powLimit = uint256S("00000377ae000000000000000000000000000000000000000000000000000000");
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
Expand Down Expand Up @@ -399,6 +402,7 @@ class CRegTestParams : public CChainParams {
consensus.CSVHeight = 1; // Always active unless overridden
consensus.SegwitHeight = 1; // Always active unless overridden
consensus.MinBIP9WarningHeight = 0;
consensus.BurnFeeHeight = 2016;
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
Expand Down
1 change: 1 addition & 0 deletions src/consensus/params.h
Expand Up @@ -93,6 +93,7 @@ struct Params {
* (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments.
* Examples: 1916 for 95%, 1512 for testchains.
*/
int BurnFeeHeight;
uint32_t nRuleChangeActivationThreshold;
uint32_t nMinerConfirmationWindow;
BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS];
Expand Down
3 changes: 2 additions & 1 deletion src/miner.cpp
Expand Up @@ -160,7 +160,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
coinbaseTx.vin[0].prevout.SetNull();
coinbaseTx.vout.resize(1);
coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn;
coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
unsigned int burnFeeRate = GetBurnRate(pindexPrev, chainparams.GetConsensus());
coinbaseTx.vout[0].nValue = nFees*(100-burnFeeRate)/100 + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus());
Expand Down
49 changes: 49 additions & 0 deletions src/pow.cpp
Expand Up @@ -46,6 +46,55 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
}

unsigned int GetBurnRate(const CBlockIndex* pindexLast, const Consensus::Params& params)
{
assert(pindexLast != nullptr);
// return 0 for blocks befare hardfork
if ((pindexLast->nHeight+1)<params.BurnFeeHeight) {
return 0;
}

unsigned int minBurnFeeRate = 10;
unsigned int maxBurnFeeRate = 90;
unsigned int step=10;
unsigned int multiplicator=4;

if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() == 0) {
//return minBurnFeeRate at the start of new difficulty epoch
return minBurnFeeRate;
}

int nHeightFirst = (pindexLast->nHeight/params.DifficultyAdjustmentInterval())*params.DifficultyAdjustmentInterval();
assert(nHeightFirst >= 0);
const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
assert(pindexFirst);

if (params.fPowNoRetargeting)
return minBurnFeeRate;

int blocksToRetarget = params.DifficultyAdjustmentInterval() - pindexLast->nHeight % params.DifficultyAdjustmentInterval();

int64_t nActualTimespan = pindexLast->GetBlockTime() + blocksToRetarget*params.nPowTargetSpacing - pindexFirst->GetBlockTime();

if (nActualTimespan < params.nPowTargetTimespan/4)
nActualTimespan = params.nPowTargetTimespan/4;
if (nActualTimespan > params.nPowTargetTimespan*4)
nActualTimespan = params.nPowTargetTimespan*4;

if (nActualTimespan >= params.nPowTargetTimespan) {
//return minBurnFeeRate if current block time<= target
return minBurnFeeRate;
} else {
unsigned int burnFeeRate = 100*(params.nPowTargetTimespan-nActualTimespan)*multiplicator/params.nPowTargetTimespan;
burnFeeRate = burnFeeRate/step*step;
if (burnFeeRate<minBurnFeeRate)
burnFeeRate=minBurnFeeRate;
if (burnFeeRate>maxBurnFeeRate)
burnFeeRate=maxBurnFeeRate;
return burnFeeRate;
}
}

unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
if (params.fPowNoRetargeting)
Expand Down
1 change: 1 addition & 0 deletions src/pow.h
Expand Up @@ -15,6 +15,7 @@ class CBlockIndex;
class uint256;

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
unsigned int GetBurnRate(const CBlockIndex* pindexLast, const Consensus::Params&);
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&);

/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
Expand Down
3 changes: 2 additions & 1 deletion src/validation.cpp
Expand Up @@ -1902,7 +1902,8 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
LogPrint(BCLog::BENCH, " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (unsigned)block.vtx.size(), MILLI * (nTime3 - nTime2), MILLI * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * MICRO, nTimeConnect * MILLI / nBlocksTotal);

CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, m_params.GetConsensus());
unsigned int burnFeeRate = GetBurnRate(pindex, m_params.GetConsensus());
CAmount blockReward = nFees*(100-burnFeeRate)/100 + GetBlockSubsidy(pindex->nHeight, m_params.GetConsensus());
if (block.vtx[0]->GetValueOut() > blockReward) {
LogPrintf("ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.vtx[0]->GetValueOut(), blockReward);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-amount");
Expand Down