Skip to content

Commit

Permalink
Adds coin select flags to defid with option to override from CLI (#1820)
Browse files Browse the repository at this point in the history
* Support optional bool args, support coin select defaults on defid

* Switch FromHeader to no overwrite

* Use compiler flag to determine if running defi-cli or defid

* Fix coinSelectOpts logic for optional bool

* Simplify access logic

* Add metadata default in JSONRPCRequest initialization list

* Pass coin select opts all the way through

* Put CoinSelectOption variables private

---------

Co-authored-by: Prasanna Loganathar <[email protected]>
Co-authored-by: cedric ogire <[email protected]>
  • Loading branch information
3 people authored Mar 17, 2023
1 parent 198855c commit b781611
Show file tree
Hide file tree
Showing 17 changed files with 162 additions and 136 deletions.
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ defid_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS
# defi-cli binary #
defi_cli_SOURCES = defi-cli.cpp
defi_cli_CPPFLAGS = $(AM_CPPFLAGS) $(DEFI_INCLUDES) $(EVENT_CFLAGS)
defi_cli_CPPFLAGS += -DDEFI_CLI
defi_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
defi_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)

Expand Down
1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,7 @@ void SetupServerArgs()
hidden_args.emplace_back("-daemon");
#endif

RPCMetadata::SetupArgs(gArgs);
// Add the hidden options
gArgs.AddHiddenArgs(hidden_args);
}
Expand Down
31 changes: 23 additions & 8 deletions src/masternodes/coinselect.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define DEFI_MASTERNODES_COINSELECT_H

#include <util/system.h>
#include <optional>

/** Default for skipping IsSolvable and return on first valid auth */
static const bool DEFAULT_COIN_SELECT_FAST_SELECT = false;
Expand All @@ -20,10 +21,15 @@ static const std::string& ARG_STR_WALLET_COIN_OPT_SKIP_SOLVABLE = "-walletcoinop
static const std::string& ARG_STR_WALLET_COIN_OPT_EAGER_SELECT = "-walletcoinopteagerselect";

struct CoinSelectionOptions {
private:
std::optional<bool> fastSelect{};
std::optional<bool> skipSolvable{};
std::optional<bool> eagerSelect{};

public:
bool fastSelect{};
bool skipSolvable{};
bool eagerSelect{};
bool IsFastSelectEnabled() const { return fastSelect.value_or(false); }
bool IsSkipSolvableEnabled() const { return skipSolvable.value_or(false); }
bool IsEagerSelectEnabled() const { return eagerSelect.value_or(false); }

static void SetupArgs(ArgsManager& args) {
args.AddArg(ARG_STR_WALLET_FAST_SELECT, strprintf("Faster coin select - Enables walletcoinoptskipsolvable and walletcoinopteagerselect. This ends up in faster selection but has the disadvantage of not being able to pick complex input scripts (default: %u)", DEFAULT_COIN_SELECT_FAST_SELECT), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
Expand All @@ -37,9 +43,10 @@ struct CoinSelectionOptions {
return opts;
}


static void FromArgs(CoinSelectionOptions& m, ArgsManager& args) {
struct V {
bool& target;
std::optional<bool>& target;
const std::string& arg;
const bool& def;
};
Expand All @@ -48,13 +55,20 @@ struct CoinSelectionOptions {
V { m.skipSolvable, ARG_STR_WALLET_COIN_OPT_SKIP_SOLVABLE, DEFAULT_COIN_SELECT_SKIP_SOLVABLE},
V { m.eagerSelect, ARG_STR_WALLET_COIN_OPT_EAGER_SELECT, DEFAULT_COIN_SELECT_EAGER_SELECT},
}) {
v = args.GetBoolArg(str, def);
// If it's defid, respond with defaults.
// If it's defi-cli, just skip init unless it's provided,
// so we just directly call GetOptionalBoolArg
#ifdef DEFI_CLI
v = args.GetOptionalBoolArg(str);
#else
v = args.GetBoolArg(str, def);
#endif
}
}

static void FromHTTPHeader(CoinSelectionOptions &m, const HTTPHeaderQueryFunc headerFunc) {
struct V {
bool& target;
std::optional<bool>& target;
const std::string& arg;
};
for (auto &[v, str]: {
Expand All @@ -69,15 +83,16 @@ struct CoinSelectionOptions {

static void ToHTTPHeader(const CoinSelectionOptions& m, const HTTPHeaderWriterFunc writer) {
struct V {
const bool& val;
const std::optional<bool>& val;
const std::string& arg;
};
for (auto &[v, str]: {
V { m.fastSelect, ARG_STR_WALLET_FAST_SELECT},
V { m.skipSolvable, ARG_STR_WALLET_COIN_OPT_SKIP_SOLVABLE},
V { m.eagerSelect, ARG_STR_WALLET_COIN_OPT_EAGER_SELECT},
}) {
writer("x" + str, v ? "1" : "0");
if (!v) continue;
writer("x" + str, *v ? "1" : "0");
}
}
};
Expand Down
24 changes: 14 additions & 10 deletions src/masternodes/mn_rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,11 @@ static std::optional<CTxIn> GetAuthInputOnly(CWalletCoinsUnlocker& pwallet, CTxD
return txin;
}

static CTransactionRef CreateAuthTx(CWalletCoinsUnlocker& pwallet, std::set<CScript> const & auths, int32_t txVersion) {
static CTransactionRef CreateAuthTx(CWalletCoinsUnlocker& pwallet,
std::set<CScript> const & auths,
int32_t txVersion,
const CoinSelectionOptions &coinSelectOpts) {

CMutableTransaction mtx(txVersion);
CCoinControl coinControl;

Expand All @@ -337,7 +341,7 @@ static CTransactionRef CreateAuthTx(CWalletCoinsUnlocker& pwallet, std::set<CScr
// Create output to cover 1KB transaction
CTxOut authOut(GetMinimumFee(*pwallet, 1000, coinControl, nullptr), auth);
mtx.vout.push_back(authOut);
fund(mtx, pwallet, {}, &coinControl);
fund(mtx, pwallet, {}, &coinControl, coinSelectOpts);

// AutoAuthPrep, auth output and change
if (mtx.vout.size() == 3) {
Expand All @@ -356,7 +360,7 @@ static CTransactionRef CreateAuthTx(CWalletCoinsUnlocker& pwallet, std::set<CScr
mtx.vout.push_back(authOut);
}

return fund(mtx, pwallet, {}, &coinControl), sign(mtx, pwallet, {});
return fund(mtx, pwallet, {}, &coinControl, coinSelectOpts), sign(mtx, pwallet, {});
}

static std::optional<CTxIn> GetAnyFoundationAuthInput(CWalletCoinsUnlocker& pwallet) {
Expand Down Expand Up @@ -428,7 +432,7 @@ std::vector<CTxIn> GetAuthInputsSmart(CWalletCoinsUnlocker& pwallet, int32_t txV
// at last, create additional tx for missed
if (!notFoundYet.empty()) {
try {
optAuthTx = CreateAuthTx(pwallet, notFoundYet, txVersion); // success or throw
optAuthTx = CreateAuthTx(pwallet, notFoundYet, txVersion, coinSelectOpts); // success or throw
} catch (const UniValue& objError) {
throw JSONRPCError(objError["code"].get_int(), "Add-on auth TX failed: " + objError["message"].getValStr());
}
Expand Down Expand Up @@ -593,7 +597,7 @@ UniValue setgov(const JSONRPCRequest& request) {
UniValue const & txInputs = request.params[1];
CTransactionRef optAuthTx;
std::set<CScript> auths;
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, true /*needFoundersAuth*/, optAuthTx, txInputs);
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, true, optAuthTx, txInputs, request.metadata.coinSelectOpts);

CCoinControl coinControl;

Expand All @@ -606,7 +610,7 @@ UniValue setgov(const JSONRPCRequest& request) {
}
}

fund(rawTx, pwallet, optAuthTx, &coinControl);
fund(rawTx, pwallet, optAuthTx, &coinControl, request.metadata.coinSelectOpts);

// check execution
execTestTx(CTransaction(rawTx), targetHeight, optAuthTx);
Expand Down Expand Up @@ -685,7 +689,7 @@ UniValue unsetgov(const JSONRPCRequest& request) {
UniValue const & txInputs = request.params[1];
CTransactionRef optAuthTx;
std::set<CScript> auths;
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, true /*needFoundersAuth*/, optAuthTx, txInputs);
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, true, optAuthTx, txInputs, request.metadata.coinSelectOpts);

CCoinControl coinControl;

Expand All @@ -698,7 +702,7 @@ UniValue unsetgov(const JSONRPCRequest& request) {
}
}

fund(rawTx, pwallet, optAuthTx, &coinControl);
fund(rawTx, pwallet, optAuthTx, &coinControl, request.metadata.coinSelectOpts);

// check execution
execTestTx(CTransaction(rawTx), targetHeight, optAuthTx);
Expand Down Expand Up @@ -807,7 +811,7 @@ UniValue setgovheight(const JSONRPCRequest& request) {
UniValue const & txInputs = request.params[2];
CTransactionRef optAuthTx;
std::set<CScript> auths;
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, true /*needFoundersAuth*/, optAuthTx, txInputs);
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, true, optAuthTx, txInputs, request.metadata.coinSelectOpts);

CCoinControl coinControl;

Expand All @@ -820,7 +824,7 @@ UniValue setgovheight(const JSONRPCRequest& request) {
}
}

fund(rawTx, pwallet, optAuthTx, &coinControl);
fund(rawTx, pwallet, optAuthTx, &coinControl, request.metadata.coinSelectOpts);

// check execution
execTestTx(CTransaction(rawTx), targetHeight, optAuthTx);
Expand Down
28 changes: 14 additions & 14 deletions src/masternodes/rpc_accounts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ UniValue utxostoaccount(const JSONRPCRequest& request) {
}

// fund
fund(rawTx, pwallet, {});
fund(rawTx, pwallet, {}, nullptr, request.metadata.coinSelectOpts);

// check execution
execTestTx(CTransaction(rawTx), targetHeight);
Expand Down Expand Up @@ -806,7 +806,7 @@ UniValue accounttoaccount(const JSONRPCRequest& request) {

CTransactionRef optAuthTx;
std::set<CScript> auths{msg.from};
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, false /*needFoundersAuth*/, optAuthTx, txInputs);
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, false, optAuthTx, txInputs, request.metadata.coinSelectOpts);

CCoinControl coinControl;

Expand All @@ -818,7 +818,7 @@ UniValue accounttoaccount(const JSONRPCRequest& request) {
}

// fund
fund(rawTx, pwallet, optAuthTx, &coinControl);
fund(rawTx, pwallet, optAuthTx, &coinControl, request.metadata.coinSelectOpts);

// check execution
execTestTx(CTransaction(rawTx), targetHeight, optAuthTx);
Expand Down Expand Up @@ -911,7 +911,7 @@ UniValue accounttoutxos(const JSONRPCRequest& request) {
const UniValue &txInputs = request.params[2];
CTransactionRef optAuthTx;
std::set<CScript> auths{msg.from};
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, false /*needFoundersAuth*/, optAuthTx, txInputs);
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, false, optAuthTx, txInputs, request.metadata.coinSelectOpts);

CCoinControl coinControl;

Expand All @@ -923,7 +923,7 @@ UniValue accounttoutxos(const JSONRPCRequest& request) {
}

// fund
fund(rawTx, pwallet, optAuthTx, &coinControl);
fund(rawTx, pwallet, optAuthTx, &coinControl, request.metadata.coinSelectOpts);

// re-encode with filled mintingOutputsStart
{
Expand Down Expand Up @@ -1909,7 +1909,7 @@ UniValue sendtokenstoaddress(const JSONRPCRequest& request) {
auths.emplace(acc.first);
}
CTransactionRef optAuthTx;
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, false /*needFoundersAuth*/, optAuthTx, txInputs);
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auths, false, optAuthTx, txInputs, request.metadata.coinSelectOpts);

CCoinControl coinControl;

Expand All @@ -1923,7 +1923,7 @@ UniValue sendtokenstoaddress(const JSONRPCRequest& request) {
}

// fund
fund(rawTx, pwallet, optAuthTx, &coinControl);
fund(rawTx, pwallet, optAuthTx, &coinControl, request.metadata.coinSelectOpts);

// check execution
execTestTx(CTransaction(rawTx), targetHeight, optAuthTx);
Expand Down Expand Up @@ -2192,7 +2192,7 @@ UniValue HandleSendDFIP2201DFIInput(const JSONRPCRequest& request, CWalletCoinsU
coinControl.matchDestination = dest;

// fund
fund(rawTx, pwallet, {}, &coinControl);
fund(rawTx, pwallet, {}, &coinControl, request.metadata.coinSelectOpts);

// check execution
execTestTx(CTransaction(rawTx), targetHeight);
Expand Down Expand Up @@ -2230,14 +2230,14 @@ UniValue HandleSendDFIP2201BTCInput(const JSONRPCRequest& request, CWalletCoinsU

CTransactionRef optAuthTx;
std::set<CScript> auth{script};
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auth, false, optAuthTx, request.params[3]);
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auth, false, optAuthTx, request.params[3], request.metadata.coinSelectOpts);

// Set change address
CCoinControl coinControl;
coinControl.destChange = dest;

// fund
fund(rawTx, pwallet, optAuthTx, &coinControl);
fund(rawTx, pwallet, optAuthTx, &coinControl, request.metadata.coinSelectOpts);

// check execution
execTestTx(CTransaction(rawTx), targetHeight, optAuthTx);
Expand Down Expand Up @@ -2379,14 +2379,14 @@ UniValue futureswap(const JSONRPCRequest& request) {

CTransactionRef optAuthTx;
std::set<CScript> auth{msg.owner};
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auth, false, optAuthTx, request.params[3]);
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auth, false, optAuthTx, request.params[3], request.metadata.coinSelectOpts);

// Set change address
CCoinControl coinControl;
coinControl.destChange = dest;

// Fund
fund(rawTx, pwallet, optAuthTx, &coinControl);
fund(rawTx, pwallet, optAuthTx, &coinControl, request.metadata.coinSelectOpts);

// Check execution
execTestTx(CTransaction(rawTx), targetHeight, optAuthTx);
Expand Down Expand Up @@ -2470,14 +2470,14 @@ UniValue withdrawfutureswap(const JSONRPCRequest& request) {

CTransactionRef optAuthTx;
std::set<CScript> auth{msg.owner};
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auth, false, optAuthTx, request.params[3]);
rawTx.vin = GetAuthInputsSmart(pwallet, rawTx.nVersion, auth, false, optAuthTx, request.params[3], request.metadata.coinSelectOpts);

// Set change address
CCoinControl coinControl;
coinControl.destChange = dest;

// Fund
fund(rawTx, pwallet, optAuthTx, &coinControl);
fund(rawTx, pwallet, optAuthTx, &coinControl, request.metadata.coinSelectOpts);

// Check execution
execTestTx(CTransaction(rawTx), targetHeight, optAuthTx);
Expand Down
Loading

0 comments on commit b781611

Please sign in to comment.