Skip to content

Commit 48fccdd

Browse files
committed
refactor: introduce coinjoin status for information on mix sessions
This helps us get rid of having to report it through `coinjoin start`. Additionally, we won't try to jump ahead of the scheduler by starting denomination routines ourselves, let the scheduler run its course. This matters because we don't plan on exposing that capability through the interface as we are migrating to the interface in the next commit.
1 parent 5c1a627 commit 48fccdd

File tree

5 files changed

+61
-12
lines changed

5 files changed

+61
-12
lines changed

doc/release-notes-6594.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Updated RPCs
2+
------------
3+
4+
* `coinjoin status` is a new RPC that reports the status message of all running mix
5+
sessions.
6+
* `coinjoin start` will no longer report errors from mix sessions, users are recommended
7+
to query the status of mix sessions using `coinjoin status` instead.

src/coinjoin/client.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -350,17 +350,18 @@ bilingual_str CCoinJoinClientSession::GetStatus(bool fWaitForBlock) const
350350
}
351351
}
352352

353-
bilingual_str CCoinJoinClientManager::GetStatuses()
353+
std::vector<std::string> CCoinJoinClientManager::GetStatuses() const
354354
{
355-
bilingual_str strStatus;
356-
bool fWaitForBlock = WaitForAnotherBlock();
357-
358355
AssertLockNotHeld(cs_deqsessions);
356+
357+
bool fWaitForBlock{WaitForAnotherBlock()};
358+
std::vector<std::string> ret;
359+
359360
LOCK(cs_deqsessions);
360361
for (const auto& session : deqSessions) {
361-
strStatus = strStatus + session.GetStatus(fWaitForBlock) + Untranslated("; ");
362+
ret.push_back(session.GetStatus(fWaitForBlock).original);
362363
}
363-
return strStatus;
364+
return ret;
364365
}
365366

366367
std::string CCoinJoinClientManager::GetSessionDenoms()

src/coinjoin/client.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ class CCoinJoinClientManager
327327
bool IsMixing() const;
328328
void ResetPool() EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
329329

330-
bilingual_str GetStatuses() EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
330+
std::vector<std::string> GetStatuses() const EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
331331
std::string GetSessionDenoms() EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
332332

333333
bool GetMixingMasternodesInfo(std::vector<CDeterministicMNCPtr>& vecDmnsRet) const EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);

src/rpc/coinjoin.cpp

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static RPCHelpMan coinjoin()
4545
return RPCHelpMan{"coinjoin",
4646
"\nAvailable commands:\n"
4747
" start - Start mixing\n"
48+
" status - Get mixing status\n"
4849
" stop - Stop mixing\n"
4950
" reset - Reset mixing",
5051
{
@@ -129,11 +130,46 @@ static RPCHelpMan coinjoin_start()
129130
throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing has been started already.");
130131
}
131132

132-
ChainstateManager& chainman = EnsureChainman(node);
133-
CTxMemPool& mempool = EnsureMemPool(node);
134-
CConnman& connman = EnsureConnman(node);
135-
bool result = cj_clientman->DoAutomaticDenominating(chainman, connman, mempool);
136-
return "Mixing " + (result ? "started successfully" : ("start failed: " + cj_clientman->GetStatuses().original + ", will retry"));
133+
return "Mixing requested";
134+
},
135+
};
136+
}
137+
138+
static RPCHelpMan coinjoin_status()
139+
{
140+
return RPCHelpMan{"coinjoin status",
141+
"\nGet status on CoinJoin mixing sessions\n",
142+
{},
143+
RPCResult{
144+
RPCResult::Type::ARR, "", "",
145+
{{RPCResult::Type::STR, "", "Status of mixing session"}}},
146+
RPCExamples{
147+
HelpExampleCli("coinjoin status", "")
148+
+ HelpExampleRpc("coinjoin status", "")
149+
},
150+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
151+
{
152+
const std::shared_ptr<const CWallet> wallet = GetWalletForJSONRPCRequest(request);
153+
if (!wallet) return NullUniValue;
154+
155+
const NodeContext& node = EnsureAnyNodeContext(request.context);
156+
157+
if (node.mn_activeman) {
158+
throw JSONRPCError(RPC_INTERNAL_ERROR, "Client-side mixing is not supported on masternodes");
159+
}
160+
161+
ValidateCoinJoinArguments();
162+
163+
auto cj_clientman = CHECK_NONFATAL(node.coinjoin_loader)->walletman().Get(wallet->GetName());
164+
if (!CHECK_NONFATAL(cj_clientman)->IsMixing()) {
165+
throw JSONRPCError(RPC_INTERNAL_ERROR, "No ongoing mix session");
166+
}
167+
168+
UniValue ret(UniValue::VARR);
169+
for (auto str_status : cj_clientman->GetStatuses()) {
170+
ret.push_back(str_status);
171+
}
172+
return ret;
137173
},
138174
};
139175
}
@@ -460,6 +496,7 @@ static const CRPCCommand commands[] =
460496
{ "dash", &coinjoin, },
461497
{ "dash", &coinjoin_reset, },
462498
{ "dash", &coinjoin_start, },
499+
{ "dash", &coinjoin_status, },
463500
{ "dash", &coinjoin_stop, },
464501
{ "dash", &coinjoinsalt, },
465502
{ "dash", &coinjoinsalt_generate, },

test/functional/rpc_coinjoin.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ def test_coinjoin_start_stop(self, node):
6666
assert_equal(cj_info['running'], True)
6767
# Repeated start should yield error
6868
assert_raises_rpc_error(-32603, 'Mixing has been started already.', node.coinjoin, 'start')
69+
# Requesting status shouldn't complain
70+
node.coinjoin('status')
6971

7072
# Stop mix session and ensure it's reported
7173
node.coinjoin('stop')
@@ -74,6 +76,8 @@ def test_coinjoin_start_stop(self, node):
7476
assert_equal(cj_info['running'], False)
7577
# Repeated stop should yield error
7678
assert_raises_rpc_error(-32603, 'No mix session to stop', node.coinjoin, 'stop')
79+
# Requesting status should tell us off
80+
assert_raises_rpc_error(-32603, 'No ongoing mix session', node.coinjoin, 'status')
7781

7882
# Reset mix session
7983
assert_equal(node.coinjoin('reset'), "Mixing was reset")

0 commit comments

Comments
 (0)