From db0f931570792f3f05f01466ec437509dfcdf37f Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 21 Sep 2016 12:02:36 -0700 Subject: [PATCH 01/11] Add founders reward to ChainParams. Fix bug where subsidy slow shift was ignored. --- src/Makefile.gtest.include | 1 + src/chainparams.cpp | 65 +++++++++++++ src/chainparams.h | 4 + src/consensus/params.h | 3 + src/gtest/test_foundersreward.cpp | 148 ++++++++++++++++++++++++++++++ src/main.cpp | 4 +- src/main.h | 3 - src/miner.cpp | 7 +- src/rpcmining.cpp | 2 +- 9 files changed, 226 insertions(+), 11 deletions(-) create mode 100644 src/gtest/test_foundersreward.cpp diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index bd6bae83..ded51685 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -5,6 +5,7 @@ bin_PROGRAMS += zcash-gtest zcash_gtest_SOURCES = \ gtest/main.cpp \ gtest/json_test_vectors.cpp \ + gtest/test_foundersreward.cpp \ gtest/test_jsonspirit.cpp \ gtest/test_tautology.cpp \ gtest/test_checktransaction.cpp \ diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 04497b6b..94813a0c 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -13,6 +13,8 @@ #include +#include "base58.h" + using namespace std; #include "chainparamsseeds.h" @@ -138,6 +140,23 @@ public: // (the tx=... number in the SetBestChain debug.log lines) 0 // * estimated number of transactions per day after checkpoint }; + + // Founders reward script expects a vector of 2-of-3 multisig addresses + vFoundersRewardAddress = { + "ADDRESS1", "ADDRESS2", "ADDRESS3", "ADDRESS4", + "ADDRESS5", "ADDRESS6", "ADDRESS7", "ADDRESS8", + "ADDRESS9", "ADDRESS10", "ADDRESS11", "ADDRESS12", + "ADDRESS13", "ADDRESS14", "ADDRESS15", "ADDRESS16", + "ADDRESS17", "ADDRESS18", "ADDRESS19", "ADDRESS20", + "ADDRESS21", "ADDRESS22", "ADDRESS23", "ADDRESS24", + "ADDRESS25", "ADDRESS26", "ADDRESS27", "ADDRESS28", + "ADDRESS29", "ADDRESS30", "ADDRESS31", "ADDRESS32", + "ADDRESS33", "ADDRESS34", "ADDRESS35", "ADDRESS36", + "ADDRESS37", "ADDRESS38", "ADDRESS39", "ADDRESS40", + "ADDRESS41", "ADDRESS42", "ADDRESS43", "ADDRESS44", + "ADDRESS45", "ADDRESS46", "ADDRESS47", "ADDRESS48", + }; + assert(vFoundersRewardAddress.size() < consensus.nSubsidyHalvingInterval + consensus.SubsidySlowStartShift()); } }; static CMainParams mainParams; @@ -202,6 +221,22 @@ public: 0 }; + // Founders reward script expects a vector of 2-of-3 multisig addresses + vFoundersRewardAddress = { + "2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4", "2NBW8WsA2jUussoJbRv82UXH1BYopkjYqcd", "2N1MudZmwDFTcYiLCZfrcsnhHwaSTTigbcN", "2MxfUJXWKz9D8X3mcMpVcdEJKdJ6zFukca9", + "2N8iUwMCpU16VYpKQ1HRM6xfut5FZwGwieM", "2N9hyafTvJVrykBvZDw79j1brozwZNySwPP", "2NFx7tRozsp3kT1M4w4tL9FfnEj8RovzbzN", "2NAqoH96V1RtmK72LEZpJNX1uxhJ5yejRiK", + "2MyV7hoV28KS8Uam2Z8nzY3xeo7R3T3TLUr", "2N8Tn19hMoCD4EmCwpg1V8qupVkQLVVPhav", "2NA5UeJU9zAQkSMyy3xpDcjfp4CEyKfzXKp", "2NBERNyXy46CfM9yewGeof4yzC3vkwYnhgS", + "2N7fnpAswHb4mnPm2ZjWX3eKkF8hABAYBtQ", "2N9MXGsz7uYaY5ciax6tSMDG7sjZUoLhJTC", "2N5PwzPQFFmLut2XWGQWAmpwKsF8VzUoPtr", "2MvZdDpNP8hWyEqg6zKW9B62YTJqcUwjHr5", + "2Mx4KfKJ37EDc3A43Frzof1iEjSe91JUX7d", "2NBMSdXjZ7YqREmwxEtgGryY59KBpqMSs1d", "2N9RbfE4ZCJ3Nx68vPfmvH2M6Q3qicJhagb", "2N4xwfFkFj4DR4NWNbynzP2aJmVcEFnA2DB", + "2Mx4TyAwedmsRuDkvMNYGqrcCZfQTfCvxAp", "2Mx4HSVsxEqXjLxn8igJzmCrFdG9XhnNvtf", "2MtLM4SP7LJbBZ5rA5ZG8kAVz9UNrNKuoFB", "2N7SPq83Cbmwuwv5rjNBzVd9QtJKAxxKj8M", + "2MwYkbE4U4p9XBsCrupDDkdcDH9L9xvc9Bn", "2MyaeCHpVmckokUi67YP1QK9L3Dkx3Pt86F", "2N7URNgBPXGjqnuPHiynCa6qMMhKm6YEaHr", "2N2eNwGVwj4WwbEdJg7YZDgrnYvDv1ZSNbB", + "2MuWAG6BqLM1mtZc67Fv1aKgGwkNQ2akDGt", "2N7XH82MbGwpzbc7PM2aK5CU14bSJvK7Etz", "2MuPX8Ke5TvDDQ1nkqpaPMgYWPyWbFp18Jn", "2NFBST7oK9yw9PaXaq5QhdyYwp5HpHz9m81", + "2MuSeMBUrttbjvDZAeQjTrrDeoP197qj2kG", "2N6JU8JNGGAUFknTCuLSuDEEhZJqMfFsH88", "2N4P2MrwtwbiHymQm1RASoVoiH3sFrBpmXa", "2MyhFiVXvVVxUNc8Qh9ppV7jG4NsKpnxige", + "2N5dLXUho2GtjuHMWuqixLrHLCwUMcYxd7s", "2N9NhfSiYBt3fhETFR6mQc3uxreEy7simSg", "2NBEEWPY3v38uuC7n1tMtviEY7ND2XzfgSG", "2NCWWj6oREJiMmfJ2bV5sbm1xchMwQfAZ5r", + "2N4ACsVCKMvJmtEb3Pd3xkqhJ3rLT4mYx1r", "2MtmMdabcwRJmenswaYtWA675df854KhUxD", "2N2h27Dd87eiGcm7ajvu4hJpXjTm9GkzvLZ", "2NGE19agRXU1EAK3PCLZWXERkpqyUexhk9r", + "2N63112wMnBsXTaBFjbCTjW9LuyTXQmvEdw", "2NBkHxgkYZbU56zsoLNsP5WZVfMtBK6X8WK", "2N5pK7NfKo6d9qBmsKggpwuvQeMxGf65SLH", "2N5jHzgCg9a9uAcLaT2jij8WKTZzWbVNC5c", + }; + assert(vFoundersRewardAddress.size() < consensus.nSubsidyHalvingInterval + consensus.SubsidySlowStartShift()); } }; static CTestNetParams testNetParams; @@ -259,6 +294,10 @@ public: 0, 0 }; + + // Founders reward script expects a vector of 2-of-3 multisig addresses + vFoundersRewardAddress = { "2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4" }; + assert(vFoundersRewardAddress.size() < consensus.nSubsidyHalvingInterval + consensus.SubsidySlowStartShift()); } }; static CRegTestParams regTestParams; @@ -298,3 +337,29 @@ bool SelectParamsFromCommandLine() SelectParams(network); return true; } + + +// 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 +{ + int maxHeight = consensus.GetLastFoundersRewardBlockHeight(); + assert(nHeight>0 && nHeight<=maxHeight); + + size_t i = (size_t)floor((double(nHeight-1)/maxHeight)*vFoundersRewardAddress.size()); + 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 +{ + assert(nHeight > 0 && nHeight <= consensus.GetLastFoundersRewardBlockHeight()); + + CBitcoinAddress address(GetFoundersRewardAddress(nHeight).c_str()); + assert(address.IsValid()); + assert(address.IsScript()); + CScriptID scriptID = get(address.Get()); // Get() returns a boost variant + CScript script = CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; + return script; +} diff --git a/src/chainparams.h b/src/chainparams.h index de89fa0e..28d08a14 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -77,6 +77,9 @@ public: const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } const std::vector& 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; protected: CChainParams() {} @@ -102,6 +105,7 @@ protected: bool fMineBlocksOnDemand; bool fTestnetToBeDeprecatedFieldRPC; Checkpoints::CCheckpointData checkpointData; + std::vector vFoundersRewardAddress; }; /** diff --git a/src/consensus/params.h b/src/consensus/params.h index 5d951eef..d3e6462b 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -32,6 +32,9 @@ struct Params { */ int SubsidySlowStartShift() const { return nSubsidySlowStartInterval / 2; } int nSubsidyHalvingInterval; + int GetLastFoundersRewardBlockHeight() const { + return nSubsidyHalvingInterval + SubsidySlowStartShift() - 1; + } /** Used to check majorities for block version upgrade */ int nMajorityEnforceBlockUpgrade; int nMajorityRejectBlockOutdated; diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp new file mode 100644 index 00000000..01a72d84 --- /dev/null +++ b/src/gtest/test_foundersreward.cpp @@ -0,0 +1,148 @@ +#include + +#include "main.h" +#include "utilmoneystr.h" +#include "chainparams.h" +#include "utilstrencodings.h" +#include "zcash/Address.hpp" +#include "wallet/wallet.h" +#include "amount.h" +#include +#include +#include +#include +#include + +// To run tests: +// ./zcash-gtest --gtest_filter="founders_reward_test.*" + +// +// Enable this test to generate and print 48 testnet 2-of-3 multisig addresses. +// The output can be copied into chainparams.cpp. +// +#if 0 +TEST(founders_reward_test, create_testnet_2of3multisig) { + ECC_Start(); + SelectParams(CBaseChainParams::TESTNET); + boost::filesystem::path temp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); + const std::string path = temp.native(); + bool fFirstRun; + auto pWallet = std::make_shared(path); + ASSERT_EQ(DB_LOAD_OK, pWallet->LoadWallet(fFirstRun)); + pWallet->TopUpKeyPool(); + + int numKeys = 48; + std::vector pubkeys; + pubkeys.resize(3); + CPubKey newKey; + std::vector addresses; + for (int i=0; iGetKeyFromPool(newKey)); + pubkeys[0] = newKey; + ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); + pubkeys[1] = newKey; + ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); + pubkeys[2] = newKey; + CScript result = GetScriptForMultisig(2, pubkeys); + ASSERT_FALSE(result.size() > MAX_SCRIPT_ELEMENT_SIZE); + CScriptID innerID(result); + std::string address = CBitcoinAddress(innerID).ToString(); + addresses.push_back(address); + } + + // Print out the addresses, 4 on each line. + std::string s = "vFoundersRewardAddress = {\n"; + int i=0; + int colsPerRow = 4; + ASSERT_TRUE(numKeys % colsPerRow == 0); + int numRows = numKeys/colsPerRow; + for (int row=0; row addresses; + for (int i=1; i<=maxHeight; i++) { + addresses.insert(params.GetFoundersRewardAddress(i)); + } + ASSERT_TRUE(addresses.size()==NUM_TESTNET_FOUNDER_ADDRESSES); + +} + + +#define NUM_MAINNET_FOUNDER_ADDRESSES 48 + +TEST(founders_reward_test, mainnet) { + SelectParams(CBaseChainParams::MAIN); + CChainParams params = Params(); + + int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); + std::set addresses; + for (int i=1; i<=maxHeight; i++) { + addresses.insert(params.GetFoundersRewardAddress(i)); + } + ASSERT_TRUE(addresses.size()==NUM_MAINNET_FOUNDER_ADDRESSES); +} + + +#define NUM_REGTEST_FOUNDER_ADDRESSES 1 + +TEST(founders_reward_test, regtest) { + SelectParams(CBaseChainParams::REGTEST); + CChainParams params = Params(); + + int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); + std::set addresses; + for (int i=1; i<=maxHeight; i++) { + addresses.insert(params.GetFoundersRewardAddress(i)); + } + ASSERT_TRUE(addresses.size()==NUM_REGTEST_FOUNDER_ADDRESSES); +} + + + +// Test that 10% founders reward is fully rewarded after the first halving and slow start shift. +// On Mainnet, this would be 2,100,000 ZEC after 850,000 blocks (840,000 + 10,000). +TEST(founders_reward_test, slow_start_subsidy) { + SelectParams(CBaseChainParams::MAIN); + CChainParams params = Params(); + + int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); + CAmount totalSubsidy = 0; + for (int nHeight=1; nHeight<=maxHeight; nHeight++) { + CAmount nSubsidy = GetBlockSubsidy(nHeight, params.GetConsensus())/ 5; + totalSubsidy += nSubsidy; + } + + ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0); +} diff --git a/src/main.cpp b/src/main.cpp index d0321ff6..c6b1f1fc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3086,11 +3086,11 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn // Coinbase transaction must include an output sending 20% of // the block reward to `FOUNDERS_REWARD_SCRIPT` until the first // subsidy halving block, with exception to the genesis block. - if ((nHeight > 0) && (nHeight < consensusParams.nSubsidyHalvingInterval)) { + if ((nHeight > 0) && (nHeight <= consensusParams.GetLastFoundersRewardBlockHeight())) { bool found = false; BOOST_FOREACH(const CTxOut& output, block.vtx[0].vout) { - if (output.scriptPubKey == ParseHex(FOUNDERS_REWARD_SCRIPT)) { + if (output.scriptPubKey == Params().GetFoundersRewardScript(nHeight)) { if (output.nValue == (GetBlockSubsidy(nHeight, consensusParams) / 5)) { found = true; break; diff --git a/src/main.h b/src/main.h index 9c875d8c..0cb71407 100644 --- a/src/main.h +++ b/src/main.h @@ -47,9 +47,6 @@ class CValidationState; struct CNodeStateStats; -// This is a 2-of-3 multisig P2SH -static const char *FOUNDERS_REWARD_SCRIPT = "a9146708e6670db0b950dac68031025cc5b63213a49187"; - /** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/ static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000; static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0; diff --git a/src/miner.cpp b/src/miner.cpp index a27210b6..0d655249 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -335,17 +335,14 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) txNew.vout[0].scriptPubKey = scriptPubKeyIn; txNew.vout[0].nValue = GetBlockSubsidy(nHeight, chainparams.GetConsensus()); - if ((nHeight > 0) && (nHeight < chainparams.GetConsensus().nSubsidyHalvingInterval)) { + if ((nHeight > 0) && (nHeight < chainparams.GetConsensus().GetLastFoundersRewardBlockHeight())) { // Founders reward is 20% of the block subsidy auto vFoundersReward = txNew.vout[0].nValue / 5; // Take some reward away from us txNew.vout[0].nValue -= vFoundersReward; - auto rewardScript = ParseHex(FOUNDERS_REWARD_SCRIPT); - // And give it to the founders - txNew.vout.push_back(CTxOut(vFoundersReward, CScript(rewardScript.begin(), - rewardScript.end()))); + txNew.vout.push_back(CTxOut(vFoundersReward, chainparams.GetFoundersRewardScript(nHeight))); } // Add fees diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index fb6b0a56..11230acd 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -786,7 +786,7 @@ Value getblocksubsidy(const Array& params, bool fHelp) CAmount nReward = GetBlockSubsidy(nHeight, Params().GetConsensus()); CAmount nFoundersReward = 0; - if ((nHeight > 0) && (nHeight < Params().GetConsensus().nSubsidyHalvingInterval)) { + if ((nHeight > 0) && (nHeight <= Params().GetConsensus().GetLastFoundersRewardBlockHeight())) { nFoundersReward = nReward/5; nReward -= nFoundersReward; } From 3b30d8361ad969b8168a1014cf994e52ea791d19 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 22 Sep 2016 16:38:44 -0700 Subject: [PATCH 02/11] Founders reward: changed index computation, added new test and some refactoring. --- src/chainparams.cpp | 14 ++++-- src/chainparams.h | 5 +- src/gtest/test_foundersreward.cpp | 78 ++++++++++++++++++++----------- src/main.cpp | 2 +- src/miner.cpp | 2 +- 5 files changed, 66 insertions(+), 35 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 94813a0c..b8dafa8d 100644 --- a/src/chainparams.cpp +++ b/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(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& 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() {} diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index 01a72d84..7c3f224b 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/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 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 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 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 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 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); + +} + diff --git a/src/main.cpp b/src/main.cpp index c6b1f1fc..5a8cd147 100644 --- a/src/main.cpp +++ b/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; diff --git a/src/miner.cpp b/src/miner.cpp index 0d655249..8c0c2ad8 100644 --- a/src/miner.cpp +++ b/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 From 241867b115c2de59cf6ece521962c4a6902c8a10 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 23 Sep 2016 14:16:38 -0700 Subject: [PATCH 03/11] Founders reward: Refactor test and formatting per review. --- src/chainparams.cpp | 10 ++++------ src/gtest/test_foundersreward.cpp | 33 +++++++++++-------------------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index b8dafa8d..08ba9a6f 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -341,10 +341,9 @@ 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::GetFoundersRewardAddressAtHeight(int nHeight) const -{ +std::string CChainParams::GetFoundersRewardAddressAtHeight(int nHeight) const { int maxHeight = consensus.GetLastFoundersRewardBlockHeight(); - assert(nHeight>0 && nHeight<=maxHeight); + assert(nHeight > 0 && nHeight <= maxHeight); size_t addressChangeInterval = (maxHeight + vFoundersRewardAddress.size()) / vFoundersRewardAddress.size(); size_t i = nHeight / addressChangeInterval; @@ -353,8 +352,7 @@ std::string CChainParams::GetFoundersRewardAddressAtHeight(int nHeight) const // 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::GetFoundersRewardScriptAtHeight(int nHeight) const -{ +CScript CChainParams::GetFoundersRewardScriptAtHeight(int nHeight) const { assert(nHeight > 0 && nHeight <= consensus.GetLastFoundersRewardBlockHeight()); CBitcoinAddress address(GetFoundersRewardAddressAtHeight(nHeight).c_str()); @@ -366,6 +364,6 @@ CScript CChainParams::GetFoundersRewardScriptAtHeight(int nHeight) const } std::string CChainParams::GetFoundersRewardAddressAtIndex(int i) const { - assert(i>=0 && i= 0 && i < vFoundersRewardAddress.size()); return vFoundersRewardAddress[i]; } diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index 7c3f224b..1e9c8b74 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -36,7 +36,7 @@ TEST(founders_reward_test, create_testnet_2of3multisig) { pubkeys.resize(3); CPubKey newKey; std::vector addresses; - for (int i=0; iGetKeyFromPool(newKey)); pubkeys[0] = newKey; ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); @@ -70,12 +70,13 @@ TEST(founders_reward_test, create_testnet_2of3multisig) { // Utility method to check the number of unique addresses from height 1 to maxHeight -void checkNumberOfUniqueAddresses(int maxHeight, int nUnique) { +void checkNumberOfUniqueAddresses(int nUnique) { + int maxHeight = Params().GetConsensus().GetLastFoundersRewardBlockHeight(); std::set addresses; - for (int i=1; i<=maxHeight; i++) { + for (int i = 1; i <= maxHeight; i++) { addresses.insert(Params().GetFoundersRewardAddressAtHeight(i)); } - ASSERT_TRUE(addresses.size()==nUnique); + ASSERT_TRUE(addresses.size() == nUnique); } @@ -104,10 +105,7 @@ TEST(founders_reward_test, general) { TEST(founders_reward_test, mainnet) { SelectParams(CBaseChainParams::MAIN); - CChainParams params = Params(); - - int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); - checkNumberOfUniqueAddresses(maxHeight, NUM_MAINNET_FOUNDER_ADDRESSES); + checkNumberOfUniqueAddresses(NUM_MAINNET_FOUNDER_ADDRESSES); } @@ -115,10 +113,7 @@ TEST(founders_reward_test, mainnet) { TEST(founders_reward_test, testnet) { SelectParams(CBaseChainParams::TESTNET); - CChainParams params = Params(); - - int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); - checkNumberOfUniqueAddresses(maxHeight, NUM_TESTNET_FOUNDER_ADDRESSES); + checkNumberOfUniqueAddresses(NUM_TESTNET_FOUNDER_ADDRESSES); } @@ -126,10 +121,7 @@ TEST(founders_reward_test, testnet) { TEST(founders_reward_test, regtest) { SelectParams(CBaseChainParams::REGTEST); - CChainParams params = Params(); - - int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); - checkNumberOfUniqueAddresses(maxHeight, NUM_REGTEST_FOUNDER_ADDRESSES); + checkNumberOfUniqueAddresses(NUM_REGTEST_FOUNDER_ADDRESSES); } @@ -142,8 +134,8 @@ TEST(founders_reward_test, slow_start_subsidy) { int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); CAmount totalSubsidy = 0; - for (int nHeight=1; nHeight<=maxHeight; nHeight++) { - CAmount nSubsidy = GetBlockSubsidy(nHeight, params.GetConsensus())/ 5; + for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { + CAmount nSubsidy = GetBlockSubsidy(nHeight, params.GetConsensus()) / 5; totalSubsidy += nSubsidy; } @@ -156,9 +148,9 @@ TEST(founders_reward_test, per_address_reward) { SelectParams(CBaseChainParams::TESTNET); CChainParams params = Params(); - int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); + int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); std::multiset ms; - for (int nHeight=1; nHeight<=maxHeight; nHeight++) { + for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { ms.insert(params.GetFoundersRewardAddressAtHeight(nHeight)); } @@ -167,6 +159,5 @@ TEST(founders_reward_test, per_address_reward) { ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(i)) == 17709); } ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(47)) == 17677); - } From 1a21a25e6246cd2287e5114f39c7704277079a34 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 28 Sep 2016 15:31:02 -0700 Subject: [PATCH 04/11] Refactor to add test to verify number of rewards each mainnet address will receive --- src/gtest/test_foundersreward.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index 1e9c8b74..4db0d985 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -143,11 +143,10 @@ TEST(founders_reward_test, slow_start_subsidy) { } -// Verify the number of rewards going to each mainnet/testnet address -TEST(founders_reward_test, per_address_reward) { - SelectParams(CBaseChainParams::TESTNET); +// For use with mainnet and testnet which each have 48 addresses. +// Verify the number of rewards each individual address receives. +void verifyNumberOfRewards() { CChainParams params = Params(); - int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); std::multiset ms; for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { @@ -161,3 +160,14 @@ TEST(founders_reward_test, per_address_reward) { ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(47)) == 17677); } +// Verify the number of rewards going to each mainnet address +TEST(founders_reward_test, per_address_reward_mainnet) { + SelectParams(CBaseChainParams::MAIN); + verifyNumberOfRewards(); +} + +// Verify the number of rewards going to each testnet address +TEST(founders_reward_test, per_address_reward_testnet) { + SelectParams(CBaseChainParams::TESTNET); + verifyNumberOfRewards(); +} \ No newline at end of file From 22dadb35eca2aa8735c960652666e6f06c5f41be Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 29 Sep 2016 10:24:15 -0700 Subject: [PATCH 05/11] Refactor and fix per review --- src/chainparams.cpp | 6 +++--- src/miner.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 08ba9a6f..c44b8b58 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -156,7 +156,7 @@ public: "ADDRESS41", "ADDRESS42", "ADDRESS43", "ADDRESS44", "ADDRESS45", "ADDRESS46", "ADDRESS47", "ADDRESS48", }; - assert(vFoundersRewardAddress.size() < consensus.nSubsidyHalvingInterval + consensus.SubsidySlowStartShift()); + assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight()); } }; static CMainParams mainParams; @@ -236,7 +236,7 @@ public: "2N4ACsVCKMvJmtEb3Pd3xkqhJ3rLT4mYx1r", "2MtmMdabcwRJmenswaYtWA675df854KhUxD", "2N2h27Dd87eiGcm7ajvu4hJpXjTm9GkzvLZ", "2NGE19agRXU1EAK3PCLZWXERkpqyUexhk9r", "2N63112wMnBsXTaBFjbCTjW9LuyTXQmvEdw", "2NBkHxgkYZbU56zsoLNsP5WZVfMtBK6X8WK", "2N5pK7NfKo6d9qBmsKggpwuvQeMxGf65SLH", "2N5jHzgCg9a9uAcLaT2jij8WKTZzWbVNC5c", }; - assert(vFoundersRewardAddress.size() < consensus.nSubsidyHalvingInterval + consensus.SubsidySlowStartShift()); + assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight()); } }; static CTestNetParams testNetParams; @@ -297,7 +297,7 @@ public: // Founders reward script expects a vector of 2-of-3 multisig addresses vFoundersRewardAddress = { "2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4" }; - assert(vFoundersRewardAddress.size() < consensus.nSubsidyHalvingInterval + consensus.SubsidySlowStartShift()); + assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight()); } }; static CRegTestParams regTestParams; diff --git a/src/miner.cpp b/src/miner.cpp index 8c0c2ad8..3c3a69e7 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -335,7 +335,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) txNew.vout[0].scriptPubKey = scriptPubKeyIn; txNew.vout[0].nValue = GetBlockSubsidy(nHeight, chainparams.GetConsensus()); - if ((nHeight > 0) && (nHeight < chainparams.GetConsensus().GetLastFoundersRewardBlockHeight())) { + if ((nHeight > 0) && (nHeight <= chainparams.GetConsensus().GetLastFoundersRewardBlockHeight())) { // Founders reward is 20% of the block subsidy auto vFoundersReward = txNew.vout[0].nValue / 5; // Take some reward away from us From b7d072069e67fc2d97a868c2e72608070418afe8 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 29 Sep 2016 19:37:38 -0700 Subject: [PATCH 06/11] Update comment per review --- src/main.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5a8cd147..55a4c36a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3084,8 +3084,10 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn } // Coinbase transaction must include an output sending 20% of - // the block reward to `FOUNDERS_REWARD_SCRIPT` until the first - // subsidy halving block, with exception to the genesis block. + // the block reward to a founders reward script, until the last founders + // reward block is reached, with exception of the genesis block. + // The last founders reward block is defined as the block just before the + // first subsidy halving block, which occurs at halving_interval + slow_start_shift if ((nHeight > 0) && (nHeight <= consensusParams.GetLastFoundersRewardBlockHeight())) { bool found = false; From 88fd81015056a26601b7e98c3c0ba115833db22b Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 29 Sep 2016 23:04:27 -0700 Subject: [PATCH 07/11] Update founders reward test to output path of temporary wallet.dat file which contains keys which can be used for testing founders reward addresses. --- src/gtest/test_foundersreward.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index 4db0d985..2f777654 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -19,17 +19,19 @@ // // Enable this test to generate and print 48 testnet 2-of-3 multisig addresses. // The output can be copied into chainparams.cpp. +// The temporary wallet file can be renamed as wallet.dat and used for testing with zcashd. // #if 0 TEST(founders_reward_test, create_testnet_2of3multisig) { ECC_Start(); SelectParams(CBaseChainParams::TESTNET); boost::filesystem::path temp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); - const std::string path = temp.native(); + const std::string path = temp.native() + "-wallet.dat"; bool fFirstRun; auto pWallet = std::make_shared(path); ASSERT_EQ(DB_LOAD_OK, pWallet->LoadWallet(fFirstRun)); pWallet->TopUpKeyPool(); + std::cout << "Test wallet file path: " << path << std::endl; int numKeys = 48; std::vector pubkeys; @@ -65,6 +67,8 @@ TEST(founders_reward_test, create_testnet_2of3multisig) { } s += " };"; std::cout << s << std::endl; + + pWallet->Flush(true); } #endif From 6c54e9fc0b34238c18f5ea24e3e5d62004f7a44f Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 29 Sep 2016 23:53:08 -0700 Subject: [PATCH 08/11] Update testnet founders reward addresses --- src/chainparams.cpp | 24 ++++++++++++------------ src/gtest/test_foundersreward.cpp | 11 ++++++----- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index c44b8b58..9efa7f0d 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -223,18 +223,18 @@ public: // Founders reward script expects a vector of 2-of-3 multisig addresses vFoundersRewardAddress = { - "2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4", "2NBW8WsA2jUussoJbRv82UXH1BYopkjYqcd", "2N1MudZmwDFTcYiLCZfrcsnhHwaSTTigbcN", "2MxfUJXWKz9D8X3mcMpVcdEJKdJ6zFukca9", - "2N8iUwMCpU16VYpKQ1HRM6xfut5FZwGwieM", "2N9hyafTvJVrykBvZDw79j1brozwZNySwPP", "2NFx7tRozsp3kT1M4w4tL9FfnEj8RovzbzN", "2NAqoH96V1RtmK72LEZpJNX1uxhJ5yejRiK", - "2MyV7hoV28KS8Uam2Z8nzY3xeo7R3T3TLUr", "2N8Tn19hMoCD4EmCwpg1V8qupVkQLVVPhav", "2NA5UeJU9zAQkSMyy3xpDcjfp4CEyKfzXKp", "2NBERNyXy46CfM9yewGeof4yzC3vkwYnhgS", - "2N7fnpAswHb4mnPm2ZjWX3eKkF8hABAYBtQ", "2N9MXGsz7uYaY5ciax6tSMDG7sjZUoLhJTC", "2N5PwzPQFFmLut2XWGQWAmpwKsF8VzUoPtr", "2MvZdDpNP8hWyEqg6zKW9B62YTJqcUwjHr5", - "2Mx4KfKJ37EDc3A43Frzof1iEjSe91JUX7d", "2NBMSdXjZ7YqREmwxEtgGryY59KBpqMSs1d", "2N9RbfE4ZCJ3Nx68vPfmvH2M6Q3qicJhagb", "2N4xwfFkFj4DR4NWNbynzP2aJmVcEFnA2DB", - "2Mx4TyAwedmsRuDkvMNYGqrcCZfQTfCvxAp", "2Mx4HSVsxEqXjLxn8igJzmCrFdG9XhnNvtf", "2MtLM4SP7LJbBZ5rA5ZG8kAVz9UNrNKuoFB", "2N7SPq83Cbmwuwv5rjNBzVd9QtJKAxxKj8M", - "2MwYkbE4U4p9XBsCrupDDkdcDH9L9xvc9Bn", "2MyaeCHpVmckokUi67YP1QK9L3Dkx3Pt86F", "2N7URNgBPXGjqnuPHiynCa6qMMhKm6YEaHr", "2N2eNwGVwj4WwbEdJg7YZDgrnYvDv1ZSNbB", - "2MuWAG6BqLM1mtZc67Fv1aKgGwkNQ2akDGt", "2N7XH82MbGwpzbc7PM2aK5CU14bSJvK7Etz", "2MuPX8Ke5TvDDQ1nkqpaPMgYWPyWbFp18Jn", "2NFBST7oK9yw9PaXaq5QhdyYwp5HpHz9m81", - "2MuSeMBUrttbjvDZAeQjTrrDeoP197qj2kG", "2N6JU8JNGGAUFknTCuLSuDEEhZJqMfFsH88", "2N4P2MrwtwbiHymQm1RASoVoiH3sFrBpmXa", "2MyhFiVXvVVxUNc8Qh9ppV7jG4NsKpnxige", - "2N5dLXUho2GtjuHMWuqixLrHLCwUMcYxd7s", "2N9NhfSiYBt3fhETFR6mQc3uxreEy7simSg", "2NBEEWPY3v38uuC7n1tMtviEY7ND2XzfgSG", "2NCWWj6oREJiMmfJ2bV5sbm1xchMwQfAZ5r", - "2N4ACsVCKMvJmtEb3Pd3xkqhJ3rLT4mYx1r", "2MtmMdabcwRJmenswaYtWA675df854KhUxD", "2N2h27Dd87eiGcm7ajvu4hJpXjTm9GkzvLZ", "2NGE19agRXU1EAK3PCLZWXERkpqyUexhk9r", - "2N63112wMnBsXTaBFjbCTjW9LuyTXQmvEdw", "2NBkHxgkYZbU56zsoLNsP5WZVfMtBK6X8WK", "2N5pK7NfKo6d9qBmsKggpwuvQeMxGf65SLH", "2N5jHzgCg9a9uAcLaT2jij8WKTZzWbVNC5c", + "2NF5QVDMtYBHaUzPLTxirybjwPjm9wVwacv", "2N8qoHsvVvdrDc89dXjpBWZHMbWdaHVc3rg", "2N8xpkGmATvu1GjgpjSjmt5L5V5fnEhW89v", "2MtTJnZRWNKJtmr5NN5jnjL9hTqP6tFBuLE", + "2N3Jbuca4yhcqMCa36w5Jy9NdLf7Te2BBZr", "2NAkLyEyxv1y1tvE3LawvaFXZ12GKDyXc9K", "2NEA5WxHJfpFWijWuJLwyjNmNYAKSdBFrFt", "2N68WRnm7HJYZRBL7XtqRJVQD7dCJtQx4Vg", + "2NAieMb6ZfC2RJ6c19Ch4JER6yqgRAd1CeG", "2Mvw6JtXth8cYPHxD2DGwF2fzL6C5g66w6w", "2N3treWEan8WhpKurCNTdsgh6JtTD8hLMEY", "2N46cPyaEBFb1MxHJWdtXKhfRjKWhoAF2VY", + "2N2hFwZYHvKCjqVJHCYwpy6FaBycyjcKaHB", "2N3wQ8GyAbtb4FXgymzK99ZUDdrdDVQBGNx", "2N2tq2AcVroDciF5H3WpkHraUiK6eZZgJqR", "2N6g8Q9Z6mZwQzTw1s5KoSaVTKYxBVDMeqc", + "2NFfPnK3jj85sn9mWe5EivUdnUPykMRXGp6", "2MwC4NhXRQSZzN9cfeg88Cdsp6DiXn2Axt9", "2MsTXMg8TBfKQvj7UJfMXKp3naKYv9ty3jv", "2MzPMV6sPt45J2qU1Uvft2U1ES1q9Cnw74J", + "2NEo5vX2Gvg83FbSUTfndQqkZbFHd1zJnZz", "2Mtkiihqt6wTV5uwvdmf9nTZKgEzZx6BMXB", "2MvM6urpNbfS2QFPFeUEoM14VKgBKoV8Qws", "2Mv3FDtDtyiHQA6u6kDWoiBKDkL5JFuA4Se", + "2MtyHB5chweTMBXXVPqSLAWHF6fgajGisi6", "2N3BU59PLVRWmPvffumGNWJdorY8ex5NKHq", "2NEiq16k9nQzYxWL1mvJVN32ticcL3b65vW", "2NB1groo8MTEAvPDbgcmzHsr56rSpbmXj48", + "2MwMr9dW3hrkgsmpWivobrwScfXC8hFsg4N", "2My9qRCuUBJ9aZohh8f4VQoXvBgmP9pBE11", "2MyHm9yFdm3aou91PLWzEVDeWrcrC5re4GS", "2N73XvH7vdzKr7UGHFkAeAUJFz4o8zTFeZY", + "2MwPLTmV6469VBcDxcsnotq4Qbf8CRX7DWz", "2MtmeB8wEGepSRodY7sq7myZVmFsBWAXYpW", "2N1WmRvcqMomQGePwvkd5QrKXQuYePDZh9Z", "2MwuBXGGBAPK2TupdoQK2Fw63vitJb7RUJZ", + "2Mz4XXqLy2TC5bmBczjakVeqajFo5D3jma2", "2NB19923xi5D9MPqZZvkvH5VbQ2MNRfW9e2", "2NBKhC9RJPPxA8B8bdPvvYvGGjkSoTfdrKh", "2Mzn2q4ZmReBsSQFHRscXav4Xt44wXWeo9a", + "2N1BqHdQV1r6NBeF3bbj3rE1by3MPrwgbbb", "2N6VpEUSwCvh1FCuVKb9eZCxcFnZuzcxB6f", "2N2Uq4i7DYaq2ngJZi4eXf9DAXuDYCDKMzc", "2MwsKBtaZeVKzD51otkAyBDoeuaDDK8wgqe", + "2NCajs4c2PeW8pWZxyMUiV3rDkEYyYnRAhQ", "2MuGtcBJQLfJD6GFbXy7iTtG8QasgZ8qd3Y", "2NFZ3yjeBSS3FKMy1N1zTeSEyqiRgnH35v4", "2Mvv8o9U4dbJjgWPvLDy3L6Sh74Wmynf36q", }; assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight()); } diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index 2f777654..66e3081d 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -89,11 +89,12 @@ TEST(founders_reward_test, general) { CChainParams params = Params(); - // For Testnet, the first address is derived from the old script. - // FOUNDERS_REWARD_SCRIPT = a9146708e6670db0b950dac68031025cc5b63213a49187 - // address = 2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4 - EXPECT_EQ(params.GetFoundersRewardScriptAtHeight(1), ParseHex("a9146708e6670db0b950dac68031025cc5b63213a49187")); - EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(1), "2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4"); + // First testnet reward: + // address = 2NF5QVDMtYBHaUzPLTxirybjwPjm9wVwacv + // script = OP_HASH160 ef775f1f997f122a062fff1a2d7443abd1f9c642 OP_EQUAL + // raw script = a914ef775f1f997f122a062fff1a2d7443abd1f9c64287 + EXPECT_EQ(params.GetFoundersRewardScriptAtHeight(1), ParseHex("a914ef775f1f997f122a062fff1a2d7443abd1f9c64287")); + EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(1), "2NF5QVDMtYBHaUzPLTxirybjwPjm9wVwacv"); int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); From 02acbfc26283a3e01aaad7a5c204d616b2a84768 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 30 Sep 2016 18:29:10 -0700 Subject: [PATCH 09/11] Add mainnet 2-of-3 multisig addresses for testing. --- src/chainparams.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 9efa7f0d..2237f2f2 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -143,19 +143,18 @@ public: // Founders reward script expects a vector of 2-of-3 multisig addresses vFoundersRewardAddress = { - "ADDRESS1", "ADDRESS2", "ADDRESS3", "ADDRESS4", - "ADDRESS5", "ADDRESS6", "ADDRESS7", "ADDRESS8", - "ADDRESS9", "ADDRESS10", "ADDRESS11", "ADDRESS12", - "ADDRESS13", "ADDRESS14", "ADDRESS15", "ADDRESS16", - "ADDRESS17", "ADDRESS18", "ADDRESS19", "ADDRESS20", - "ADDRESS21", "ADDRESS22", "ADDRESS23", "ADDRESS24", - "ADDRESS25", "ADDRESS26", "ADDRESS27", "ADDRESS28", - "ADDRESS29", "ADDRESS30", "ADDRESS31", "ADDRESS32", - "ADDRESS33", "ADDRESS34", "ADDRESS35", "ADDRESS36", - "ADDRESS37", "ADDRESS38", "ADDRESS39", "ADDRESS40", - "ADDRESS41", "ADDRESS42", "ADDRESS43", "ADDRESS44", - "ADDRESS45", "ADDRESS46", "ADDRESS47", "ADDRESS48", - }; + "3G9jrP2booTPMDLpHpz5tfvUDNhhF6BXPA", "3FE1e5eAUDDJS2vuPgFCcFqAf5nswXJ3NP", "3Q6UzRpXZJM1q8QT6QWkPD4Vm33ZR3gYki", "3D3VqtdjePHgHZKZ6U6Kj9DLnK37RYkxqf", + "3KsyrZagqiWop27ZmStPP4v3weRMbvpU5F", "3F2RKNQZvtqcKaW36oTS2LGy37RxxshGXS", "37iaAcocxmBfnrgrcQw2n9tC2dNj16f6gu", "3JL9iA8hSnAZ9VWYoVU5rdozax9hv65XFa", + "3JcBvC299zBqKVvJXmvLgXEcXHCm4EY7kR", "3HNYRVzMxrtzGHSSVd9D4iQCCScs8DL7w5", "3JVMcA1Sf6NxVU5bCp8g9xDRc4U9bkJUDi", "3N5nParFFNrhdyvJAKo2qu9tF3aAS3pBVf", + "3GYg958NgmTfAv82rVxKaFXZygLBQqCfHC", "32uim4XvTJ93BgNtxwQn9onaW3vgbVgv42", "36QSmW19FeUTyZfV55LmPZ9gSKsykayWDj", "3CM6SAEbfi4PcdNYnWFu1CCN7cqQRUkCJ4", + "37BoW4U7v3zMmpjD6qsUXfsLzxGqPeNxzv", "3Jzcs4RTQYycRKUiZ1XaqkGphw3vp34yds", "32KnSrYKK7QheD2msrBnbqXCS2uQpNS43y", "3L8n5dPFYkTtkUsTqKVhdNZeYHs8GfeEYi", + "33n6xxNHQzwXYGbhSGEdBKUASn3JaAWB5C", "34mVHc7mPhuoaRcymEsMHRLYJZHzMTmFMH", "3Lfcdsj7G8oXsLy7PzpxYd61xsoKRTN3Qd", "3NHFaDoEMFP7kojSkPyEyFyoPz2NqaT23w", + "3PXoXwApPgZHWc8Mh8mE3ETBoCgD3pzcFY", "34np9aGVNWdUQXg7ZaCfK6o7L2hYPERQJW", "3H6FHDSbqEpV346pvxUTMLgGTkBxN7bHjh", "3HRTS3YWc4rzSFawH6pf2maasBK8FcUUkN", + "3ADiBFGpSJnZEsrpDtyHw5haYTr28PFniR", "3CMRxVdrYNGgQ4nhuFFVG1A6ZhvjEfk3YL", "36iPNEHP4dh3j7AXZHqutQRUissu9oYmAN", "3HiRQfSQfLhi65V9WuXZGK11y2xCqphka8", + "31vWyvVDoSSCDs17tMhscbDrvLr79SMXuk", "3LD9NqF9c7e542rYvZHRJsoA5mhsgtqgG9", "34dPRHzi1PqPB78Hvs7U4FdH7s2Xg3At67", "3FbK44VH2vzJ4t1WcTzRcvgwFY4CpPLAwK", + "3BSdnxeYARKZ1nDnUEMBBKnd3jh6HoGc2R", "3Kd3Fy8HnmCgybLE6ENqBt6T98Z8eAre1r", "36sPVoc9S32ZGZaDZuy66NcKCTM8CjvX83", "3EvQApCtxwLy3UwuhNPdWmDJxRwaAecCs1", + "3Pt8dBVuTjMEU3nsjwQxKjpN2o8jt84p7h", "357TXhYimgNg9hUWn15AXCAezhK4M2poCe", "39MRrWWudf2pkCiaTbZU3Z2SAJbuB8pC2a", "33mZ6wiv6jQcHxeMbzs9h1qst6pbRXXQoF", + }; assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight()); } }; From 2d6e97ecc5b750e83375218cb90eb5b772fa0663 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 30 Sep 2016 18:31:51 -0700 Subject: [PATCH 10/11] Add field fMinerTestModeForFoundersRewardScript to chainparams --- src/chainparams.cpp | 8 ++++++++ src/chainparams.h | 2 ++ src/test/miner_tests.cpp | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 2237f2f2..1dc41c02 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -354,6 +354,14 @@ std::string CChainParams::GetFoundersRewardAddressAtHeight(int nHeight) const { CScript CChainParams::GetFoundersRewardScriptAtHeight(int nHeight) const { assert(nHeight > 0 && nHeight <= consensus.GetLastFoundersRewardBlockHeight()); + // #1398 START + // We can remove this code when miner_tests no longer expect this script + if (fMinerTestModeForFoundersRewardScript) { + auto rewardScript = ParseHex("a9146708e6670db0b950dac68031025cc5b63213a49187"); + return CScript(rewardScript.begin(), rewardScript.end()); + } + // #1398 END + CBitcoinAddress address(GetFoundersRewardAddressAtHeight(nHeight).c_str()); assert(address.IsValid()); assert(address.IsScript()); diff --git a/src/chainparams.h b/src/chainparams.h index 2fc92053..ac9d099e 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -81,6 +81,8 @@ public: std::string GetFoundersRewardAddressAtHeight(int height) const; CScript GetFoundersRewardScriptAtHeight(int height) const; std::string GetFoundersRewardAddressAtIndex(int i) const; + /** #1398 to return a fixed founders reward script for miner_tests */ + bool fMinerTestModeForFoundersRewardScript = false; protected: CChainParams() {} diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index a93a13fd..7b145c83 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -137,6 +137,14 @@ struct { // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { + // #1398 START + // Current test data expects to receive a reward script for the address + // 2N2e2FRfP9D1dRN1oRWkH7pbFM69eGNAuQ4 even though the test is run on mainnet + // and not testnet, and there are many founders reward addresses not just one. + // When test data is re-generated, we will no longer need to do this. + Params(CBaseChainParams::MAIN).fMinerTestModeForFoundersRewardScript = true; + // #1398 END + CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; CBlockTemplate *pblocktemplate; CMutableTransaction tx,tx2; From 4d11e5d2b9b32bb84092c04a60a9e15d95f81fb9 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 1 Oct 2016 07:19:24 -0700 Subject: [PATCH 11/11] Update mainnet addresses used for testing to have the correct number --- src/chainparams.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 1dc41c02..0c7e91e1 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -143,17 +143,18 @@ public: // Founders reward script expects a vector of 2-of-3 multisig addresses vFoundersRewardAddress = { - "3G9jrP2booTPMDLpHpz5tfvUDNhhF6BXPA", "3FE1e5eAUDDJS2vuPgFCcFqAf5nswXJ3NP", "3Q6UzRpXZJM1q8QT6QWkPD4Vm33ZR3gYki", "3D3VqtdjePHgHZKZ6U6Kj9DLnK37RYkxqf", - "3KsyrZagqiWop27ZmStPP4v3weRMbvpU5F", "3F2RKNQZvtqcKaW36oTS2LGy37RxxshGXS", "37iaAcocxmBfnrgrcQw2n9tC2dNj16f6gu", "3JL9iA8hSnAZ9VWYoVU5rdozax9hv65XFa", - "3JcBvC299zBqKVvJXmvLgXEcXHCm4EY7kR", "3HNYRVzMxrtzGHSSVd9D4iQCCScs8DL7w5", "3JVMcA1Sf6NxVU5bCp8g9xDRc4U9bkJUDi", "3N5nParFFNrhdyvJAKo2qu9tF3aAS3pBVf", - "3GYg958NgmTfAv82rVxKaFXZygLBQqCfHC", "32uim4XvTJ93BgNtxwQn9onaW3vgbVgv42", "36QSmW19FeUTyZfV55LmPZ9gSKsykayWDj", "3CM6SAEbfi4PcdNYnWFu1CCN7cqQRUkCJ4", - "37BoW4U7v3zMmpjD6qsUXfsLzxGqPeNxzv", "3Jzcs4RTQYycRKUiZ1XaqkGphw3vp34yds", "32KnSrYKK7QheD2msrBnbqXCS2uQpNS43y", "3L8n5dPFYkTtkUsTqKVhdNZeYHs8GfeEYi", - "33n6xxNHQzwXYGbhSGEdBKUASn3JaAWB5C", "34mVHc7mPhuoaRcymEsMHRLYJZHzMTmFMH", "3Lfcdsj7G8oXsLy7PzpxYd61xsoKRTN3Qd", "3NHFaDoEMFP7kojSkPyEyFyoPz2NqaT23w", - "3PXoXwApPgZHWc8Mh8mE3ETBoCgD3pzcFY", "34np9aGVNWdUQXg7ZaCfK6o7L2hYPERQJW", "3H6FHDSbqEpV346pvxUTMLgGTkBxN7bHjh", "3HRTS3YWc4rzSFawH6pf2maasBK8FcUUkN", - "3ADiBFGpSJnZEsrpDtyHw5haYTr28PFniR", "3CMRxVdrYNGgQ4nhuFFVG1A6ZhvjEfk3YL", "36iPNEHP4dh3j7AXZHqutQRUissu9oYmAN", "3HiRQfSQfLhi65V9WuXZGK11y2xCqphka8", - "31vWyvVDoSSCDs17tMhscbDrvLr79SMXuk", "3LD9NqF9c7e542rYvZHRJsoA5mhsgtqgG9", "34dPRHzi1PqPB78Hvs7U4FdH7s2Xg3At67", "3FbK44VH2vzJ4t1WcTzRcvgwFY4CpPLAwK", - "3BSdnxeYARKZ1nDnUEMBBKnd3jh6HoGc2R", "3Kd3Fy8HnmCgybLE6ENqBt6T98Z8eAre1r", "36sPVoc9S32ZGZaDZuy66NcKCTM8CjvX83", "3EvQApCtxwLy3UwuhNPdWmDJxRwaAecCs1", - "3Pt8dBVuTjMEU3nsjwQxKjpN2o8jt84p7h", "357TXhYimgNg9hUWn15AXCAezhK4M2poCe", "39MRrWWudf2pkCiaTbZU3Z2SAJbuB8pC2a", "33mZ6wiv6jQcHxeMbzs9h1qst6pbRXXQoF", + "37dSC2gL2SftgVJBHemBfWtSsNwuNfeTkz", "3KENXyYPCx4SZPGqE2Qp64Vrt49JNxvCbH", "3B2t3k6oQBACSmZArbYiseYsbsxBFFsHXG", "3QuE4MQXQwuzynXJwLPuWaciKjmRqkj9Yg", + "3FGDxAMPbjgq2ZTSFdoeWTHUu8i3nZcENb", "3HMUFCvai1KtyJ3woLXyY5dGTWjBwmD3M2", "3Mqskxz8RexngVRBkZnGVCLp1Z7wyqFjVE", "359NbXKBNezXEUqvU1cqJkfdZTHbzfsQfV", + "3KGJQmUe7zjMFkTGskiBH6JBNuymJRzU3a", "36PjhjMcMkU9kjgvCocAke5VSF6JzKXuqZ", "35fucu9Bh1AKad9zMvDgDhc3kmoj6ZcFNV", "35EnKe4u16128G6j1efUT27Vwqha6MgWDH", + "3FWa1GEjWWY3eFuFK8ht2HBhH8ZT1zXJcR", "3ByiCPMp3vNYjq1fQrQx2LXbMJ3uyiUfH6", "3DNWVawdGNJJ3sp9aMgyjtFv74rPivPUcM", "3HKAkRbUbUTV2vs1qSoEbhpoUAjNAmGxrm", + "3CV41uQT2B6FU8H57rAh22d4wyDG8FrK37", "361jTn1yhDRHji9qMrwq8p2qbSxrEfcf58", "3A4hTEi36fQdvTczkiNESqdtoADRFEUGdr", "36LBGQ4CNWRtEVxdRk8Lym52rFqRx5aAy9", + "34Hvy7rqUToVzQKu6v6gN69Qo1M37ktKpZ", "3Qii1z7vD5EFpGx3yFAqDBLQ9kCdfpxwpC", "3HNSu7ibS7yu4FW3Sf2D36Ms8BKDhBTPQo", "36djsWiivpZwPC4eZqMAFoS87VgxkjDHen", + "3E7dsoe6eJavv6HEwADC7eV2JjHXZE8wx4", "3Ks5EBz94K2TgAx19vxvwX6A2cUf1AWNfJ", "3GuGkVkqD1k9wYJNikNhMxK8ci8HGnJ3HN", "3QPjeeX5FFwEbDk8RHDXCPunsgHp9YLXsV", + "3MY2DeyRPJaUKZwpKTGsT31vZMLtVk66FP", "36f92vZ3jo3TYBXVGv55BptKmL2MDL47ZF", "3DDUDXN3aSgXckFnTdFTV1t8HjkifNKbJM", "3ArUZmHERS6CDyNYb1DhnCZ7XCCoWEURAb", + "3QnJ98YuZcVZhxs49kwwDmf5BUYPbjvKRQ", "3DNdji6oCCTVbLF4iuzamAv73MGQ9LsKNb", "3Q5cGqEzkBLMac8DNSdVesZPUcucFP3jqU", "3JuQnoHp6Qm9N39ETD4yRHhj1CCKXo3deG", + "3EQftBB2MsZ4wNgGxKfhMREU3hNk29VZeW", "38baEewZky2kRaMSvjxh2x3eDdHt1ovVnu", "32kq15rjjtjaj1Z5dW8N6DikKxBeEbCZ5B", "34tta8VkpCZFNZyM9oWf656QcNwDB2qoRV", + "33nGWUV4nKjAM7XWYNTf5Fe6aBahCe22RN", "36tt5b1MDeYks6N7Zhk5gDs3sNZjkh4mG7", "32eS4cHrpJv7MkGQzkA7KwYZuNCvbpCzm4", "39Wqmd6f23mFWsMurx9d9YbaHxyEmXpw4G", + "32x1txo29hfy6fm5kMryX2175qz7ocU8iz", "3KR3wPnecQgpndUGAdwWCfehbEES4DES3C", "3HBPRij6s8Thv2AnRytLEZ9pW6Wqoztcr6", "3N3BPLx8rHfEdqPnEWuguYfAXtDXc8sK53", }; assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight()); }