Founders reward: changed index computation, added new test and some refactoring.
This commit is contained in:
@@ -341,25 +341,31 @@ bool SelectParamsFromCommandLine()
|
|||||||
|
|
||||||
// Block height must be >0 and <=last founders reward block height
|
// Block height must be >0 and <=last founders reward block height
|
||||||
// Index variable i ranges from 0 - (vFoundersRewardAddress.size()-1)
|
// Index variable i ranges from 0 - (vFoundersRewardAddress.size()-1)
|
||||||
std::string CChainParams::GetFoundersRewardAddress(int nHeight) const
|
std::string CChainParams::GetFoundersRewardAddressAtHeight(int nHeight) const
|
||||||
{
|
{
|
||||||
int maxHeight = consensus.GetLastFoundersRewardBlockHeight();
|
int maxHeight = consensus.GetLastFoundersRewardBlockHeight();
|
||||||
assert(nHeight>0 && nHeight<=maxHeight);
|
assert(nHeight>0 && nHeight<=maxHeight);
|
||||||
|
|
||||||
size_t i = (size_t)floor((double(nHeight-1)/maxHeight)*vFoundersRewardAddress.size());
|
size_t addressChangeInterval = (maxHeight + vFoundersRewardAddress.size()) / vFoundersRewardAddress.size();
|
||||||
|
size_t i = nHeight / addressChangeInterval;
|
||||||
return vFoundersRewardAddress[i];
|
return vFoundersRewardAddress[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block height must be >0 and <=last founders reward block height
|
// Block height must be >0 and <=last founders reward block height
|
||||||
// The founders reward address is expected to be a multisig (P2SH) address
|
// The founders reward address is expected to be a multisig (P2SH) address
|
||||||
CScript CChainParams::GetFoundersRewardScript(int nHeight) const
|
CScript CChainParams::GetFoundersRewardScriptAtHeight(int nHeight) const
|
||||||
{
|
{
|
||||||
assert(nHeight > 0 && nHeight <= consensus.GetLastFoundersRewardBlockHeight());
|
assert(nHeight > 0 && nHeight <= consensus.GetLastFoundersRewardBlockHeight());
|
||||||
|
|
||||||
CBitcoinAddress address(GetFoundersRewardAddress(nHeight).c_str());
|
CBitcoinAddress address(GetFoundersRewardAddressAtHeight(nHeight).c_str());
|
||||||
assert(address.IsValid());
|
assert(address.IsValid());
|
||||||
assert(address.IsScript());
|
assert(address.IsScript());
|
||||||
CScriptID scriptID = get<CScriptID>(address.Get()); // Get() returns a boost variant
|
CScriptID scriptID = get<CScriptID>(address.Get()); // Get() returns a boost variant
|
||||||
CScript script = CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
|
CScript script = CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CChainParams::GetFoundersRewardAddressAtIndex(int i) const {
|
||||||
|
assert(i>=0 && i<vFoundersRewardAddress.size());
|
||||||
|
return vFoundersRewardAddress[i];
|
||||||
|
}
|
||||||
|
|||||||
@@ -78,8 +78,9 @@ public:
|
|||||||
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
|
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
|
||||||
const Checkpoints::CCheckpointData& Checkpoints() const { return checkpointData; }
|
const Checkpoints::CCheckpointData& Checkpoints() const { return checkpointData; }
|
||||||
/** Return the founder's reward address and script for a given block height */
|
/** Return the founder's reward address and script for a given block height */
|
||||||
std::string GetFoundersRewardAddress(int height) const;
|
std::string GetFoundersRewardAddressAtHeight(int height) const;
|
||||||
CScript GetFoundersRewardScript(int height) const;
|
CScript GetFoundersRewardScriptAtHeight(int height) const;
|
||||||
|
std::string GetFoundersRewardAddressAtIndex(int i) const;
|
||||||
protected:
|
protected:
|
||||||
CChainParams() {}
|
CChainParams() {}
|
||||||
|
|
||||||
|
|||||||
@@ -69,9 +69,17 @@ TEST(founders_reward_test, create_testnet_2of3multisig) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define NUM_TESTNET_FOUNDER_ADDRESSES 48
|
// Utility method to check the number of unique addresses from height 1 to maxHeight
|
||||||
|
void checkNumberOfUniqueAddresses(int maxHeight, int nUnique) {
|
||||||
|
std::set<std::string> addresses;
|
||||||
|
for (int i=1; i<=maxHeight; i++) {
|
||||||
|
addresses.insert(Params().GetFoundersRewardAddressAtHeight(i));
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(addresses.size()==nUnique);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(founders_reward_test, testnet) {
|
|
||||||
|
TEST(founders_reward_test, general) {
|
||||||
SelectParams(CBaseChainParams::TESTNET);
|
SelectParams(CBaseChainParams::TESTNET);
|
||||||
|
|
||||||
CChainParams params = Params();
|
CChainParams params = Params();
|
||||||
@@ -79,24 +87,16 @@ TEST(founders_reward_test, testnet) {
|
|||||||
// For Testnet, the first address is derived from the old script.
|
// For Testnet, the first address is derived from the old script.
|
||||||
// FOUNDERS_REWARD_SCRIPT = a9146708e6670db0b950dac68031025cc5b63213a49187
|
// FOUNDERS_REWARD_SCRIPT = a9146708e6670db0b950dac68031025cc5b63213a49187
|
||||||
// address = 2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4
|
// address = 2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4
|
||||||
EXPECT_EQ(params.GetFoundersRewardScript(1), ParseHex("a9146708e6670db0b950dac68031025cc5b63213a49187"));
|
EXPECT_EQ(params.GetFoundersRewardScriptAtHeight(1), ParseHex("a9146708e6670db0b950dac68031025cc5b63213a49187"));
|
||||||
EXPECT_EQ(params.GetFoundersRewardAddress(1), "2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4");
|
EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(1), "2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4");
|
||||||
|
|
||||||
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
|
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
|
||||||
|
|
||||||
// If the block height parameter is out of bounds, there is an assert.
|
// If the block height parameter is out of bounds, there is an assert.
|
||||||
EXPECT_DEATH(params.GetFoundersRewardScript(0), "nHeight");
|
EXPECT_DEATH(params.GetFoundersRewardScriptAtHeight(0), "nHeight");
|
||||||
EXPECT_DEATH(params.GetFoundersRewardScript(maxHeight+1), "nHeight");
|
EXPECT_DEATH(params.GetFoundersRewardScriptAtHeight(maxHeight+1), "nHeight");
|
||||||
EXPECT_DEATH(params.GetFoundersRewardAddress(0), "nHeight");
|
EXPECT_DEATH(params.GetFoundersRewardAddressAtHeight(0), "nHeight");
|
||||||
EXPECT_DEATH(params.GetFoundersRewardAddress(maxHeight+1), "nHeight");
|
EXPECT_DEATH(params.GetFoundersRewardAddressAtHeight(maxHeight+1), "nHeight");
|
||||||
|
|
||||||
// Check that different addresses are used for testnet
|
|
||||||
std::set<std::string> addresses;
|
|
||||||
for (int i=1; i<=maxHeight; i++) {
|
|
||||||
addresses.insert(params.GetFoundersRewardAddress(i));
|
|
||||||
}
|
|
||||||
ASSERT_TRUE(addresses.size()==NUM_TESTNET_FOUNDER_ADDRESSES);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -107,11 +107,18 @@ TEST(founders_reward_test, mainnet) {
|
|||||||
CChainParams params = Params();
|
CChainParams params = Params();
|
||||||
|
|
||||||
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
|
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
|
||||||
std::set<std::string> addresses;
|
checkNumberOfUniqueAddresses(maxHeight, NUM_MAINNET_FOUNDER_ADDRESSES);
|
||||||
for (int i=1; i<=maxHeight; i++) {
|
}
|
||||||
addresses.insert(params.GetFoundersRewardAddress(i));
|
|
||||||
}
|
|
||||||
ASSERT_TRUE(addresses.size()==NUM_MAINNET_FOUNDER_ADDRESSES);
|
#define NUM_TESTNET_FOUNDER_ADDRESSES 48
|
||||||
|
|
||||||
|
TEST(founders_reward_test, testnet) {
|
||||||
|
SelectParams(CBaseChainParams::TESTNET);
|
||||||
|
CChainParams params = Params();
|
||||||
|
|
||||||
|
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
|
||||||
|
checkNumberOfUniqueAddresses(maxHeight, NUM_TESTNET_FOUNDER_ADDRESSES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -122,11 +129,7 @@ TEST(founders_reward_test, regtest) {
|
|||||||
CChainParams params = Params();
|
CChainParams params = Params();
|
||||||
|
|
||||||
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
|
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
|
||||||
std::set<std::string> addresses;
|
checkNumberOfUniqueAddresses(maxHeight, NUM_REGTEST_FOUNDER_ADDRESSES);
|
||||||
for (int i=1; i<=maxHeight; i++) {
|
|
||||||
addresses.insert(params.GetFoundersRewardAddress(i));
|
|
||||||
}
|
|
||||||
ASSERT_TRUE(addresses.size()==NUM_REGTEST_FOUNDER_ADDRESSES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -146,3 +149,24 @@ TEST(founders_reward_test, slow_start_subsidy) {
|
|||||||
|
|
||||||
ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0);
|
ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Verify the number of rewards going to each mainnet/testnet address
|
||||||
|
TEST(founders_reward_test, per_address_reward) {
|
||||||
|
SelectParams(CBaseChainParams::TESTNET);
|
||||||
|
CChainParams params = Params();
|
||||||
|
|
||||||
|
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
|
||||||
|
std::multiset<std::string> ms;
|
||||||
|
for (int nHeight=1; nHeight<=maxHeight; nHeight++) {
|
||||||
|
ms.insert(params.GetFoundersRewardAddressAtHeight(nHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(0)) == 17708);
|
||||||
|
for (int i = 1; i <= 46; i++) {
|
||||||
|
ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(i)) == 17709);
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(47)) == 17677);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3090,7 +3090,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
BOOST_FOREACH(const CTxOut& output, block.vtx[0].vout) {
|
BOOST_FOREACH(const CTxOut& output, block.vtx[0].vout) {
|
||||||
if (output.scriptPubKey == Params().GetFoundersRewardScript(nHeight)) {
|
if (output.scriptPubKey == Params().GetFoundersRewardScriptAtHeight(nHeight)) {
|
||||||
if (output.nValue == (GetBlockSubsidy(nHeight, consensusParams) / 5)) {
|
if (output.nValue == (GetBlockSubsidy(nHeight, consensusParams) / 5)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
|||||||
txNew.vout[0].nValue -= vFoundersReward;
|
txNew.vout[0].nValue -= vFoundersReward;
|
||||||
|
|
||||||
// And give it to the founders
|
// And give it to the founders
|
||||||
txNew.vout.push_back(CTxOut(vFoundersReward, chainparams.GetFoundersRewardScript(nHeight)));
|
txNew.vout.push_back(CTxOut(vFoundersReward, chainparams.GetFoundersRewardScriptAtHeight(nHeight)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add fees
|
// Add fees
|
||||||
|
|||||||
Reference in New Issue
Block a user