Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add owner and operator address support to getmasternode #2573

Merged
merged 1 commit into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 45 additions & 6 deletions src/dfi/rpc_masternodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ UniValue getmasternode(const JSONRPCRequest &request) {
"getmasternode",
"\nReturns information about specified masternode.\n",
{
{"mn_id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Masternode's id"},
{"mn_id", RPCArg::Type::STR, RPCArg::Optional::NO, "Masternode's ID, operator or owner address"},
},
RPCResult{"{id:{...}} (object) Json object with masternode information\n"},
RPCExamples{HelpExampleCli("getmasternode", "mn_id") + HelpExampleRpc("getmasternode", "mn_id")},
Expand All @@ -621,15 +621,54 @@ UniValue getmasternode(const JSONRPCRequest &request) {
}
auto pwallet = GetWallet(request);

uint256 id = ParseHashV(request.params[0], "masternode id");
const auto idStr = request.params[0].get_str();

LOCK(cs_main);
const auto mnIds = pcustomcsview->GetOperatorsMulti();
auto node = pcustomcsview->GetMasternode(id);
if (node) {
auto res = mnToJSON(*pcustomcsview, id, *node, true, mnIds, pwallet); // or maybe just node, w/o id?
return GetRPCResultCache().Set(request, res);

auto printMasternode = [&](const uint256 &id) -> std::optional<UniValue> {
auto node = pcustomcsview->GetMasternode(id);
if (node) {
auto res = mnToJSON(*pcustomcsview, id, *node, true, mnIds, pwallet);
return GetRPCResultCache().Set(request, res);
}
return {};
};

// Try from hex string
if (IsHex(idStr) && idStr.length() == 64) {
const auto id = uint256S(idStr);
if (auto res = printMasternode(id)) {
return *res;
}
}

const auto dest = DecodeDestination(idStr);
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Masternode not found");
}

const auto keyId = CKeyID::TryFromDestination(dest);
if (!keyId) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Masternode not found");
}

// Try from operator address
auto hash = pcustomcsview->GetMasternodeIdByOperator(*keyId);
if (hash) {
if (auto res = printMasternode(*hash)) {
return *res;
}
}

// Try from owner address
hash = pcustomcsview->GetMasternodeIdByOwner(*keyId);
if (hash) {
if (auto res = printMasternode(*hash)) {
return *res;
}
}

throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Masternode not found");
}

Expand Down
38 changes: 38 additions & 0 deletions test/functional/rpc_mn_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ def run_test(self):

# Create node0
self.nodes[0].generate(1)

# Save start block for revert
start_block = self.nodes[0].getblockcount()

collateral1 = self.nodes[1].getnewaddress("", "legacy")
assert_raises_rpc_error(
-8,
Expand Down Expand Up @@ -294,6 +298,40 @@ def run_test(self):
self.nodes[0].generate(1)
assert_equal(self.nodes[0].listmasternodes()[mnTx]["state"], "RESIGNED")

# Rollback to the start
self.rollback_to(start_block)

# Generate separate owner and operator address
owner = self.nodes[0].getnewaddress("", "legacy")
operator = self.nodes[0].getnewaddress("", "legacy")

# Create masternode
id = self.nodes[0].createmasternode(owner, operator)
self.nodes[0].generate(1)

# Try and get MN with invalid string
assert_raises_rpc_error(
-5,
"Masternode not found",
self.nodes[0].getmasternode,
"notanid",
)

# Get masternode by ID
node = self.nodes[0].getmasternode(id)[id]
assert_equal(node["ownerAuthAddress"], owner)
assert_equal(node["operatorAuthAddress"], operator)

# Get masternode by owner
node = self.nodes[0].getmasternode(owner)[id]
assert_equal(node["ownerAuthAddress"], owner)
assert_equal(node["operatorAuthAddress"], operator)

# Get masternode by operator
node = self.nodes[0].getmasternode(operator)[id]
assert_equal(node["ownerAuthAddress"], owner)
assert_equal(node["operatorAuthAddress"], operator)


if __name__ == "__main__":
MasternodesRpcBasicTest().main()