Skip to content

Commit

Permalink
Add sleep in batchvote rpc (#1810)
Browse files Browse the repository at this point in the history
* Add sleep in batchvote rpc

* Reduce time and minor refactor

* Update rpc_proposals.cpp

* Add sleep time parameter for voteGovBatch

* Add description for sleep-time parameter

---------

Co-authored-by: cedric ogire <[email protected]>
  • Loading branch information
prasannavl and cedric ogire authored Mar 17, 2023
1 parent 5201fc4 commit b86cff2
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ void SetupServerArgs()
gArgs.AddArg("-dftxworkers=<n>", strprintf("No. of parallel workers associated with the DfTx related work pool. Stock splits, parallel processing of the chain where appropriate, etc use this worker pool (default: %d)", DEFAULT_DFTX_WORKERS), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
gArgs.AddArg("-maxaddrratepersecond=<n>", strprintf("Sets MAX_ADDR_RATE_PER_SECOND limit for ADDR messages(default: %f)", MAX_ADDR_RATE_PER_SECOND), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
gArgs.AddArg("-maxaddrprocessingtokenbucket=<n>", strprintf("Sets MAX_ADDR_PROCESSING_TOKEN_BUCKET limit for ADDR messages(default: %d)", MAX_ADDR_PROCESSING_TOKEN_BUCKET), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
gArgs.AddArg("-sleep-time=<n>", "Sets sleeping time for voteGovBatch, by default the value is set to 500ms", ArgsManager::ALLOW_ANY, OptionsCategory::HIDDEN);

#if HAVE_DECL_DAEMON
gArgs.AddArg("-daemon", "Run in the background as a daemon and accept commands", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
Expand Down
36 changes: 25 additions & 11 deletions src/masternodes/rpc_proposals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <functional>

const bool DEFAULT_RPC_GOV_NEUTRAL = false;
const int SLEEP_TIME_MILLIS = 500;

struct VotingInfo {
int32_t votesPossible = 0;
Expand Down Expand Up @@ -610,37 +611,43 @@ UniValue votegovbatch(const JSONRPCRequest &request) {
RPCTypeCheck(request.params, {UniValue::VARR}, false);

const auto &keys = request.params[0].get_array();
auto sleepTime = gArgs.GetBoolArg("-sleep-time", SLEEP_TIME_MILLIS);
auto neutralVotesAllowed = gArgs.GetBoolArg("-rpc-governance-accept-neutral", DEFAULT_RPC_GOV_NEUTRAL);

int targetHeight;

struct MasternodeMultiVote {
struct VotingState {
uint256 propId;
uint256 mnId;
CTxDestination dest;
CProposalVoteType type;
};

std::vector<MasternodeMultiVote> mnMultiVotes;
std::vector<VotingState> voteList;
{
CCustomCSView view(*pcustomcsview);

for (size_t i{}; i < keys.size(); ++i) {

const auto &votes{keys[i].get_array()};
if (votes.size() != 3) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Incorrect number of items, three expected, proposal ID, masternode ID and vote expected. %d entries provided.", votes.size()));
throw JSONRPCError(RPC_INVALID_PARAMETER,
strprintf("Incorrect number of items, three expected, proposal ID, masternode ID and vote expected. %d entries provided.",
votes.size()));
}

const auto propId = ParseHashV(votes[0].get_str(), "proposalId");
const auto prop = view.GetProposal(propId);
if (!prop) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Proposal <%s> does not exist", propId.GetHex()));
throw JSONRPCError(RPC_INVALID_PARAMETER,
strprintf("Proposal <%s> does not exist",
propId.GetHex()));
}

if (prop->status != CProposalStatusType::Voting) {
throw JSONRPCError(RPC_INVALID_PARAMETER,
strprintf("Proposal <%s> is not in voting period", propId.GetHex()));
strprintf("Proposal <%s> is not in voting period",
propId.GetHex()));
}

uint256 mnId;
Expand All @@ -652,15 +659,16 @@ UniValue votegovbatch(const JSONRPCRequest &request) {
const CTxDestination dest = DecodeDestination(id);
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_PARAMETER,
strprintf("The masternode id or address is not valid: %s", id));
strprintf("The masternode id or address is not valid: %s", id));
}
CKeyID ckeyId;
if (dest.index() == PKHashType) {
ckeyId = CKeyID(std::get<PKHash>(dest));
} else if (dest.index() == WitV0KeyHashType) {
ckeyId = CKeyID(std::get<WitnessV0KeyHash>(dest));
} else {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s does not refer to a P2PKH or P2WPKH address", id));
throw JSONRPCError(RPC_INVALID_PARAMETER,
strprintf("%s does not refer to a P2PKH or P2WPKH address", id));
}
if (auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId)) {
mnId = masterNodeIdByOwner.value();
Expand All @@ -672,7 +680,7 @@ UniValue votegovbatch(const JSONRPCRequest &request) {
const auto node = view.GetMasternode(mnId);
if (!node) {
throw JSONRPCError(RPC_INVALID_PARAMETER,
strprintf("The masternode does not exist or the address doesn't own a masternode: %s", id));
strprintf("The masternode does not exist or the address doesn't own a masternode: %s", id));
}

auto vote = CProposalVoteType::VoteNeutral;
Expand All @@ -688,10 +696,11 @@ UniValue votegovbatch(const JSONRPCRequest &request) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Decision supports yes or no. Neutral is currently disabled because of issue https://github.com/DeFiCh/ain/issues/1704");
}

mnMultiVotes.push_back({
voteList.push_back({
propId,
mnId,
node->ownerType == 1 ? CTxDestination(PKHash(node->ownerAuthAddress)) : CTxDestination(WitnessV0KeyHash(node->ownerAuthAddress)),
node->ownerType == 1 ? CTxDestination(PKHash(node->ownerAuthAddress)) :
CTxDestination(WitnessV0KeyHash(node->ownerAuthAddress)),
vote
});
}
Expand All @@ -701,7 +710,7 @@ UniValue votegovbatch(const JSONRPCRequest &request) {

UniValue ret(UniValue::VARR);

for (const auto& [propId, mnId, ownerDest, vote] : mnMultiVotes) {
for (const auto& [propId, mnId, ownerDest, vote] : voteList) {

CProposalVoteMessage msg;
msg.propId = propId;
Expand Down Expand Up @@ -734,6 +743,11 @@ UniValue votegovbatch(const JSONRPCRequest &request) {
execTestTx(CTransaction(rawTx), targetHeight, optAuthTx);

ret.push_back(signsend(rawTx, pwallet, optAuthTx)->GetHash().GetHex());
// Sleep the RPC worker thread a bit, so that the node can
// relay the TXs as it works through. Otherwise, the main
// chain can be locked for too long that prevent broadcasting of
// TXs
std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
}

return ret;
Expand Down

0 comments on commit b86cff2

Please sign in to comment.