aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2014-02-22 12:02:42 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2014-03-27 12:33:55 +0100
commit1d46fe3327f6645fd79b442cd72ef422418c1a50 (patch)
tree0f7a4f089e41ba3e6697e8e30436f2f7b36f756f /src
parentebb783a9f2acd0992a5497deb4953271ebfa4726 (diff)
'sendrawtransaction' improvements
- Make it report the reject code and reason - Make it possible to re-send transactions that are already in the mempool
Diffstat (limited to 'src')
-rw-r--r--src/rpcprotocol.h3
-rw-r--r--src/rpcrawtransaction.cpp30
2 files changed, 17 insertions, 16 deletions
diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h
index 80cdb34f15..8b3df19621 100644
--- a/src/rpcprotocol.h
+++ b/src/rpcprotocol.h
@@ -49,6 +49,9 @@ enum RPCErrorCode
RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter
RPC_DATABASE_ERROR = -20, // Database error
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
RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index 837aee7eaa..f0267cf8ab 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -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
- CValidationState state;
- if (!AcceptToMemoryPool(mempool, state, tx, false, NULL, !fOverrideFees))
- throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected"); // TODO: report validation state
+ 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))
+ 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());
}
- }
- 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);
+ } else if (fHaveChain) {
+ throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
}
RelayTransaction(tx, hashTx);