Skip to content

Commit 77d037d

Browse files
authored
Merge pull request #2425 from jamescowens/mrc_for_pr
consensus, contract, mining, researcher, rpc, staking, gui: Implementation of MRC - baseline functionality
2 parents cef4fac + 5b924ef commit 77d037d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2894
-565
lines changed

src/Makefile.am

+2
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ GRIDCOIN_CORE_H = \
106106
gridcoin/cpid.h \
107107
gridcoin/gridcoin.h \
108108
gridcoin/magnitude.h \
109+
gridcoin/mrc.h \
109110
gridcoin/project.h \
110111
gridcoin/quorum.h \
111112
gridcoin/researcher.h \
@@ -223,6 +224,7 @@ GRIDCOIN_CORE_CPP = addrdb.cpp \
223224
gridcoin/contract/message.cpp \
224225
gridcoin/cpid.cpp \
225226
gridcoin/gridcoin.cpp \
227+
gridcoin/mrc.cpp \
226228
gridcoin/project.cpp \
227229
gridcoin/quorum.cpp \
228230
gridcoin/researcher.cpp \

src/Makefile.qt.include

+1
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ RES_ICONS = \
439439
qt/res/icons/transaction0.png \
440440
qt/res/icons/transaction2.svg \
441441
qt/res/icons/tx_contract_beacon.svg \
442+
qt/res/icons/tx_contract_mrc.svg \
442443
qt/res/icons/tx_contract_voting.svg \
443444
qt/res/icons/tx_inout.svg \
444445
qt/res/icons/tx_input.svg \

src/Makefile.test.include

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ GRIDCOIN_TESTS =\
5050
test/gridcoin/cpid_tests.cpp \
5151
test/gridcoin/enumbytes_tests.cpp \
5252
test/gridcoin/magnitude_tests.cpp \
53+
test/gridcoin/mrc_tests.cpp \
5354
test/gridcoin/project_tests.cpp \
5455
test/gridcoin/researcher_tests.cpp \
5556
test/gridcoin/superblock_tests.cpp \

src/chainparams.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ class CMainParams : public CChainParams {
6464
consensus.BlockV9TallyHeight = 1144120;
6565
consensus.BlockV10Height = 1420000;
6666
consensus.BlockV11Height = 2053000;
67+
consensus.BlockV12Height = std::numeric_limits<int>::max();
68+
// Immediately post zero payment interval fees 40% for mainnet
69+
consensus.InitialMRCFeeFractionPostZeroInterval = Fraction(2, 5);
70+
// Zero day interval is 14 days on mainnet
71+
consensus.MRCZeroPaymentInterval = 14 * 24 * 60 * 60;
6772
// "standard" scrypt target limit for proof of work, results in 0,000244140625 proof-of-work difficulty.
6873
// Equivalent to ~arith_uint256() >> 20 or 1e0fffff in compact notation.
6974
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
@@ -149,6 +154,11 @@ class CTestNetParams : public CChainParams {
149154
consensus.BlockV9TallyHeight = 399120;
150155
consensus.BlockV10Height = 629409;
151156
consensus.BlockV11Height = 1301500;
157+
consensus.BlockV12Height = std::numeric_limits<int>::max();
158+
// Immediately post zero payment interval fees 40% for testnet, the same as mainnet
159+
consensus.InitialMRCFeeFractionPostZeroInterval = Fraction(2, 5);
160+
// Zero day interval is 10 minutes on testnet. The very short interval facilitates testing.
161+
consensus.MRCZeroPaymentInterval = 10 * 60;
152162
// Equivalent to ~arith_uint256() >> 16 or 1f00ffff in compact notation.
153163
consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
154164

src/chainparams.h

+11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
#include "consensus/params.h"
1111
#include "protocol.h"
1212

13+
// system.h included only for temporary V12 fork point overrides for testing.
14+
#include "util/system.h"
15+
1316
#include <memory>
1417
#include <vector>
1518

@@ -131,6 +134,14 @@ inline bool IsV11Enabled(int nHeight)
131134
return nHeight >= Params().GetConsensus().BlockV11Height;
132135
}
133136

137+
inline bool IsV12Enabled(int nHeight)
138+
{
139+
// Temporary override for testing. Cf. Corresponding code in init.cpp
140+
int BlockV12Height = gArgs.GetArg("-blockv12height", Params().GetConsensus().BlockV12Height);
141+
142+
return nHeight >= BlockV12Height;
143+
}
144+
134145
inline int GetSuperblockAgeSpacing(int nHeight)
135146
{
136147
return (fTestNet ? 86400 : (nHeight > 364500) ? 86400 : 43200);

src/consensus/params.h

+11
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define BITCOIN_CONSENSUS_PARAMS_H
88

99
#include "uint256.h"
10+
#include "util.h"
1011

1112
namespace Consensus {
1213

@@ -30,6 +31,16 @@ struct Params {
3031
int BlockV10Height;
3132
/** Block height at which v11 blocks are created */
3233
int BlockV11Height;
34+
/** Block height at which v12 blocks are created */
35+
int BlockV12Height;
36+
/** The fraction of rewards taken as fees in an MRC after the zero payment interval. Only consesnus critical
37+
* at BlockV12Height or above.
38+
*/
39+
Fraction InitialMRCFeeFractionPostZeroInterval;
40+
/** The amount of time from the last reward payment to a researcher where submitting an MRC will resort in 100%
41+
* forfeiture of fees to the staker and/or foundation. Only consensus critical at BlockV12Height or above.
42+
*/
43+
int64_t MRCZeroPaymentInterval;
3344

3445
uint256 powLimit;
3546
};

src/dbwrapper.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ bool CTxDB::LoadBlockIndex()
396396
pindexNew->nBits = diskindex.nBits;
397397
pindexNew->nNonce = diskindex.nNonce;
398398
pindexNew->m_researcher = diskindex.m_researcher;
399+
pindexNew->m_mrc_researchers = diskindex.m_mrc_researchers;
399400

400401
nBlockCount++;
401402
// Watch for genesis block

src/gridcoin/account.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ class ResearchAccount
197197
//! \return A block height of zero if the account never earned a research
198198
//! reward before.
199199
//!
200-
uint32_t LastRewardHeight() const
200+
int32_t LastRewardHeight() const
201201
{
202202
if (const BlockPtrOption pindex = LastRewardBlock()) {
203203
return (*pindex)->nHeight;

src/gridcoin/beacon.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ bool Beacon::Expired(const int64_t now) const
117117
// Temporary transition to version 2 beacons after the block version 11
118118
// hard-fork:
119119
//
120-
if (m_timestamp <= g_v11_timestamp) {
121-
return now - g_v11_timestamp > 14 * 86400;
122-
}
120+
// if (m_timestamp <= g_v11_timestamp) {
121+
// return now - g_v11_timestamp > 14 * 86400;
122+
// }
123123

124124
return false;
125125
}

src/gridcoin/block_index.h

+9
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ class ResearcherContext
3030
Cpid m_cpid;
3131
int64_t m_research_subsidy;
3232
double m_magnitude;
33+
34+
ADD_SERIALIZE_METHODS;
35+
36+
template <typename Stream, typename Operation>
37+
inline void SerializationOp(Stream& s, Operation ser_action) {
38+
READWRITE(m_cpid);
39+
READWRITE(m_research_subsidy);
40+
READWRITE(m_magnitude);
41+
}
3342
};
3443

3544
//!

src/gridcoin/claim.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ uint256 GetClaimHash(
5959

6060
if (claim.m_version >= 3) {
6161
hasher << coinstake_tx;
62+
63+
if (claim.m_version >= 4) {
64+
hasher << claim.m_mrc_tx_map;
65+
}
6266
}
6367

6468
return hasher.GetHash();
@@ -173,6 +177,10 @@ bool Claim::WellFormed() const
173177
return false;
174178
}
175179

180+
// Note: It is appealing to check the size of m_mrc to ensure within limit of number of MRC outputs; however,
181+
// the limit of the number of MRC outputs is a function of the block version as well as the claim version, so
182+
// this is done exterior to this class in block level validation.
183+
176184
return true;
177185
}
178186

src/gridcoin/claim.h

+18-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Claim : public IContractPayload
3535
//! ensure that the serialization/deserialization routines also handle all
3636
//! of the previous versions.
3737
//!
38-
static constexpr uint32_t CURRENT_VERSION = 3;
38+
static constexpr uint32_t CURRENT_VERSION = 4;
3939

4040
//!
4141
//! \brief The maximum length of a serialized client version in a claim.
@@ -187,6 +187,19 @@ class Claim : public IContractPayload
187187
//!
188188
SuperblockPtr m_superblock;
189189

190+
//!
191+
//! \brief A map of mrc transactions keyed by CPID. There can be only one MRC per CPID
192+
//! in the claim.
193+
//!
194+
std::map<Cpid, uint256> m_mrc_tx_map;
195+
196+
//!
197+
//! \brief This represents the fees taken from the MRC research subsidies that are awarded to the staker.
198+
//! This must be tracked because this value is added to coinstake award for the staker and must be
199+
//! included in the claim validation.
200+
//!
201+
CAmount m_mrc_fees_to_staker;
202+
190203
//!
191204
//! \brief Initialize an empty, invalid reward claim object.
192205
//!
@@ -394,6 +407,10 @@ class Claim : public IContractPayload
394407
{
395408
READWRITE(m_superblock);
396409
}
410+
411+
if (m_version >= 4) {
412+
READWRITE(m_mrc_tx_map);
413+
}
397414
}
398415
}; // Claim
399416
}

src/gridcoin/contract/contract.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "main.h"
88
#include "gridcoin/appcache.h"
99
#include "gridcoin/claim.h"
10+
#include "gridcoin/mrc.h"
1011
#include "gridcoin/contract/contract.h"
1112
#include "gridcoin/contract/handler.h"
1213
#include "gridcoin/beacon.h"
@@ -304,6 +305,7 @@ class Dispatcher
304305

305306
private:
306307
AppCacheContractHandler m_appcache_handler; //<! Temporary.
308+
MRCContractHandler m_mrc_contract_handler; //<! Simple wrapper to do context validation on MRC transactions.
307309
UnknownContractHandler m_unknown_handler; //<! Logs unknown types.
308310

309311
//!
@@ -324,6 +326,7 @@ class Dispatcher
324326
case ContractType::PROTOCOL: return m_appcache_handler;
325327
case ContractType::SCRAPER: return m_appcache_handler;
326328
case ContractType::VOTE: return GetPollRegistry();
329+
case ContractType::MRC: return m_mrc_contract_handler;
327330
default: return m_unknown_handler;
328331
}
329332
}
@@ -765,6 +768,7 @@ Contract::Type Contract::Type::Parse(std::string input)
765768
// Ordered by frequency:
766769
if (input == "claim") return ContractType::CLAIM;
767770
if (input == "beacon") return ContractType::BEACON;
771+
if (input == "mrc") return ContractType::MRC;
768772
if (input == "vote") return ContractType::VOTE;
769773
if (input == "poll") return ContractType::POLL;
770774
if (input == "project") return ContractType::PROJECT;
@@ -780,6 +784,7 @@ std::string Contract::Type::ToString() const
780784
switch (m_value) {
781785
case ContractType::BEACON: return "beacon";
782786
case ContractType::CLAIM: return "claim";
787+
case ContractType::MRC: return "mrc";
783788
case ContractType::MESSAGE: return "message";
784789
case ContractType::POLL: return "poll";
785790
case ContractType::PROJECT: return "project";
@@ -856,6 +861,9 @@ ContractPayload Contract::Body::ConvertFromLegacy(const ContractType type) const
856861
// Claims can only exist in a coinbase transaction and have no
857862
// legacy representation as a contract:
858863
assert(false && "Attempted to convert legacy claim contract.");
864+
case ContractType::MRC:
865+
// MRCs have no legacy representation as a contract.
866+
assert(false && "Attempted to convert non-existent legacy MRC contract.");
859867
case ContractType::MESSAGE:
860868
// The contract system does not map legacy transaction messages
861869
// stored in the CTransaction::hashBoinc field:
@@ -891,6 +899,9 @@ void Contract::Body::ResetType(const ContractType type)
891899
case ContractType::CLAIM:
892900
m_payload.Reset(new Claim());
893901
break;
902+
case ContractType::MRC:
903+
m_payload.Reset(new MRC());
904+
break;
894905
case ContractType::MESSAGE:
895906
m_payload.Reset(new TxMessage());
896907
break;

src/gridcoin/contract/payload.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,14 @@ enum class ContractType
5757
{
5858
UNKNOWN, //!< An invalid, non-standard, or empty contract type.
5959
BEACON, //!< Beacon advertisement or deletion.
60-
CLAIM, //!< Gridcoin block reward claim context.
60+
CLAIM, //!< Gridcoin block reward claim context (also includes bound MRCs paid as a delegated stake).
6161
MESSAGE, //!< A user-supplied string. No associated protocol behavior.
6262
POLL, //!< Submission of a new poll.
6363
PROJECT, //!< Project whitelist addition or removal.
6464
PROTOCOL, //!< Network control message or configuration directive.
6565
SCRAPER, //!< Scraper node authorization grants and revocations.
6666
VOTE, //!< A vote cast by a wallet for a poll.
67+
MRC, //!< A manual rewards claim (MRC) request to pay rewards
6768
OUT_OF_BOUND, //!< Marker value for the end of the valid range.
6869
};
6970

0 commit comments

Comments
 (0)