|
|
@ -11,6 +11,7 @@ |
|
|
|
#include "init.h" |
|
|
|
#include "init.h" |
|
|
|
#include "keystore.h" |
|
|
|
#include "keystore.h" |
|
|
|
#include "validation.h" |
|
|
|
#include "validation.h" |
|
|
|
|
|
|
|
#include "validationinterface.h" |
|
|
|
#include "merkleblock.h" |
|
|
|
#include "merkleblock.h" |
|
|
|
#include "net.h" |
|
|
|
#include "net.h" |
|
|
|
#include "policy/policy.h" |
|
|
|
#include "policy/policy.h" |
|
|
@ -30,6 +31,7 @@ |
|
|
|
#include "wallet/wallet.h" |
|
|
|
#include "wallet/wallet.h" |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <future> |
|
|
|
#include <stdint.h> |
|
|
|
#include <stdint.h> |
|
|
|
|
|
|
|
|
|
|
|
#include <univalue.h> |
|
|
|
#include <univalue.h> |
|
|
@ -917,7 +919,9 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
ObserveSafeMode(); |
|
|
|
ObserveSafeMode(); |
|
|
|
LOCK(cs_main); |
|
|
|
|
|
|
|
|
|
|
|
std::promise<void> promise; |
|
|
|
|
|
|
|
|
|
|
|
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); |
|
|
|
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); |
|
|
|
|
|
|
|
|
|
|
|
// parse hex string from parameter
|
|
|
|
// parse hex string from parameter
|
|
|
@ -931,6 +935,8 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) |
|
|
|
if (!request.params[1].isNull() && request.params[1].get_bool()) |
|
|
|
if (!request.params[1].isNull() && request.params[1].get_bool()) |
|
|
|
nMaxRawTxFee = 0; |
|
|
|
nMaxRawTxFee = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ // cs_main scope
|
|
|
|
|
|
|
|
LOCK(cs_main); |
|
|
|
CCoinsViewCache &view = *pcoinsTip; |
|
|
|
CCoinsViewCache &view = *pcoinsTip; |
|
|
|
bool fHaveChain = false; |
|
|
|
bool fHaveChain = false; |
|
|
|
for (size_t o = 0; !fHaveChain && o < tx->vout.size(); o++) { |
|
|
|
for (size_t o = 0; !fHaveChain && o < tx->vout.size(); o++) { |
|
|
@ -952,10 +958,24 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) |
|
|
|
} |
|
|
|
} |
|
|
|
throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason()); |
|
|
|
throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// If wallet is enabled, ensure that the wallet has been made aware
|
|
|
|
|
|
|
|
// of the new transaction prior to returning. This prevents a race
|
|
|
|
|
|
|
|
// where a user might call sendrawtransaction with a transaction
|
|
|
|
|
|
|
|
// to/from their wallet, immediately call some wallet RPC, and get
|
|
|
|
|
|
|
|
// a stale result because callbacks have not yet been processed.
|
|
|
|
|
|
|
|
CallFunctionInValidationInterfaceQueue([&promise] { |
|
|
|
|
|
|
|
promise.set_value(); |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (fHaveChain) { |
|
|
|
} else if (fHaveChain) { |
|
|
|
throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain"); |
|
|
|
throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // cs_main
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
promise.get_future().wait(); |
|
|
|
|
|
|
|
|
|
|
|
if(!g_connman) |
|
|
|
if(!g_connman) |
|
|
|
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); |
|
|
|
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); |
|
|
|
|
|
|
|
|
|
|
@ -964,6 +984,7 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) |
|
|
|
{ |
|
|
|
{ |
|
|
|
pnode->PushInventory(inv); |
|
|
|
pnode->PushInventory(inv); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
return hashTx.GetHex(); |
|
|
|
return hashTx.GetHex(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|