diff --git a/src/key_io.cpp b/src/key_io.cpp index cdbdb49c3d7..126d92d9da0 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -226,3 +226,11 @@ bool IsValidDestinationString(const std::string& str) { return IsValidDestinationString(str, Params()); } + +CKeyID getCKeyIDFromDestination(const CTxDestination& dest) { + switch (dest.which()) { + case PKHashType : return CKeyID(*boost::get(&dest)); + case WitV0KeyHashType : return CKeyID(*boost::get(&dest)); + default : return CKeyID(); + } +} diff --git a/src/key_io.h b/src/key_io.h index b14613c3912..393d381c774 100644 --- a/src/key_io.h +++ b/src/key_io.h @@ -28,4 +28,6 @@ CTxDestination DecodeDestination(const std::string& str, const CChainParams& par bool IsValidDestinationString(const std::string& str); bool IsValidDestinationString(const std::string& str, const CChainParams& params); +CKeyID getCKeyIDFromDestination(const CTxDestination& dest); + #endif // DEFI_KEY_IO_H diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 7a80b690604..14d1f7a4452 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -190,13 +190,23 @@ static UniValue generatetoaddress(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address"); } - auto myIDs = pcustomcsview->AmIOperator(); - if (!myIDs) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: I am not masternode operator"); + CKeyID passedID = getCKeyIDFromDestination(destination); + + auto myAllMNs = pcustomcsview->GetOperatorsMulti(); + if (myAllMNs.empty()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: I am not masternode operator"); } - CScript coinbase_script = GetScriptForDestination(destination); + CKeyID operatorID; + auto mnForPassedID = pcustomcsview->GetMasternodeIdByOperator(passedID); + // check mnForPassedID is in myAllMNs + if (mnForPassedID && myAllMNs.count(std::make_pair(passedID, *mnForPassedID))) { + operatorID = passedID; + } else { + operatorID = myAllMNs.begin()->first; + } + CScript coinbase_script = GetScriptForDestination(destination); CKey minterKey; { std::vector> wallets = GetWallets(); @@ -205,7 +215,7 @@ static UniValue generatetoaddress(const JSONRPCRequest& request) bool found =false; for (auto&& wallet : wallets) { - if (wallet->GetKey(myIDs->first, minterKey)) { + if (wallet->GetKey(operatorID, minterKey)) { found = true; break; } @@ -214,7 +224,7 @@ static UniValue generatetoaddress(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: masternode operator private key not found"); } - return generateBlocks(coinbase_script, minterKey, myIDs->first, nGenerate, nMaxTries); + return generateBlocks(coinbase_script, minterKey, operatorID, nGenerate, nMaxTries); } // Returns the mining information of all local masternodes diff --git a/test/functional/rpc_getmininginfo.py b/test/functional/rpc_getmininginfo.py index de64e425217..7ba78fda437 100755 --- a/test/functional/rpc_getmininginfo.py +++ b/test/functional/rpc_getmininginfo.py @@ -6,6 +6,7 @@ from test_framework.test_framework import DefiTestFramework from test_framework.util import ( assert_equal, + assert_greater_than, connect_nodes_bi, ) @@ -32,8 +33,8 @@ def run_test(self): operators = [node0_keys.operatorAuthAddress, node1_keys.operatorAuthAddress] self.log.info("Restart nodes...") - self.restart_node(0, ['-gen', '-masternode_operator=' + operators[0]]) - self.restart_node(1, ['-gen', '-rewardaddress=' + operators[1]] + + self.restart_node(0, ['-gen', '-dummypos=0', '-masternode_operator=' + operators[0]]) + self.restart_node(1, ['-gen', '-dummypos=0', '-rewardaddress=' + operators[1]] + ['-masternode_operator=' + x for x in operators]) connect_nodes_bi(self.nodes, 0, 1) @@ -41,7 +42,8 @@ def run_test(self): self.log.info("Mining blocks ...") self.nodes[0].generate(10) self.sync_all() - self.nodes[1].generate(50) + self.nodes[1].generate(25) + self.nodes[1].generatetoaddress(25, node0_keys.operatorAuthAddress) self.sync_all() # getmininginfo() on node[0], should only return one master node in the response array @@ -50,6 +52,7 @@ def run_test(self): assert_equal(resp0['masternodes'][0]['state'], "ENABLED") assert_equal(resp0['masternodes'][0]['generate'], True) assert_equal(resp0['masternodes'][0]['lastblockcreationattempt'] != "0", True) + assert_greater_than(resp0['masternodes'][0]['mintedblocks'], 0) # getmininginfo() on node[1], should return two master nodes in the response array resp1 = self.nodes[1].getmininginfo() @@ -57,10 +60,13 @@ def run_test(self): assert_equal(resp1['masternodes'][0]['state'], "ENABLED") assert_equal(resp1['masternodes'][0]['generate'], True) assert_equal(resp1['masternodes'][0]['lastblockcreationattempt'] != "0", True) + assert_greater_than(resp1['masternodes'][0]['mintedblocks'], 0) + assert_equal(resp1['masternodes'][1]['state'], "ENABLED") assert_equal(resp1['masternodes'][1]['generate'], True) assert_equal(resp1['masternodes'][1]['lastblockcreationattempt'] != "0", True) + assert_greater_than(resp1['masternodes'][1]['mintedblocks'], 0) if __name__ == '__main__': GetMiningInfoRPCTest().main()