Skip to content

Commit

Permalink
Founders reward: changed index computation, added new test and some r…
Browse files Browse the repository at this point in the history
…efactoring.
  • Loading branch information
bitcartel committed Sep 30, 2016
1 parent db0f931 commit 3b30d83
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 35 deletions.
14 changes: 10 additions & 4 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 3 additions & 2 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ class CChainParams
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() {}

Expand Down
78 changes: 51 additions & 27 deletions src/gtest/test_foundersreward.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,34 +69,34 @@ 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();

// 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");
}


Expand All @@ -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);
}


Expand All @@ -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);
}


Expand All @@ -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 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 3b30d83

Please sign in to comment.