mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
rpc: make coinjoin
a composite command
This commit is contained in:
parent
1f113587fb
commit
51b6b94fc0
@ -22,19 +22,55 @@
|
|||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#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()
|
static RPCHelpMan coinjoin()
|
||||||
{
|
{
|
||||||
return RPCHelpMan{"coinjoin",
|
return RPCHelpMan{"coinjoin",
|
||||||
"\nAvailable commands:\n"
|
"\nAvailable commands:\n"
|
||||||
" start - Start mixing\n"
|
" start - Start mixing\n"
|
||||||
" stop - Stop mixing\n"
|
" stop - Stop mixing\n"
|
||||||
" reset - Reset mixing",
|
" reset - Reset mixing",
|
||||||
{
|
{
|
||||||
{"command", RPCArg::Type::STR, RPCArg::Optional::NO, "The command to execute"},
|
{"command", RPCArg::Type::STR, RPCArg::Optional::NO, "The command to execute"},
|
||||||
},
|
},
|
||||||
RPCResults{},
|
RPCResults{},
|
||||||
RPCExamples{""},
|
RPCExamples{""},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](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);
|
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||||
if (!wallet) return NullUniValue;
|
if (!wallet) return NullUniValue;
|
||||||
@ -45,49 +81,100 @@ static RPCHelpMan coinjoin()
|
|||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Client-side mixing is not supported on masternodes");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Client-side mixing is not supported on masternodes");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CCoinJoinClientOptions::IsEnabled()) {
|
ValidateCoinJoinArguments();
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
CHECK_NONFATAL(node.coinjoin_loader);
|
||||||
auto cj_clientman = node.coinjoin_loader->walletman().Get(wallet->GetName());
|
auto cj_clientman = node.coinjoin_loader->walletman().Get(wallet->GetName());
|
||||||
CHECK_NONFATAL(cj_clientman != nullptr);
|
|
||||||
|
|
||||||
if (request.params[0].get_str() == "start") {
|
CHECK_NONFATAL(cj_clientman);
|
||||||
{
|
cj_clientman->ResetPool();
|
||||||
LOCK(wallet->cs_wallet);
|
|
||||||
if (wallet->IsLocked(true))
|
|
||||||
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please unlock wallet for mixing with walletpassphrase first.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cj_clientman->StartMixing()) {
|
return "Mixing was reset";
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing has been started already.");
|
},
|
||||||
}
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const ChainstateManager& chainman = EnsureChainman(node);
|
static RPCHelpMan coinjoin_start()
|
||||||
CTxMemPool& mempool = EnsureMemPool(node);
|
{
|
||||||
CConnman& connman = EnsureConnman(node);
|
return RPCHelpMan{"coinjoin start",
|
||||||
bool result = cj_clientman->DoAutomaticDenominating(chainman.ActiveChainstate(), connman, mempool);
|
"\nStart CoinJoin mixing\n"
|
||||||
return "Mixing " + (result ? "started successfully" : ("start failed: " + cj_clientman->GetStatuses().original + ", will retry"));
|
"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") {
|
ValidateCoinJoinArguments();
|
||||||
cj_clientman->StopMixing();
|
|
||||||
return "Mixing was stopped";
|
{
|
||||||
|
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") {
|
CHECK_NONFATAL(node.coinjoin_loader);
|
||||||
cj_clientman->ResetPool();
|
auto cj_clientman = node.coinjoin_loader->walletman().Get(wallet->GetName());
|
||||||
return "Mixing was reset";
|
|
||||||
|
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
|
// clang-format off
|
||||||
static const CRPCCommand commands[] =
|
static const CRPCCommand commands[] =
|
||||||
{ // category name actor (function) argNames
|
{ // category name actor (function) argNames
|
||||||
// --------------------- ------------------------ ---------------------------------
|
// ------------------------------------------------------------------------------------------------------
|
||||||
{ "dash", "getpoolinfo", &getpoolinfo, {} },
|
{ "dash", "getpoolinfo", &getpoolinfo, {} },
|
||||||
{ "dash", "getcoinjoininfo", &getcoinjoininfo, {} },
|
{ "dash", "getcoinjoininfo", &getcoinjoininfo, {} },
|
||||||
#ifdef ENABLE_WALLET
|
#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
|
#endif // ENABLE_WALLET
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
for (const auto& command : commands) {
|
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