Browse Source

Founders reward: changed index computation, added new test and some refactoring.

pull/4/head
Simon 8 years ago
parent
commit
3b30d8361a
  1. 14
      src/chainparams.cpp
  2. 5
      src/chainparams.h
  3. 78
      src/gtest/test_foundersreward.cpp
  4. 2
      src/main.cpp
  5. 2
      src/miner.cpp

14
src/chainparams.cpp

@ -341,25 +341,31 @@ bool SelectParamsFromCommandLine()
// Block height must be >0 and <=last founders reward block height
// 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();
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];
}
// Block height must be >0 and <=last founders reward block height
// 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());
CBitcoinAddress address(GetFoundersRewardAddress(nHeight).c_str());
CBitcoinAddress address(GetFoundersRewardAddressAtHeight(nHeight).c_str());
assert(address.IsValid());
assert(address.IsScript());
CScriptID scriptID = get<CScriptID>(address.Get()); // Get() returns a boost variant
CScript script = CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
return script;
}
std::string CChainParams::GetFoundersRewardAddressAtIndex(int i) const {
assert(i>=0 && i<vFoundersRewardAddress.size());
return vFoundersRewardAddress[i];
}

5
src/chainparams.h

@ -78,8 +78,9 @@ public:
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
const Checkpoints::CCheckpointData& Checkpoints() const { return checkpointData; }
/** Return the founder's reward address and script for a given block height */
std::string GetFoundersRewardAddress(int height) const;
CScript GetFoundersRewardScript(int height) const;
std::string GetFoundersRewardAddressAtHeight(int height) const;
CScript GetFoundersRewardScriptAtHeight(int height) const;
std::string GetFoundersRewardAddressAtIndex(int i) const;
protected:
CChainParams() {}

78
src/gtest/test_foundersreward.cpp

@ -69,9 +69,17 @@ TEST(founders_reward_test, create_testnet_2of3multisig) {
#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);
CChainParams params = Params();
@ -79,24 +87,16 @@ TEST(founders_reward_test, testnet) {
// For Testnet, the first address is derived from the old script.
// FOUNDERS_REWARD_SCRIPT = a9146708e6670db0b950dac68031025cc5b63213a49187
// address = 2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4
EXPECT_EQ(params.GetFoundersRewardScript(1), ParseHex("a9146708e6670db0b950dac68031025cc5b63213a49187"));
EXPECT_EQ(params.GetFoundersRewardAddress(1), "2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4");
EXPECT_EQ(params.GetFoundersRewardScriptAtHeight(1), ParseHex("a9146708e6670db0b950dac68031025cc5b63213a49187"));
EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(1), "2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4");
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
// If the block height parameter is out of bounds, there is an assert.
EXPECT_DEATH(params.GetFoundersRewardScript(0), "nHeight");
EXPECT_DEATH(params.GetFoundersRewardScript(maxHeight+1), "nHeight");
EXPECT_DEATH(params.GetFoundersRewardAddress(0), "nHeight");
EXPECT_DEATH(params.GetFoundersRewardAddress(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);
EXPECT_DEATH(params.GetFoundersRewardScriptAtHeight(0), "nHeight");
EXPECT_DEATH(params.GetFoundersRewardScriptAtHeight(maxHeight+1), "nHeight");
EXPECT_DEATH(params.GetFoundersRewardAddressAtHeight(0), "nHeight");
EXPECT_DEATH(params.GetFoundersRewardAddressAtHeight(maxHeight+1), "nHeight");
}
@ -107,11 +107,18 @@ TEST(founders_reward_test, mainnet) {
CChainParams params = Params();
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
std::set<std::string> addresses;
for (int i=1; i<=maxHeight; i++) {
addresses.insert(params.GetFoundersRewardAddress(i));
}
ASSERT_TRUE(addresses.size()==NUM_MAINNET_FOUNDER_ADDRESSES);
checkNumberOfUniqueAddresses(maxHeight, 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);
}
@ -120,13 +127,9 @@ TEST(founders_reward_test, mainnet) {
TEST(founders_reward_test, regtest) {
SelectParams(CBaseChainParams::REGTEST);
CChainParams params = Params();
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
std::set<std::string> addresses;
for (int i=1; i<=maxHeight; i++) {
addresses.insert(params.GetFoundersRewardAddress(i));
}
ASSERT_TRUE(addresses.size()==NUM_REGTEST_FOUNDER_ADDRESSES);
checkNumberOfUniqueAddresses(maxHeight, NUM_REGTEST_FOUNDER_ADDRESSES);
}
@ -146,3 +149,24 @@ TEST(founders_reward_test, slow_start_subsidy) {
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);
}

2
src/main.cpp

@ -3090,7 +3090,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
bool found = false;
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)) {
found = true;
break;

2
src/miner.cpp

@ -342,7 +342,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
txNew.vout[0].nValue -= vFoundersReward;
// 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

Loading…
Cancel
Save