@ -5,7 +5,6 @@
# include <consensus/validation.h>
# include <net.h>
# include <rpc/server.h>
# include <txmempool.h>
# include <validation.h>
# include <validationinterface.h>
@ -13,9 +12,36 @@
# include <future>
uint256 BroadcastTransaction ( const CTransactionRef tx , const bool allowhighfees ) {
const char * TransactionErrorString ( const TransactionError err )
{
switch ( err ) {
case TransactionError : : OK :
return " No error " ;
case TransactionError : : MISSING_INPUTS :
return " Missing inputs " ;
case TransactionError : : ALREADY_IN_CHAIN :
return " Transaction already in block chain " ;
case TransactionError : : P2P_DISABLED :
return " Peer-to-peer functionality missing or disabled " ;
case TransactionError : : MEMPOOL_REJECTED :
return " Transaction rejected by AcceptToMemoryPool " ;
case TransactionError : : MEMPOOL_ERROR :
return " AcceptToMemoryPool failed " ;
case TransactionError : : INVALID_PSBT :
return " PSBT is not sane " ;
case TransactionError : : SIGHASH_MISMATCH :
return " Specified sighash value does not match existing value " ;
case TransactionError : : UNKNOWN_ERROR :
default : break ;
}
return " Unknown error " ;
}
bool BroadcastTransaction ( const CTransactionRef tx , uint256 & hashTx , TransactionError & error , std : : string & err_string , const bool allowhighfees )
{
std : : promise < void > promise ;
const uint256 & hashTx = tx - > GetHash ( ) ;
hashTx = tx - > GetHash ( ) ;
CAmount nMaxRawTxFee = maxTxFee ;
if ( allowhighfees )
@ -37,12 +63,17 @@ uint256 BroadcastTransaction(const CTransactionRef tx, const bool allowhighfees)
if ( ! AcceptToMemoryPool ( mempool , state , std : : move ( tx ) , & fMissingInputs ,
nullptr /* plTxnReplaced */ , false /* bypass_limits */ , nMaxRawTxFee ) ) {
if ( state . IsInvalid ( ) ) {
throw JSONRPCError ( RPC_TRANSACTION_REJECTED , FormatStateMessage ( state ) ) ;
err_string = FormatStateMessage ( state ) ;
error = TransactionError : : MEMPOOL_REJECTED ;
return false ;
} else {
if ( fMissingInputs ) {
throw JSONRPCError ( RPC_TRANSACTION_ERROR , " Missing inputs " ) ;
error = TransactionError : : MISSING_INPUTS ;
return false ;
}
throw JSONRPCError ( RPC_TRANSACTION_ERROR , FormatStateMessage ( state ) ) ;
err_string = FormatStateMessage ( state ) ;
error = TransactionError : : MEMPOOL_ERROR ;
return false ;
}
} else {
// If wallet is enabled, ensure that the wallet has been made aware
@ -55,7 +86,8 @@ uint256 BroadcastTransaction(const CTransactionRef tx, const bool allowhighfees)
} ) ;
}
} else if ( fHaveChain ) {
throw JSONRPCError ( RPC_TRANSACTION_ALREADY_IN_CHAIN , " transaction already in block chain " ) ;
error = TransactionError : : ALREADY_IN_CHAIN ;
return false ;
} else {
// Make sure we don't block forever if re-sending
// a transaction already in mempool.
@ -66,8 +98,10 @@ uint256 BroadcastTransaction(const CTransactionRef tx, const bool allowhighfees)
promise . get_future ( ) . wait ( ) ;
if ( ! g_connman )
throw JSONRPCError ( RPC_CLIENT_P2P_DISABLED , " Error: Peer-to-peer functionality missing or disabled " ) ;
if ( ! g_connman ) {
error = TransactionError : : P2P_DISABLED ;
return false ;
}
CInv inv ( MSG_TX , hashTx ) ;
g_connman - > ForEachNode ( [ & inv ] ( CNode * pnode )
@ -75,5 +109,5 @@ uint256 BroadcastTransaction(const CTransactionRef tx, const bool allowhighfees)
pnode - > PushInventory ( inv ) ;
} ) ;
return hashTx ;
}
return true ;
}