From e9d19e5138adf0f79ef1124dc1a2c3aa22f22426 Mon Sep 17 00:00:00 2001 From: Pasta Date: Thu, 22 Nov 2018 23:03:50 -0600 Subject: [PATCH 1/6] Implement optional CoinControl for gobject prepare --- src/rpc/governance.cpp | 23 ++++++++++++++++++++--- src/wallet/wallet.cpp | 10 +++++++--- src/wallet/wallet.h | 2 +- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/rpc/governance.cpp b/src/rpc/governance.cpp index 7c9e7f45a5e8..5eb02f22f290 100644 --- a/src/rpc/governance.cpp +++ b/src/rpc/governance.cpp @@ -133,12 +133,15 @@ void gobject_prepare_help() "3. time (numeric, required) time this object was created\n" "4. data-hex (string, required) data in hex string form\n" "5. use-IS (boolean, optional, default=false) InstantSend lock the collateral, only requiring one chain confirmation\n" + "6. outputHash (string, optional) the single output to submit the fee from\n" + "7. outputIndex (numeric, optional) The output index.\n" ); + ); } UniValue gobject_prepare(const JSONRPCRequest& request) { - if (request.fHelp || (request.params.size() != 5 && request.params.size() != 6)) + if (request.fHelp || (request.params.size() != 5 && request.params.size() != 6 && request.params.size() != 8)) gobject_prepare_help(); if (!EnsureWalletIsAvailable(request.fHelp)) @@ -199,9 +202,23 @@ UniValue gobject_prepare(const JSONRPCRequest& request) EnsureWalletIsUnlocked(); + // If specified, spend this outpoint as the fee + COutPoint outpoint; + outpoint.SetNull(); + if (request.params.size() == 8) { + uint256 collateralHash = ParseHashV(request.params[6], "outputHash"); + int32_t collateralIndex = ParseInt32V(request.params[7], "outputIndex"); + if (collateralHash.IsNull() || collateralIndex < 0) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("invalid hash or index: %s-%d", collateralHash.ToString(), collateralIndex)); + } + outpoint = COutPoint(collateralHash, (uint32_t)collateralIndex); + } + CWalletTx wtx; - if (!pwalletMain->GetBudgetSystemCollateralTX(wtx, govobj.GetHash(), govobj.GetMinCollateralFee(), useIS)) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Error making collateral transaction for governance object. Please check your wallet balance and make sure your wallet is unlocked."); + if (!pwalletMain->GetBudgetSystemCollateralTX(wtx, govobj.GetHash(), govobj.GetMinCollateralFee(), useIS, outpoint)) { + std::string err = "Error making collateral transaction for governance object. Please check your wallet balance and make sure your wallet is unlocked."; + if (request.params.size() == 7) err += "Please verify your specified output is valid and is enough for the combined proposal fee and transaction fee."; + throw JSONRPCError(RPC_INTERNAL_ERROR, err); } // -- make our change address diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ca9b51d1e41a..39f3502cc18c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3356,7 +3356,7 @@ bool CWallet::CreateCollateralTransaction(CMutableTransaction& txCollateral, std return true; } -bool CWallet::GetBudgetSystemCollateralTX(CWalletTx& tx, uint256 hash, CAmount amount, bool fUseInstantSend) +bool CWallet::GetBudgetSystemCollateralTX(CWalletTx& tx, uint256 hash, CAmount amount, bool fUseInstantSend, COutPoint outpoint) { // make our change address CReserveKey reservekey(this); @@ -3370,8 +3370,12 @@ bool CWallet::GetBudgetSystemCollateralTX(CWalletTx& tx, uint256 hash, CAmount a std::vector< CRecipient > vecSend; vecSend.push_back((CRecipient){scriptChange, amount, false}); - CCoinControl *coinControl=NULL; - bool success = CreateTransaction(vecSend, tx, reservekey, nFeeRet, nChangePosRet, strFail, coinControl, true, ALL_COINS, fUseInstantSend); + CCoinControl coinControl; + coinControl.SetNull(); + if (!outpoint.IsNull()) { + coinControl.Select(outpoint); + } + bool success = CreateTransaction(vecSend, tx, reservekey, nFeeRet, nChangePosRet, strFail, &coinControl, true, ALL_COINS, fUseInstantSend); if(!success){ LogPrintf("CWallet::GetBudgetSystemCollateralTX -- Error: %s\n", strFail); return false; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d17e8e957490..f97500f61205 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -922,7 +922,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface CAmount GetNeedsToBeAnonymizedBalance(CAmount nMinBalance = 0) const; CAmount GetDenominatedBalance(bool unconfirmed=false) const; - bool GetBudgetSystemCollateralTX(CWalletTx& tx, uint256 hash, CAmount amount, bool fUseInstantSend); + bool GetBudgetSystemCollateralTX(CWalletTx& tx, uint256 hash, CAmount amount, bool fUseInstantSend, COutPoint outpoint=COutPoint()/*defaults null*/); /** * Insert additional inputs into the transaction by From 50f5adf068e18ee66cddfb80cd05383efc376bca Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Mon, 26 Nov 2018 16:54:20 -0600 Subject: [PATCH 2/6] Removes duplicate `);` from merge error Co-Authored-By: PastaPastaPasta --- src/rpc/governance.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rpc/governance.cpp b/src/rpc/governance.cpp index 5eb02f22f290..0301dd3dd715 100644 --- a/src/rpc/governance.cpp +++ b/src/rpc/governance.cpp @@ -136,7 +136,6 @@ void gobject_prepare_help() "6. outputHash (string, optional) the single output to submit the fee from\n" "7. outputIndex (numeric, optional) The output index.\n" ); - ); } UniValue gobject_prepare(const JSONRPCRequest& request) From c510880e7584a64a453e9b392b90ee7937423abf Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 26 Nov 2018 16:57:58 -0600 Subject: [PATCH 3/6] Fix equality check allowing more relevant help output --- src/rpc/governance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/governance.cpp b/src/rpc/governance.cpp index 0301dd3dd715..97cc38452336 100644 --- a/src/rpc/governance.cpp +++ b/src/rpc/governance.cpp @@ -216,7 +216,7 @@ UniValue gobject_prepare(const JSONRPCRequest& request) CWalletTx wtx; if (!pwalletMain->GetBudgetSystemCollateralTX(wtx, govobj.GetHash(), govobj.GetMinCollateralFee(), useIS, outpoint)) { std::string err = "Error making collateral transaction for governance object. Please check your wallet balance and make sure your wallet is unlocked."; - if (request.params.size() == 7) err += "Please verify your specified output is valid and is enough for the combined proposal fee and transaction fee."; + if (request.params.size() == 8) err += "Please verify your specified output is valid and is enough for the combined proposal fee and transaction fee."; throw JSONRPCError(RPC_INTERNAL_ERROR, err); } From bfab0972d3a899f1c4269d32be8a4ef67da20cb6 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Mon, 26 Nov 2018 17:30:26 -0600 Subject: [PATCH 4/6] Pass COutPoint as const reference Co-Authored-By: PastaPastaPasta --- src/wallet/wallet.cpp | 2 +- src/wallet/wallet.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 39f3502cc18c..f05097a16e5f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3356,7 +3356,7 @@ bool CWallet::CreateCollateralTransaction(CMutableTransaction& txCollateral, std return true; } -bool CWallet::GetBudgetSystemCollateralTX(CWalletTx& tx, uint256 hash, CAmount amount, bool fUseInstantSend, COutPoint outpoint) +bool CWallet::GetBudgetSystemCollateralTX(CWalletTx& tx, uint256 hash, CAmount amount, bool fUseInstantSend, const COutPoint& outpoint) { // make our change address CReserveKey reservekey(this); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index f97500f61205..2e07ac69f89e 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -922,7 +922,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface CAmount GetNeedsToBeAnonymizedBalance(CAmount nMinBalance = 0) const; CAmount GetDenominatedBalance(bool unconfirmed=false) const; - bool GetBudgetSystemCollateralTX(CWalletTx& tx, uint256 hash, CAmount amount, bool fUseInstantSend, COutPoint outpoint=COutPoint()/*defaults null*/); + bool GetBudgetSystemCollateralTX(CWalletTx& tx, uint256 hash, CAmount amount, bool fUseInstantSend, const COutPoint& outpoint=COutPoint()/*defaults null*/); /** * Insert additional inputs into the transaction by From 1ed0ae8d753bec3b1d89272917da538adaea8c28 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Tue, 27 Nov 2018 08:31:40 -0600 Subject: [PATCH 5/6] Remove unnecessary SetNull call Co-Authored-By: PastaPastaPasta --- src/wallet/wallet.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f05097a16e5f..f1bb0b4ccec4 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3371,7 +3371,6 @@ bool CWallet::GetBudgetSystemCollateralTX(CWalletTx& tx, uint256 hash, CAmount a vecSend.push_back((CRecipient){scriptChange, amount, false}); CCoinControl coinControl; - coinControl.SetNull(); if (!outpoint.IsNull()) { coinControl.Select(outpoint); } From 8598ff00db0786cd1994fd69c751c321b8f88f6a Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 27 Nov 2018 11:08:42 -0600 Subject: [PATCH 6/6] Specify proposal fee Co-Authored-By: PastaPastaPasta --- src/rpc/governance.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/governance.cpp b/src/rpc/governance.cpp index 97cc38452336..704582f49940 100644 --- a/src/rpc/governance.cpp +++ b/src/rpc/governance.cpp @@ -133,7 +133,7 @@ void gobject_prepare_help() "3. time (numeric, required) time this object was created\n" "4. data-hex (string, required) data in hex string form\n" "5. use-IS (boolean, optional, default=false) InstantSend lock the collateral, only requiring one chain confirmation\n" - "6. outputHash (string, optional) the single output to submit the fee from\n" + "6. outputHash (string, optional) the single output to submit the proposal fee from\n" "7. outputIndex (numeric, optional) The output index.\n" ); } @@ -201,7 +201,7 @@ UniValue gobject_prepare(const JSONRPCRequest& request) EnsureWalletIsUnlocked(); - // If specified, spend this outpoint as the fee + // If specified, spend this outpoint as the proposal fee COutPoint outpoint; outpoint.SetNull(); if (request.params.size() == 8) {