16224898d4
Brings back the abandontransaction RPC that was removed when Triangles
forked from Bitcoin Core 0.18. The fix for a stuck or conflicted
transaction is currently to either wait indefinitely for the conflict
to resolve or restart the wallet with -zapwallettxes=1 (a heavy hammer
that wipes ALL unconfirmed txs). abandontransaction gives the user
targeted control.
Backend (port of Bitcoin Core 0.17's CWallet::AbandonTransaction):
- CWallet::AbandonTransaction(const uint256& hashTx) in src/wallet.{h,cpp}
Erases the tx from the wallet and the wallet DB, which releases
the inputs (vfSpent was tracked on the wtx). Iterates the wallet
to record descendant txs that spend this tx's outputs.
- abandontransaction RPC in src/rpcwallet.cpp + trianglesrpc.{h,cpp}.
Validates the tx is unconfirmed, in-wallet, and from this wallet
before calling AbandonTransaction.
- extern forward declaration in trianglesrpc.h so the RPC table can
reference the function.
UI (Qt right-click context menu in transactionview.cpp):
- New 'Abandon transaction' action in the context menu, only enabled
for transactions with Unconfirmed / Conflicted / Offline status.
- Confirmation dialog before calling the RPC.
- On success, refreshes the transactions table.
WalletModel::abandonTransaction(QString) in src/qt/walletmodel.{h,cpp}
is the thin wrapper that converts the QString hash to a uint256 and
calls CWallet::AbandonTransaction.
Tested by: building a Linux daemon + a successful regtest-style dry-run
that confirmed the new RPC is registered and the symbol is in the
binary. UI rebuild on Windows requires running build-all.yml on a
windows-latest runner (done via workflow_dispatch).
260 lines
14 KiB
C++
260 lines
14 KiB
C++
// Copyright (c) 2010 Satoshi Nakamoto
|
|
// Copyright (c) 2009-2012 The Bitcoin developers
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#ifndef _TRIANGLESRPC_H_
|
|
#define _TRIANGLESRPC_H_ 1
|
|
|
|
#include <string>
|
|
#include <list>
|
|
#include <map>
|
|
|
|
class CBlockIndex;
|
|
|
|
#include "json/json_compat.h"
|
|
|
|
#include "util.h"
|
|
#include "checkpoints.h"
|
|
|
|
// HTTP status codes
|
|
enum HTTPStatusCode
|
|
{
|
|
HTTP_OK = 200,
|
|
HTTP_BAD_REQUEST = 400,
|
|
HTTP_UNAUTHORIZED = 401,
|
|
HTTP_FORBIDDEN = 403,
|
|
HTTP_NOT_FOUND = 404,
|
|
HTTP_INTERNAL_SERVER_ERROR = 500,
|
|
};
|
|
|
|
// Triangles RPC error codes
|
|
enum RPCErrorCode
|
|
{
|
|
// Standard JSON-RPC 2.0 errors
|
|
RPC_INVALID_REQUEST = -32600,
|
|
RPC_METHOD_NOT_FOUND = -32601,
|
|
RPC_INVALID_PARAMS = -32602,
|
|
RPC_INTERNAL_ERROR = -32603,
|
|
RPC_PARSE_ERROR = -32700,
|
|
|
|
// General application defined errors
|
|
RPC_MISC_ERROR = -1, // std::exception thrown in command handling
|
|
RPC_FORBIDDEN_BY_SAFE_MODE = -2, // Server is in safe mode, and command is not allowed in safe mode
|
|
RPC_TYPE_ERROR = -3, // Unexpected type was passed as parameter
|
|
RPC_INVALID_ADDRESS_OR_KEY = -5, // Invalid address or key
|
|
RPC_OUT_OF_MEMORY = -7, // Ran out of memory during operation
|
|
RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter
|
|
RPC_DATABASE_ERROR = -20, // Database error
|
|
RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format
|
|
RPC_SERVER_NOT_STARTED = -18, // RPC server was not started (StartRPCThreads() not called)
|
|
|
|
|
|
// P2P client errors
|
|
RPC_CLIENT_NOT_CONNECTED = -9, // Triangles is not connected
|
|
RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, // Still downloading initial blocks
|
|
|
|
// Wallet errors
|
|
RPC_WALLET_ERROR = -4, // Unspecified problem with wallet (key not found etc.)
|
|
RPC_WALLET_INSUFFICIENT_FUNDS = -6, // Not enough funds in wallet or account
|
|
RPC_WALLET_INVALID_ACCOUNT_NAME = -11, // Invalid account name
|
|
RPC_WALLET_KEYPOOL_RAN_OUT = -12, // Keypool ran out, call keypoolrefill first
|
|
RPC_WALLET_UNLOCK_NEEDED = -13, // Enter the wallet passphrase with walletpassphrase first
|
|
RPC_WALLET_PASSPHRASE_INCORRECT = -14, // The wallet passphrase entered was incorrect
|
|
RPC_WALLET_WRONG_ENC_STATE = -15, // Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.)
|
|
RPC_WALLET_ENCRYPTION_FAILED = -16, // Failed to encrypt the wallet
|
|
RPC_WALLET_ALREADY_UNLOCKED = -17, // Wallet is already unlocked
|
|
};
|
|
|
|
json_spirit::Object JSONRPCError(int code, const std::string& message);
|
|
|
|
void ThreadRPCServer(void* parg);
|
|
int CommandLineRPC(int argc, char *argv[]);
|
|
|
|
/** Convert parameter values for RPC call from strings to command-specific JSON objects. */
|
|
json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams);
|
|
|
|
/*
|
|
Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
|
|
the right number of arguments are passed, just that any passed are the correct type.
|
|
Use like: RPCTypeCheck(params, {str_type, int_type, obj_type});
|
|
*/
|
|
void RPCTypeCheck(const json_spirit::Array& params,
|
|
const std::list<json_spirit::Value_type>& typesExpected, bool fAllowNull=false);
|
|
/*
|
|
Check for expected keys/value types in an Object.
|
|
Use like: RPCTypeCheck(object, {{"name", str_type}, {"value", int_type}});
|
|
*/
|
|
void RPCTypeCheck(const json_spirit::Object& o,
|
|
const std::map<std::string, json_spirit::Value_type>& typesExpected, bool fAllowNull=false);
|
|
|
|
typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp);
|
|
|
|
class CRPCCommand
|
|
{
|
|
public:
|
|
std::string name;
|
|
rpcfn_type actor;
|
|
bool okSafeMode;
|
|
bool unlocked;
|
|
};
|
|
|
|
/**
|
|
* Triangles RPC command dispatcher.
|
|
*/
|
|
class CRPCTable
|
|
{
|
|
private:
|
|
std::map<std::string, const CRPCCommand*> mapCommands;
|
|
public:
|
|
CRPCTable();
|
|
const CRPCCommand* operator[](std::string name) const;
|
|
std::string help(std::string name) const;
|
|
|
|
/**
|
|
* Execute a method.
|
|
* @param method Method to execute
|
|
* @param params Array of arguments (JSON objects)
|
|
* @returns Result of the call.
|
|
* @throws an exception (json_spirit::Value) when an error happens.
|
|
*/
|
|
json_spirit::Value execute(const std::string &method, const json_spirit::Array ¶ms) const;
|
|
};
|
|
|
|
extern const CRPCTable tableRPC;
|
|
|
|
extern int64_t nWalletUnlockTime;
|
|
extern int64_t AmountFromValue(const json_spirit::Value& value);
|
|
extern json_spirit::Value ValueFromAmount(int64_t amount);
|
|
extern double GetDifficulty(const CBlockIndex* blockindex = nullptr);
|
|
|
|
extern double GetPoWMHashPS();
|
|
extern double GetPoSKernelPS();
|
|
|
|
extern std::string HexBits(unsigned int nBits);
|
|
extern std::string HelpRequiringPassphrase();
|
|
extern void EnsureWalletIsUnlocked();
|
|
|
|
//
|
|
// Utilities: convert hex-encoded Values
|
|
// (throws error if not hex).
|
|
//
|
|
extern uint256 ParseHashV(const json_spirit::Value& v, std::string strName);
|
|
extern uint256 ParseHashO(const json_spirit::Object& o, std::string strKey);
|
|
extern std::vector<unsigned char> ParseHexV(const json_spirit::Value& v, std::string strName);
|
|
extern std::vector<unsigned char> ParseHexO(const json_spirit::Object& o, std::string strKey);
|
|
|
|
extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp
|
|
extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getnetworkinfo(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getseedlist(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getnetworkstability(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value disconnectnode(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getwalletinfo(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value dumpwallet(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
|
|
extern json_spirit::Value hdnew(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value hdrestore(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value hdshow(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value hdinfo(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp);
|
|
|
|
extern json_spirit::Value getsubsidy(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getstakinginfo(const json_spirit::Array& params, bool fHelp);
|
|
|
|
extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
|
|
extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value setaccount(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getaccount(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getaddressesbyaccount(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value sendtoaddress(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value signmessage(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value verifymessage(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getreceivedbyaddress(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getreceivedbyaccount(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getbalance(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value movecmd(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value sendfrom(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value sendmany(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value addmultisigaddress(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value addredeemscript(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value listreceivedbyaddress(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value listreceivedbyaccount(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value listtransactions(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value listaddressgroupings(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value listaccounts(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value listsinceblock(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value gettransaction(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value backupwallet(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value keypoolrefill(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value walletpassphrase(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value encryptwallet(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value validateaddress(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value reservebalance(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value checkwallet(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value repairwallet(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value resendtx(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value abandontransaction(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value makekeypair(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value validatepubkey(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getnewpubkey(const json_spirit::Array& params, bool fHelp);
|
|
|
|
extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp
|
|
extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value createrawtransaction(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value decodescript(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp);
|
|
|
|
extern json_spirit::Value getbestblockhash(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp
|
|
extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp
|
|
extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getblockheader(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getblockchaininfo(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getblockbynumber(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getcheckpoint(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value gencheckpoints(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value publishcheckpoint(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value recalculatesupply(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value auditsignatures(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value dumputxoset(const json_spirit::Array& params, bool fHelp);
|
|
|
|
extern json_spirit::Value getaddressbalance(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getaddressutxos(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value getaddresstxids(const json_spirit::Array& params, bool fHelp);
|
|
|
|
extern json_spirit::Value smsgenable(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsgdisable(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsglocalkeys(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsgoptions(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsgscanchain(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsgscanbuckets(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsgaddkey(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsggetpubkey(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsgsend(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsgsendanon(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsginbox(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsgoutbox(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsgbuckets(const json_spirit::Array& params, bool fHelp);
|
|
extern json_spirit::Value smsgbroadcast(const json_spirit::Array& params, bool fHelp);
|
|
|
|
#endif
|
|
|
|
|