|
|
|
@ -777,25 +777,23 @@ Value sendrawtransaction(const Array& params, bool fHelp)
@@ -777,25 +777,23 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
|
|
|
|
} |
|
|
|
|
uint256 hashTx = tx.GetHash(); |
|
|
|
|
|
|
|
|
|
bool fHave = false; |
|
|
|
|
CCoinsViewCache &view = *pcoinsTip; |
|
|
|
|
CCoins existingCoins; |
|
|
|
|
{ |
|
|
|
|
fHave = view.GetCoins(hashTx, existingCoins); |
|
|
|
|
if (!fHave) { |
|
|
|
|
// push to local node
|
|
|
|
|
bool fHaveMempool = mempool.exists(hashTx); |
|
|
|
|
bool fHaveChain = view.GetCoins(hashTx, existingCoins) && existingCoins.nHeight < 1000000000; |
|
|
|
|
if (!fHaveMempool && !fHaveChain) { |
|
|
|
|
// push to local node and sync with wallets
|
|
|
|
|
CValidationState state; |
|
|
|
|
if (!AcceptToMemoryPool(mempool, state, tx, false, NULL, !fOverrideFees)) |
|
|
|
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected"); // TODO: report validation state
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (fHave) { |
|
|
|
|
if (existingCoins.nHeight < 1000000000) |
|
|
|
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "transaction already in block chain"); |
|
|
|
|
// Not in block, but already in the memory pool; will drop
|
|
|
|
|
// through to re-relay it.
|
|
|
|
|
} else { |
|
|
|
|
if (AcceptToMemoryPool(mempool, state, tx, false, NULL, !fOverrideFees)) |
|
|
|
|
SyncWithWallets(hashTx, tx, NULL); |
|
|
|
|
else { |
|
|
|
|
if(state.IsInvalid()) |
|
|
|
|
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason())); |
|
|
|
|
else |
|
|
|
|
throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason()); |
|
|
|
|
} |
|
|
|
|
} else if (fHaveChain) { |
|
|
|
|
throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain"); |
|
|
|
|
} |
|
|
|
|
RelayTransaction(tx, hashTx); |
|
|
|
|
|
|
|
|
|