mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
rpc: make coinjoin
a composite command
This commit is contained in:
parent
1f113587fb
commit
51b6b94fc0
@ -22,19 +22,55 @@
|
||||
#include <univalue.h>
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
namespace {
|
||||
void ValidateCoinJoinArguments()
|
||||
{
|
||||
/* If CoinJoin is enabled, everything is working as expected, we can bail */
|
||||
if (CCoinJoinClientOptions::IsEnabled())
|
||||
return;
|
||||
|
||||
/* CoinJoin is on by default, unless a command line argument says otherwise */
|
||||
if (!gArgs.GetBoolArg("-enablecoinjoin", true)) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing is disabled via -enablecoinjoin=0 command line option, remove it to enable mixing again");
|
||||
}
|
||||
|
||||
/* Most likely something bad happened and we disabled it while running the wallet */
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing is disabled due to an internal error");
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
static RPCHelpMan coinjoin()
|
||||
{
|
||||
return RPCHelpMan{"coinjoin",
|
||||
"\nAvailable commands:\n"
|
||||
" start - Start mixing\n"
|
||||
" stop - Stop mixing\n"
|
||||
" reset - Reset mixing",
|
||||
{
|
||||
{"command", RPCArg::Type::STR, RPCArg::Optional::NO, "The command to execute"},
|
||||
},
|
||||
RPCResults{},
|
||||
RPCExamples{""},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
return RPCHelpMan{"coinjoin",
|
||||
"\nAvailable commands:\n"
|
||||
" start - Start mixing\n"
|
||||
" stop - Stop mixing\n"
|
||||
" reset - Reset mixing",
|
||||
{
|
||||
{"command", RPCArg::Type::STR, RPCArg::Optional::NO, "The command to execute"},
|
||||
},
|
||||
RPCResults{},
|
||||
RPCExamples{""},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
{
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Must be a valid command");
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static RPCHelpMan coinjoin_reset()
|
||||
{
|
||||
return RPCHelpMan{"coinjoin reset",
|
||||
"\nReset CoinJoin mixing\n",
|
||||
{},
|
||||
RPCResult{
|
||||
RPCResult::Type::STR, "", "Status of request"
|
||||
},
|
||||
RPCExamples{
|
||||
HelpExampleCli("coinjoin reset", "")
|
||||
+ HelpExampleRpc("coinjoin reset", "")
|
||||
},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
{
|
||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||
if (!wallet) return NullUniValue;
|
||||
@ -45,49 +81,100 @@ static RPCHelpMan coinjoin()
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Client-side mixing is not supported on masternodes");
|
||||
}
|
||||
|
||||
if (!CCoinJoinClientOptions::IsEnabled()) {
|
||||
if (!gArgs.GetBoolArg("-enablecoinjoin", true)) {
|
||||
// otherwise it's on by default, unless cmd line option says otherwise
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing is disabled via -enablecoinjoin=0 command line option, remove it to enable mixing again");
|
||||
} else {
|
||||
// not enablecoinjoin=false case,
|
||||
// most likely something bad happened and we disabled it while running the wallet
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing is disabled due to some internal error");
|
||||
}
|
||||
}
|
||||
ValidateCoinJoinArguments();
|
||||
|
||||
CHECK_NONFATAL(node.coinjoin_loader);
|
||||
auto cj_clientman = node.coinjoin_loader->walletman().Get(wallet->GetName());
|
||||
CHECK_NONFATAL(cj_clientman != nullptr);
|
||||
|
||||
if (request.params[0].get_str() == "start") {
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
if (wallet->IsLocked(true))
|
||||
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please unlock wallet for mixing with walletpassphrase first.");
|
||||
}
|
||||
CHECK_NONFATAL(cj_clientman);
|
||||
cj_clientman->ResetPool();
|
||||
|
||||
if (!cj_clientman->StartMixing()) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing has been started already.");
|
||||
}
|
||||
return "Mixing was reset";
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const ChainstateManager& chainman = EnsureChainman(node);
|
||||
CTxMemPool& mempool = EnsureMemPool(node);
|
||||
CConnman& connman = EnsureConnman(node);
|
||||
bool result = cj_clientman->DoAutomaticDenominating(chainman.ActiveChainstate(), connman, mempool);
|
||||
return "Mixing " + (result ? "started successfully" : ("start failed: " + cj_clientman->GetStatuses().original + ", will retry"));
|
||||
static RPCHelpMan coinjoin_start()
|
||||
{
|
||||
return RPCHelpMan{"coinjoin start",
|
||||
"\nStart CoinJoin mixing\n"
|
||||
"Wallet must be unlocked for mixing\n",
|
||||
{},
|
||||
RPCResult{
|
||||
RPCResult::Type::STR, "", "Status of request"
|
||||
},
|
||||
RPCExamples{
|
||||
HelpExampleCli("coinjoin start", "")
|
||||
+ HelpExampleRpc("coinjoin start", "")
|
||||
},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
{
|
||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||
if (!wallet) return NullUniValue;
|
||||
|
||||
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||
|
||||
if (node.mn_activeman) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Client-side mixing is not supported on masternodes");
|
||||
}
|
||||
|
||||
if (request.params[0].get_str() == "stop") {
|
||||
cj_clientman->StopMixing();
|
||||
return "Mixing was stopped";
|
||||
ValidateCoinJoinArguments();
|
||||
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
if (wallet->IsLocked(true))
|
||||
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please unlock wallet for mixing with walletpassphrase first.");
|
||||
}
|
||||
|
||||
if (request.params[0].get_str() == "reset") {
|
||||
cj_clientman->ResetPool();
|
||||
return "Mixing was reset";
|
||||
CHECK_NONFATAL(node.coinjoin_loader);
|
||||
auto cj_clientman = node.coinjoin_loader->walletman().Get(wallet->GetName());
|
||||
|
||||
CHECK_NONFATAL(cj_clientman);
|
||||
if (!cj_clientman->StartMixing()) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing has been started already.");
|
||||
}
|
||||
|
||||
return "Unknown command, please see \"help coinjoin\"";
|
||||
const ChainstateManager& chainman = EnsureChainman(node);
|
||||
CTxMemPool& mempool = EnsureMemPool(node);
|
||||
CConnman& connman = EnsureConnman(node);
|
||||
bool result = cj_clientman->DoAutomaticDenominating(chainman.ActiveChainstate(), connman, mempool);
|
||||
return "Mixing " + (result ? "started successfully" : ("start failed: " + cj_clientman->GetStatuses().original + ", will retry"));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static RPCHelpMan coinjoin_stop()
|
||||
{
|
||||
return RPCHelpMan{"coinjoin stop",
|
||||
"\nStop CoinJoin mixing\n",
|
||||
{},
|
||||
RPCResult{
|
||||
RPCResult::Type::STR, "", "Status of request"
|
||||
},
|
||||
RPCExamples{
|
||||
HelpExampleCli("coinjoin stop", "")
|
||||
+ HelpExampleRpc("coinjoin stop", "")
|
||||
},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
{
|
||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||
if (!wallet) return NullUniValue;
|
||||
|
||||
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||
|
||||
if (node.mn_activeman) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Client-side mixing is not supported on masternodes");
|
||||
}
|
||||
|
||||
ValidateCoinJoinArguments();
|
||||
|
||||
CHECK_NONFATAL(node.coinjoin_loader);
|
||||
auto cj_clientman = node.coinjoin_loader->walletman().Get(wallet->GetName());
|
||||
|
||||
CHECK_NONFATAL(cj_clientman);
|
||||
cj_clientman->StopMixing();
|
||||
|
||||
return "Mixing was stopped";
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -191,16 +278,19 @@ void RegisterCoinJoinRPCCommands(CRPCTable &t)
|
||||
{
|
||||
// clang-format off
|
||||
static const CRPCCommand commands[] =
|
||||
{ // category name actor (function) argNames
|
||||
// --------------------- ------------------------ ---------------------------------
|
||||
{ "dash", "getpoolinfo", &getpoolinfo, {} },
|
||||
{ "dash", "getcoinjoininfo", &getcoinjoininfo, {} },
|
||||
{ // category name actor (function) argNames
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
{ "dash", "getpoolinfo", &getpoolinfo, {} },
|
||||
{ "dash", "getcoinjoininfo", &getcoinjoininfo, {} },
|
||||
#ifdef ENABLE_WALLET
|
||||
{ "dash", "coinjoin", &coinjoin, {"command"} },
|
||||
{ "dash", "coinjoin", &coinjoin, {"command"} },
|
||||
{ "dash", "coinjoin", "reset", &coinjoin_reset, {} },
|
||||
{ "dash", "coinjoin", "start", &coinjoin_start, {} },
|
||||
{ "dash", "coinjoin", "stop", &coinjoin_stop, {} },
|
||||
#endif // ENABLE_WALLET
|
||||
};
|
||||
// clang-format on
|
||||
for (const auto& command : commands) {
|
||||
t.appendCommand(command.name, &command);
|
||||
t.appendCommand(command.name, command.subname, &command);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user