Skip to content

Commit

Permalink
Implementation of getmrcinfo
Browse files Browse the repository at this point in the history
This provides an rpc command to get a summary and if desired details
of MRC payments.
  • Loading branch information
jamescowens committed Sep 4, 2022
1 parent a9dddc0 commit a92ae13
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3108,7 +3108,7 @@ GRC::MRCFees CBlock::GetMRCFees() const EXCLUSIVE_LOCKS_REQUIRED(cs_main)

Fraction foundation_fee_fraction = FoundationSideStakeAllocation();

const GRC::Claim claim = NCONST_PTR(this)->PullClaim();
const GRC::Claim claim = GetClaim();

CAmount mrc_total_fees = 0;

Expand Down
159 changes: 159 additions & 0 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,165 @@ UniValue dumpcontracts(const UniValue& params, bool fHelp)
return report;
}

UniValue getmrcinfo(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() > 3)
throw runtime_error(
"getmrcinfo [detailed MRC info [low height [high height]]]\n"
"\n"
"[detailed MRC info]: optional boolean to output MRC details.\n"
" Defaults to false.\n"
"[low height]: optional low height for scope.\n"
" Defaults to V12 block height.\n"
"[high height]: optional high height for scope.\n"
" Defaults to current block.\n"
);

bool output_mrc_details = false;

if (params.size() > 0) {
output_mrc_details = params[0].get_bool();
}

// No MRC's below V12 block height.
int low_height = Params().GetConsensus().BlockV12Height;
int high_height = 0;

if (params.size() > 1) {
// If specified low height is lower than V12 height, set to V12 height.
low_height = std::max(params[1].get_int(), low_height);
}

if (params.size() > 2) {
// High height can't be lower than the low height.
high_height = std::max(low_height, params[2].get_int());
}

UniValue report(UniValue::VOBJ);
UniValue block_output_array(UniValue::VARR);

uint64_t total_mrcs_paid = 0;
uint64_t total_mrc_requests = 0;

CAmount mrc_total_research_rewards = 0;
CAmount mrc_total_foundation_fees = 0;
CAmount mrc_total_staker_fees = 0;

CBlock block;
UniValue block_output(UniValue::VOBJ);

LOCK(cs_main);

// Set default high_height here if not specified above now that lock on cs_main is taken.
if (!high_height) {
high_height = pindexBest->nHeight;
}

CBlockIndex* blockindex = pindexBest;

// Rewind to low height.
for (; blockindex; blockindex = blockindex->pprev) {
if (blockindex->nHeight == low_height) break;
}

while (blockindex && blockindex->nHeight <= high_height) {
CAmount mrc_research_rewards = 0;

for (const auto& mrc_context : blockindex->m_mrc_researchers) {
mrc_research_rewards += mrc_context->m_research_subsidy;
}

ReadBlockFromDisk(block, blockindex, Params().GetConsensus());

// Get the claim which is where MRCs are actually paid.
GRC::Claim claim = block.GetClaim();
GRC::MRCFees mrc_fees = block.GetMRCFees();

uint64_t mrcs_paid = claim.m_mrc_tx_map.size(); // This also matches the size of the blockindex->m_mrc_researchers
uint64_t mrc_requests = 0;

if (output_mrc_details) {
UniValue mrc_requests_output_array(UniValue::VARR);

block_output.pushKV("hash", block.GetHash().GetHex());
block_output.pushKV("height", blockindex->nHeight);
block_output.pushKV("mrc_research_rewards", ValueFromAmount(mrc_research_rewards));
block_output.pushKV("mrc_foundation_fees", ValueFromAmount(mrc_fees.m_mrc_foundation_fees));
block_output.pushKV("mrc_staker_fees", ValueFromAmount(mrc_fees.m_mrc_staker_fees));
block_output.pushKV("mrc_net_paid_to_researchers", ValueFromAmount(mrc_research_rewards
- mrc_fees.m_mrc_foundation_fees
- mrc_fees.m_mrc_staker_fees));
block_output.pushKV("mrcs_paid", mrcs_paid);
block_output.pushKV("claim", ClaimToJson(block.GetClaim(), blockindex));

for (const auto& tx : block.vtx) {
for (const auto& contract : tx.GetContracts()) {
// We are only interested in MRC request contracts here.
if (contract.m_type != GRC::ContractType::MRC) continue;

++mrc_requests;

bool mrc_paid_in_claim = false;

for (const auto& iter : claim.m_mrc_tx_map) {
if (tx.GetHash() == iter.second) {
mrc_paid_in_claim = true;
break;
}
}

UniValue mrc_output(UniValue::VOBJ);

mrc_output.pushKV("txid", tx.GetHash().GetHex());
mrc_output.pushKVs(MRCToJson(contract.CopyPayloadAs<GRC::MRC>()));
mrc_output.pushKV("mrc_request_paid", mrc_paid_in_claim);

mrc_requests_output_array.push_back(mrc_output);

} // contracts
} // transaction

block_output.pushKV("mrc_requests", mrc_requests_output_array);
block_output.pushKV("mrc_requests_not_paid", mrc_requests - mrcs_paid);

if (mrc_requests) {
block_output_array.push_back(block_output);
}
} else {
for (const auto& tx : block.vtx) {
for (const auto& contract : tx.GetContracts()) {
// We are only interested in MRC request contracts here.
if (contract.m_type != GRC::ContractType::MRC) continue;

++mrc_requests;
} // contracts
} // transaction
}

mrc_total_foundation_fees += mrc_fees.m_mrc_foundation_fees;
mrc_total_staker_fees += mrc_fees.m_mrc_staker_fees;
total_mrc_requests += mrc_requests;
total_mrcs_paid += mrcs_paid;
mrc_total_research_rewards += mrc_research_rewards;
blockindex = blockindex->pnext;
} // while (pblockindex...)

report.pushKV("total_mrcs_paid", total_mrcs_paid);
report.pushKV("total_mrc_requests", total_mrc_requests);
report.pushKV("total_mrc_requests_not_paid", total_mrc_requests - total_mrcs_paid);
report.pushKV("mrc_total_research_rewards", ValueFromAmount(mrc_total_research_rewards));
report.pushKV("mrc_total_foundation_fees", ValueFromAmount(mrc_total_foundation_fees));
report.pushKV("mrc_total_staker_fees", ValueFromAmount(mrc_total_staker_fees));
report.pushKV("mrc_total_net_paid_to_researchers", ValueFromAmount(mrc_total_research_rewards
- mrc_total_foundation_fees
- mrc_total_staker_fees));
if (output_mrc_details) {
report.pushKV("mrc_details_by_block", block_output_array);
}

return report;
}

UniValue showblock(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 1)
Expand Down
3 changes: 3 additions & 0 deletions src/rpc/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "beaconreport" , 0 },
{ "createmrcrequest" , 0 },
{ "createmrcrequest" , 1 },
{ "getmrcinfo" , 0 },
{ "getmrcinfo" , 1 },
{ "getmrcinfo" , 2 },
{ "superblocks" , 0 },
{ "superblocks" , 1 },

Expand Down
1 change: 1 addition & 0 deletions src/rpc/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ static const CRPCCommand vRPCCommands[] =
{ "createmrcrequest", &createmrcrequest, cat_staking },
{ "explainmagnitude", &explainmagnitude, cat_staking },
{ "getlaststake", &getlaststake, cat_staking },
{ "getmrcinfo", &getmrcinfo, cat_staking },
{ "getstakinginfo", &getstakinginfo, cat_staking },
{ "getmininginfo", &getstakinginfo, cat_staking }, //alias for getstakinginfo (compatibility)
{ "lifetime", &lifetime, cat_staking },
Expand Down
1 change: 1 addition & 0 deletions src/rpc/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ extern UniValue beaconstatus(const UniValue& params, bool fHelp);
extern UniValue createmrcrequest(const UniValue& params, const bool fHelp);
extern UniValue explainmagnitude(const UniValue& params, bool fHelp);
extern UniValue getlaststake(const UniValue& params, bool fHelp);
extern UniValue getmrcinfo(const UniValue& params, bool fHelp);
extern UniValue getstakinginfo(const UniValue& params, bool fHelp);
extern UniValue lifetime(const UniValue& params, bool fHelp);
extern UniValue magnitude(const UniValue& params, bool fHelp);
Expand Down

0 comments on commit a92ae13

Please sign in to comment.