forked from dogecoin/dogecoin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdogecoin.cpp
151 lines (124 loc) · 5.5 KB
/
dogecoin.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright (c) 2015-2022 The Dogecoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <boost/random/uniform_int.hpp>
#include <boost/random/mersenne_twister.hpp>
#include "policy/policy.h"
#include "arith_uint256.h"
#include "dogecoin.h"
#include "txmempool.h"
#include "util.h"
#include "validation.h"
#include "dogecoin-fees.h"
int static generateMTRandom(unsigned int s, int range)
{
boost::mt19937 gen(s);
boost::uniform_int<> dist(1, range);
return dist(gen);
}
// Dogecoin: Normally minimum difficulty blocks can only occur in between
// retarget blocks. However, once we introduce Digishield every block is
// a retarget, so we need to handle minimum difficulty on all blocks.
bool AllowDigishieldMinDifficultyForBlock(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
{
// check if the chain allows minimum difficulty blocks
if (!params.fPowAllowMinDifficultyBlocks)
return false;
// check if the chain allows minimum difficulty blocks on recalc blocks
if (pindexLast->nHeight < 157500)
// if (!params.fPowAllowDigishieldMinDifficultyBlocks)
return false;
// Allow for a minimum block time if the elapsed time > 2*nTargetSpacing
return (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2);
}
unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
int nHeight = pindexLast->nHeight + 1;
const int64_t retargetTimespan = params.nPowTargetTimespan;
const int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
int64_t nModulatedTimespan = nActualTimespan;
int64_t nMaxTimespan;
int64_t nMinTimespan;
if (params.fDigishieldDifficultyCalculation) //DigiShield implementation - thanks to RealSolid & WDC for this code
{
// amplitude filter - thanks to daft27 for this code
nModulatedTimespan = retargetTimespan + (nModulatedTimespan - retargetTimespan) / 8;
nMinTimespan = retargetTimespan - (retargetTimespan / 4);
nMaxTimespan = retargetTimespan + (retargetTimespan / 2);
} else if (nHeight > 10000) {
nMinTimespan = retargetTimespan / 4;
nMaxTimespan = retargetTimespan * 4;
} else if (nHeight > 5000) {
nMinTimespan = retargetTimespan / 8;
nMaxTimespan = retargetTimespan * 4;
} else {
nMinTimespan = retargetTimespan / 16;
nMaxTimespan = retargetTimespan * 4;
}
// Limit adjustment step
if (nModulatedTimespan < nMinTimespan)
nModulatedTimespan = nMinTimespan;
else if (nModulatedTimespan > nMaxTimespan)
nModulatedTimespan = nMaxTimespan;
// Retarget
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
arith_uint256 bnNew;
arith_uint256 bnOld;
bnNew.SetCompact(pindexLast->nBits);
bnOld = bnNew;
bnNew *= nModulatedTimespan;
bnNew /= retargetTimespan;
if (bnNew > bnPowLimit)
bnNew = bnPowLimit;
return bnNew.GetCompact();
}
bool CheckAuxPowProofOfWork(const CBlockHeader& block, const Consensus::Params& params)
{
/* Except for legacy blocks with full version 1, ensure that
the chain ID is correct. Legacy blocks are not allowed since
the merge-mining start, which is checked in AcceptBlockHeader
where the height is known. */
if (!block.IsLegacy() && params.fStrictChainId && block.GetChainId() != params.nAuxpowChainId)
return error("%s : block does not have our chain ID"
" (got %d, expected %d, full nVersion %d)",
__func__, block.GetChainId(),
params.nAuxpowChainId, block.nVersion);
/* If there is no auxpow, just check the block hash. */
if (!block.auxpow) {
if (block.IsAuxpow())
return error("%s : no auxpow on block with auxpow version",
__func__);
if (!CheckProofOfWork(block.GetPoWHash(), block.nBits, params))
return error("%s : non-AUX proof of work failed", __func__);
return true;
}
/* We have auxpow. Check it. */
if (!block.IsAuxpow())
return error("%s : auxpow on block with non-auxpow version", __func__);
if (!CheckProofOfWork(block.auxpow->getParentBlockPoWHash(), block.nBits, params))
return error("%s : AUX proof of work failed", __func__);
if (!block.auxpow->check(block.GetHash(), block.GetChainId(), params))
return error("%s : AUX POW is not valid", __func__);
return true;
}
CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusParams, uint256 prevHash)
{
int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
if (!consensusParams.fSimplifiedRewards)
{
// Old-style rewards derived from the previous block hash
const std::string cseed_str = prevHash.ToString().substr(7, 7);
const char* cseed = cseed_str.c_str();
char* endp = NULL;
long seed = strtol(cseed, &endp, 16);
CAmount maxReward = (1000000 >> halvings) - 1;
int rand = generateMTRandom(seed, maxReward);
return (1 + rand) * COIN;
} else if (nHeight < (6 * consensusParams.nSubsidyHalvingInterval)) {
// New-style constant rewards for each halving interval
return (500000 * COIN) >> halvings;
} else {
// Constant inflation
return 10000 * COIN;
}
}