Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refactor] Combine parameter checking of budget commands #964

Merged
merged 1 commit into from
Aug 3, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 54 additions & 72 deletions src/rpc/budget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,73 +48,85 @@ void budgetToJSON(CBudgetProposal* pbudgetProposal, UniValue& bObj)
bObj.push_back(Pair("fValid", pbudgetProposal->fValid));
}

UniValue preparebudget(const UniValue& params, bool fHelp)
void checkBudgetInputs(const UniValue& params, std::string &strProposalName, std::string &strURL,
int &nPaymentCount, int &nBlockStart, CBitcoinAddress &address, CAmount &nAmount)
{
int nBlockMin = 0;
CBlockIndex* pindexPrev = chainActive.Tip();
Warrows marked this conversation as resolved.
Show resolved Hide resolved

if (fHelp || params.size() != 6)
throw std::runtime_error(
"preparebudget \"proposal-name\" \"url\" payment-count block-start \"pivx-address\" monthly-payment\n"
"\nPrepare proposal for network by signing and creating tx\n"

"\nArguments:\n"
"1. \"proposal-name\": (string, required) Desired proposal name (20 character limit)\n"
"2. \"url\": (string, required) URL of proposal details (64 character limit)\n"
"3. payment-count: (numeric, required) Total number of monthly payments\n"
"4. block-start: (numeric, required) Starting super block height\n"
"5. \"pivx-address\": (string, required) PIVX address to send payments to\n"
"6. monthly-payment: (numeric, required) Monthly payment amount\n"

"\nResult:\n"
"\"xxxx\" (string) proposal fee hash (if successful) or error message (if failed)\n"

"\nExamples:\n" +
HelpExampleCli("preparebudget", "\"test-proposal\" \"https://forum.pivx.org/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500") +
HelpExampleRpc("preparebudget", "\"test-proposal\" \"https://forum.pivx.org/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500"));

LOCK2(cs_main, pwalletMain->cs_wallet);

EnsureWalletIsUnlocked();

std::string strProposalName = SanitizeString(params[0].get_str());
strProposalName = SanitizeString(params[0].get_str());
if (strProposalName.size() > 20)
throw std::runtime_error("Invalid proposal name, limit of 20 characters.");

std::string strURL = SanitizeString(params[1].get_str());
strURL = SanitizeString(params[1].get_str());
if (strURL.size() > 64)
throw std::runtime_error("Invalid url, limit of 64 characters.");

int nPaymentCount = params[2].get_int();
nPaymentCount = params[2].get_int();
if (nPaymentCount < 1)
throw std::runtime_error("Invalid payment count, must be more than zero.");

// Start must be in the next budget cycle
if (pindexPrev != NULL) nBlockMin = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetBudgetCycleBlocks() + Params().GetBudgetCycleBlocks();

int nBlockStart = params[3].get_int();
nBlockStart = params[3].get_int();
if (nBlockStart % Params().GetBudgetCycleBlocks() != 0) {
int nNext = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetBudgetCycleBlocks() + Params().GetBudgetCycleBlocks();
throw std::runtime_error(strprintf("Invalid block start - must be a budget cycle block. Next valid block: %d", nNext));
}

int nBlockEnd = nBlockStart + Params().GetBudgetCycleBlocks() * nPaymentCount; // End must be AFTER current cycle
int nBlockEnd = nBlockStart + (Params().GetBudgetCycleBlocks() * nPaymentCount); // End must be AFTER current cycle

if (nBlockStart < nBlockMin)
throw std::runtime_error("Invalid block start, must be more than current height.");

if (nBlockEnd < pindexPrev->nHeight)
throw std::runtime_error("Invalid ending block, starting block + (payment_cycle*payments) must be more than current height.");

CBitcoinAddress address(params[4].get_str());
address = params[4].get_str();
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid PIVX address");

nAmount = AmountFromValue(params[5]);
}

UniValue preparebudget(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 6)
throw std::runtime_error(
"preparebudget \"proposal-name\" \"url\" payment-count block-start \"pivx-address\" monthy-payment\n"
"\nPrepare proposal for network by signing and creating tx\n"

"\nArguments:\n"
"1. \"proposal-name\": (string, required) Desired proposal name (20 character limit)\n"
"2. \"url\": (string, required) URL of proposal details (64 character limit)\n"
"3. payment-count: (numeric, required) Total number of monthly payments\n"
"4. block-start: (numeric, required) Starting super block height\n"
"5. \"pivx-address\": (string, required) PIVX address to send payments to\n"
"6. monthly-payment: (numeric, required) Monthly payment amount\n"

"\nResult:\n"
"\"xxxx\" (string) proposal fee hash (if successful) or error message (if failed)\n"

"\nExamples:\n" +
HelpExampleCli("preparebudget", "\"test-proposal\" \"https://forum.pivx.org/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500") +
HelpExampleRpc("preparebudget", "\"test-proposal\" \"https://forum.pivx.org/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500"));

LOCK2(cs_main, pwalletMain->cs_wallet);
random-zebra marked this conversation as resolved.
Show resolved Hide resolved

EnsureWalletIsUnlocked();

std::string strProposalName;
std::string strURL;
int nPaymentCount;
int nBlockStart;
CBitcoinAddress address;
CAmount nAmount;

checkBudgetInputs(params, strProposalName, strURL, nPaymentCount, nBlockStart, address, nAmount);

// Parse PIVX address
CScript scriptPubKey = GetScriptForDestination(address.Get());
CAmount nAmount = AmountFromValue(params[5]);

//*************************************************************************

// create transaction 15 minutes into the future, to allow for confirmation time
CBudgetProposalBroadcast budgetProposalBroadcast(strProposalName, strURL, nPaymentCount, scriptPubKey, nAmount, nBlockStart, 0);
Expand Down Expand Up @@ -145,9 +157,6 @@ UniValue preparebudget(const UniValue& params, bool fHelp)

UniValue submitbudget(const UniValue& params, bool fHelp)
{
int nBlockMin = 0;
CBlockIndex* pindexPrev = chainActive.Tip();

if (fHelp || params.size() != 7)
throw std::runtime_error(
"submitbudget \"proposal-name\" \"url\" payment-count block-start \"pivx-address\" monthly-payment \"fee-tx\"\n"
Expand All @@ -169,45 +178,18 @@ UniValue submitbudget(const UniValue& params, bool fHelp)
HelpExampleCli("submitbudget", "\"test-proposal\" \"https://forum.pivx.org/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500") +
HelpExampleRpc("submitbudget", "\"test-proposal\" \"https://forum.pivx.org/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500"));

// Check these inputs the same way we check the vote commands:
// **********************************************************

std::string strProposalName = SanitizeString(params[0].get_str());
if (strProposalName.size() > 20)
throw std::runtime_error("Invalid proposal name, limit of 20 characters.");

std::string strURL = SanitizeString(params[1].get_str());
if (strURL.size() > 64)
throw std::runtime_error("Invalid url, limit of 64 characters.");

int nPaymentCount = params[2].get_int();
if (nPaymentCount < 1)
throw std::runtime_error("Invalid payment count, must be more than zero.");

// Start must be in the next budget cycle
if (pindexPrev != NULL) nBlockMin = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetBudgetCycleBlocks() + Params().GetBudgetCycleBlocks();

int nBlockStart = params[3].get_int();
if (nBlockStart % Params().GetBudgetCycleBlocks() != 0) {
int nNext = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetBudgetCycleBlocks() + Params().GetBudgetCycleBlocks();
throw std::runtime_error(strprintf("Invalid block start - must be a budget cycle block. Next valid block: %d", nNext));
}

int nBlockEnd = nBlockStart + (Params().GetBudgetCycleBlocks() * nPaymentCount); // End must be AFTER current cycle
std::string strProposalName;
std::string strURL;
int nPaymentCount;
int nBlockStart;
CBitcoinAddress address;
CAmount nAmount;

if (nBlockStart < nBlockMin)
throw std::runtime_error("Invalid block start, must be more than current height.");

if (nBlockEnd < pindexPrev->nHeight)
throw std::runtime_error("Invalid ending block, starting block + (payment_cycle*payments) must be more than current height.");

CBitcoinAddress address(params[4].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid PIVX address");
checkBudgetInputs(params, strProposalName, strURL, nPaymentCount, nBlockStart, address, nAmount);

// Parse PIVX address
CScript scriptPubKey = GetScriptForDestination(address.Get());
CAmount nAmount = AmountFromValue(params[5]);

uint256 hash = ParseHashV(params[6], "parameter 1");

//create the proposal incase we're the first to make it
Expand Down