mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-26 03:03:22 -03:00
interfaces: Change getUnspentOutput return type to avoid multiprocess segfault
Coin serialize method segfaults if IsSpent condition is true. This caused multiprocess code to segfault when serializing the Coin& output argument to of the Node::getUnspentOutput method if the coin was not found. Segfault could be triggered by double clicking and viewing transaction details in the GUI transaction list. Fix this by replacing Coin& output argument with optional<Coin> return value to avoid trying to serializing spent coins.
This commit is contained in:
parent
4978754c00
commit
156f49d682
3 changed files with 8 additions and 8 deletions
|
@ -204,8 +204,8 @@ public:
|
||||||
//! Unset RPC timer interface.
|
//! Unset RPC timer interface.
|
||||||
virtual void rpcUnsetTimerInterface(RPCTimerInterface* iface) = 0;
|
virtual void rpcUnsetTimerInterface(RPCTimerInterface* iface) = 0;
|
||||||
|
|
||||||
//! Get unspent outputs associated with a transaction.
|
//! Get unspent output associated with a transaction.
|
||||||
virtual bool getUnspentOutput(const COutPoint& output, Coin& coin) = 0;
|
virtual std::optional<Coin> getUnspentOutput(const COutPoint& output) = 0;
|
||||||
|
|
||||||
//! Broadcast transaction.
|
//! Broadcast transaction.
|
||||||
virtual TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, std::string& err_string) = 0;
|
virtual TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, std::string& err_string) = 0;
|
||||||
|
|
|
@ -328,10 +328,12 @@ public:
|
||||||
std::vector<std::string> listRpcCommands() override { return ::tableRPC.listCommands(); }
|
std::vector<std::string> listRpcCommands() override { return ::tableRPC.listCommands(); }
|
||||||
void rpcSetTimerInterfaceIfUnset(RPCTimerInterface* iface) override { RPCSetTimerInterfaceIfUnset(iface); }
|
void rpcSetTimerInterfaceIfUnset(RPCTimerInterface* iface) override { RPCSetTimerInterfaceIfUnset(iface); }
|
||||||
void rpcUnsetTimerInterface(RPCTimerInterface* iface) override { RPCUnsetTimerInterface(iface); }
|
void rpcUnsetTimerInterface(RPCTimerInterface* iface) override { RPCUnsetTimerInterface(iface); }
|
||||||
bool getUnspentOutput(const COutPoint& output, Coin& coin) override
|
std::optional<Coin> getUnspentOutput(const COutPoint& output) override
|
||||||
{
|
{
|
||||||
LOCK(::cs_main);
|
LOCK(::cs_main);
|
||||||
return chainman().ActiveChainstate().CoinsTip().GetCoin(output, coin);
|
Coin coin;
|
||||||
|
if (chainman().ActiveChainstate().CoinsTip().GetCoin(output, coin)) return coin;
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, std::string& err_string) override
|
TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, std::string& err_string) override
|
||||||
{
|
{
|
||||||
|
|
|
@ -360,12 +360,10 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall
|
||||||
{
|
{
|
||||||
COutPoint prevout = txin.prevout;
|
COutPoint prevout = txin.prevout;
|
||||||
|
|
||||||
Coin prev;
|
if (auto prev{node.getUnspentOutput(prevout)}) {
|
||||||
if(node.getUnspentOutput(prevout, prev))
|
|
||||||
{
|
|
||||||
{
|
{
|
||||||
strHTML += "<li>";
|
strHTML += "<li>";
|
||||||
const CTxOut &vout = prev.out;
|
const CTxOut& vout = prev->out;
|
||||||
CTxDestination address;
|
CTxDestination address;
|
||||||
if (ExtractDestination(vout.scriptPubKey, address))
|
if (ExtractDestination(vout.scriptPubKey, address))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue