From 32951f795ce55fa238b3da071834fa5723511b33 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Wed, 14 Mar 2018 08:57:08 +0100 Subject: [PATCH] Implement "protx update_service" RPC --- src/rpc/rpcevo.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/src/rpc/rpcevo.cpp b/src/rpc/rpcevo.cpp index 886cc78eb..7876bbd67 100644 --- a/src/rpc/rpcevo.cpp +++ b/src/rpc/rpcevo.cpp @@ -240,6 +240,72 @@ UniValue protx_register(const JSONRPCRequest& request) return SignAndSendSpecialTx(tx); } +void protx_update_service_help() +{ + throw std::runtime_error( + "protx update_service \"proTxHash\" \"ipAndPort\" protocolVersion (\"operatorPayoutAddress\")\n" + "\nCreates and sends a ProUpServTx to the network. This will update the address and protocol version\n" + "of a masternode. The operator key of the masternode must be known to your wallet.\n" + "If this is done for a masternode that got PoSe-banned, the ProUpServTx will also revive this masternode.\n" + "\nArguments:\n" + "1. \"proTxHash\" (string, required) The hash of the initial ProRegTx.\n" + "2. \"ipAndPort\" (string, required) IP and port in the form \"IP:PORT\".\n" + " Must be unique on the network.\n" + "3. \"protocolVersion\" (numeric, required) The protocol version of your masternode.\n" + " Can be 0 to default to the clients protocol version\n" + "4. \"operatorPayoutAddress\" (string, optional) The address used for operator reward payments.\n" + " Only allowed when the ProRegTx had a non-zero operatorReward value.\n" + "\nExamples:\n" + + HelpExampleCli("protx", "update_service \"0123456701234567012345670123456701234567012345670123456701234567\" \"1.2.3.4:1234\" 0") + ); +} + +UniValue protx_update_service(const JSONRPCRequest& request) +{ + if (request.fHelp || (request.params.size() != 4 && request.params.size() != 5)) + protx_update_service_help(); + + CProUpServTx ptx; + ptx.nVersion = CProRegTx::CURRENT_VERSION; + ptx.proTxHash = ParseHashV(request.params[1], "proTxHash"); + + if (!Lookup(request.params[2].get_str().c_str(), ptx.addr, Params().GetDefaultPort(), false)) { + throw std::runtime_error(strprintf("invalid network address %s", request.params[3].get_str())); + } + + ptx.nProtocolVersion = ParseInt32V(request.params[3], "protocolVersion"); + if (ptx.nProtocolVersion == 0) { + ptx.nProtocolVersion = PROTOCOL_VERSION; + } + + if (request.params.size() > 4) { + CBitcoinAddress payoutAddress(request.params[4].get_str()); + if (!payoutAddress.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("invalid operator payout address: %s", request.params[4].get_str())); + ptx.scriptOperatorPayout = GetScriptForDestination(payoutAddress.Get()); + } + + auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(ptx.proTxHash); + if (!dmn) { + throw std::runtime_error(strprintf("masternode with proTxHash %s not found", ptx.proTxHash.ToString())); + } + + CKey keyOperator; + if (!pwalletMain->GetKey(dmn->pdmnState->keyIDOperator, keyOperator)) { + throw std::runtime_error(strprintf("operator key %s not found in your wallet", dmn->pdmnState->keyIDOperator.ToString())); + } + + CMutableTransaction tx; + tx.nVersion = 3; + tx.nType = TRANSACTION_PROVIDER_UPDATE_SERVICE; + + FundSpecialTx(tx, ptx); + SignSpecialTxPayload(tx, ptx, keyOperator); + SetTxPayload(tx, ptx); + + return SignAndSendSpecialTx(tx); +} + void protx_list_help() { throw std::runtime_error( @@ -380,8 +446,9 @@ UniValue protx(const JSONRPCRequest& request) "\nArguments:\n" "1. \"command\" (string, required) The command to execute\n" "\nAvailable commands:\n" - " register - Create and send ProTx to network\n" - " list - List ProTxs\n" + " register - Create and send ProTx to network\n" + " list - List ProTxs\n" + " update_service - Create and send ProUpServTx to network\n" ); } @@ -391,6 +458,8 @@ UniValue protx(const JSONRPCRequest& request) return protx_register(request); } else if (command == "list") { return protx_list(request); + } else if (command == "update_service") { + return protx_update_service(request); } else { throw std::runtime_error("invalid command: " + command); }