'sendrawtransaction' improvements
- Make it report the reject code and reason - Make it possible to re-send transactions that are already in the mempool
This commit is contained in:
parent
ebb783a9f2
commit
1d46fe3327
2 changed files with 17 additions and 16 deletions
|
@ -49,6 +49,9 @@ enum RPCErrorCode
|
||||||
RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter
|
RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter
|
||||||
RPC_DATABASE_ERROR = -20, // Database error
|
RPC_DATABASE_ERROR = -20, // Database error
|
||||||
RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format
|
RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format
|
||||||
|
RPC_TRANSACTION_ERROR = -25, // General error during transaction submission
|
||||||
|
RPC_TRANSACTION_REJECTED = -26, // Transaction was rejected by network rules
|
||||||
|
RPC_TRANSACTION_ALREADY_IN_CHAIN= -27, // Transaction already in chain
|
||||||
|
|
||||||
// P2P client errors
|
// P2P client errors
|
||||||
RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected
|
RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected
|
||||||
|
|
|
@ -777,25 +777,23 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
||||||
}
|
}
|
||||||
uint256 hashTx = tx.GetHash();
|
uint256 hashTx = tx.GetHash();
|
||||||
|
|
||||||
bool fHave = false;
|
|
||||||
CCoinsViewCache &view = *pcoinsTip;
|
CCoinsViewCache &view = *pcoinsTip;
|
||||||
CCoins existingCoins;
|
CCoins existingCoins;
|
||||||
{
|
bool fHaveMempool = mempool.exists(hashTx);
|
||||||
fHave = view.GetCoins(hashTx, existingCoins);
|
bool fHaveChain = view.GetCoins(hashTx, existingCoins) && existingCoins.nHeight < 1000000000;
|
||||||
if (!fHave) {
|
if (!fHaveMempool && !fHaveChain) {
|
||||||
// push to local node
|
// push to local node and sync with wallets
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!AcceptToMemoryPool(mempool, state, tx, false, NULL, !fOverrideFees))
|
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 {
|
|
||||||
SyncWithWallets(hashTx, tx, NULL);
|
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);
|
RelayTransaction(tx, hashTx);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue