aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Ofsky <ryan@ofsky.org>2024-08-06 10:47:15 -0400
committerRyan Ofsky <ryan@ofsky.org>2024-08-06 11:31:03 -0400
commit870447fd585e5926b4ce4e83db31c59b1be45a50 (patch)
tree95641bd17739df684c42f502d8de3a81d6795856
parent31a3ff55154bf15fb35b157c3f67ec05408ecdf9 (diff)
parente9de0a76b99fd4708295e1178f6c079db92e7f36 (diff)
Merge bitcoin/bitcoin#30212: rename TransactionError:ALREADY_IN_CHAIN
e9de0a76b99fd4708295e1178f6c079db92e7f36 doc: release note for 30212 (willcl-ark) 87b188052528e97729a85d9701864eaff1ea5ec6 rpc: clarify ALREADY_IN_CHAIN rpc errors (willcl-ark) Pull request description: Closes: #19363 Renaming this error improves clarity around the returned error both internally and externally when a transactions' outputs are already found in the utxo set (`TransactionError::ALREADY_IN_CHAIN -> TransactionError::ALREADY_IN_UTXO_SET`) ACKs for top commit: tdb3: ACK e9de0a76b99fd4708295e1178f6c079db92e7f36 ismaelsadeeq: ACK e9de0a76b99fd4708295e1178f6c079db92e7f36 ryanofsky: Code review ACK e9de0a76b99fd4708295e1178f6c079db92e7f36. Tree-SHA512: 7d2617200909790340951fe56a241448f9ce511900777cb2a712e8b9c0778a27d1f912b460f82335844224f1abb4322bc898ca076440959edade55c082a09237
-rw-r--r--doc/release-notes-30212.md8
-rw-r--r--src/common/messages.cpp4
-rw-r--r--src/node/transaction.cpp2
-rw-r--r--src/node/types.h2
-rw-r--r--src/rpc/mempool.cpp2
-rw-r--r--src/rpc/protocol.h3
-rw-r--r--src/rpc/util.cpp4
-rw-r--r--src/test/fuzz/kitchen_sink.cpp2
-rwxr-xr-xtest/functional/rpc_rawtransaction.py4
9 files changed, 19 insertions, 12 deletions
diff --git a/doc/release-notes-30212.md b/doc/release-notes-30212.md
new file mode 100644
index 0000000000..cc4ea59b7f
--- /dev/null
+++ b/doc/release-notes-30212.md
@@ -0,0 +1,8 @@
+RPC
+---
+
+- Previously when using the `sendrawtransaction` rpc and specifying outputs
+ that are already in the UXTO set an RPC error code `-27` with RPC error
+ text "Transaction already in block chain" was returned in response.
+ The help text has been updated to "Transaction outputs already in utxo set"
+ to more accurately describe the source of the issue.
diff --git a/src/common/messages.cpp b/src/common/messages.cpp
index 9e88ca8b0f..6a3ebbca67 100644
--- a/src/common/messages.cpp
+++ b/src/common/messages.cpp
@@ -100,8 +100,8 @@ bilingual_str TransactionErrorString(const TransactionError err)
return Untranslated("No error");
case TransactionError::MISSING_INPUTS:
return Untranslated("Inputs missing or spent");
- case TransactionError::ALREADY_IN_CHAIN:
- return Untranslated("Transaction already in block chain");
+ case TransactionError::ALREADY_IN_UTXO_SET:
+ return Untranslated("Transaction outputs already in utxo set");
case TransactionError::MEMPOOL_REJECTED:
return Untranslated("Transaction rejected by mempool");
case TransactionError::MEMPOOL_ERROR:
diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp
index 591dcd698d..0f45da45db 100644
--- a/src/node/transaction.cpp
+++ b/src/node/transaction.cpp
@@ -55,7 +55,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
const Coin& existingCoin = view.AccessCoin(COutPoint(txid, o));
// IsSpent doesn't mean the coin is spent, it means the output doesn't exist.
// So if the output does exist, then this transaction exists in the chain.
- if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_CHAIN;
+ if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_UTXO_SET;
}
if (auto mempool_tx = node.mempool->get(txid); mempool_tx) {
diff --git a/src/node/types.h b/src/node/types.h
index bb8d17ef43..1302f1b127 100644
--- a/src/node/types.h
+++ b/src/node/types.h
@@ -19,7 +19,7 @@ namespace node {
enum class TransactionError {
OK, //!< No error
MISSING_INPUTS,
- ALREADY_IN_CHAIN,
+ ALREADY_IN_UTXO_SET,
MEMPOOL_REJECTED,
MEMPOOL_ERROR,
MAX_FEE_EXCEEDED,
diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp
index b67d272b65..d61898260b 100644
--- a/src/rpc/mempool.cpp
+++ b/src/rpc/mempool.cpp
@@ -43,7 +43,7 @@ static RPCHelpMan sendrawtransaction()
"\nThe transaction will be sent unconditionally to all peers, so using sendrawtransaction\n"
"for manual rebroadcast may degrade privacy by leaking the transaction's origin, as\n"
"nodes will normally not rebroadcast non-wallet transactions already in their mempool.\n"
- "\nA specific exception, RPC_TRANSACTION_ALREADY_IN_CHAIN, may throw if the transaction cannot be added to the mempool.\n"
+ "\nA specific exception, RPC_TRANSACTION_ALREADY_IN_UTXO_SET, may throw if the transaction cannot be added to the mempool.\n"
"\nRelated RPCs: createrawtransaction, signrawtransactionwithkey\n",
{
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h
index 83a9010681..0574335c96 100644
--- a/src/rpc/protocol.h
+++ b/src/rpc/protocol.h
@@ -46,14 +46,13 @@ enum RPCErrorCode
RPC_DESERIALIZATION_ERROR = -22, //!< Error parsing or validating structure in raw format
RPC_VERIFY_ERROR = -25, //!< General error during transaction or block submission
RPC_VERIFY_REJECTED = -26, //!< Transaction or block was rejected by network rules
- RPC_VERIFY_ALREADY_IN_CHAIN = -27, //!< Transaction already in chain
+ RPC_VERIFY_ALREADY_IN_UTXO_SET = -27, //!< Transaction already in utxo set
RPC_IN_WARMUP = -28, //!< Client still warming up
RPC_METHOD_DEPRECATED = -32, //!< RPC method is deprecated
//! Aliases for backward compatibility
RPC_TRANSACTION_ERROR = RPC_VERIFY_ERROR,
RPC_TRANSACTION_REJECTED = RPC_VERIFY_REJECTED,
- RPC_TRANSACTION_ALREADY_IN_CHAIN= RPC_VERIFY_ALREADY_IN_CHAIN,
//! P2P client errors
RPC_CLIENT_NOT_CONNECTED = -9, //!< Bitcoin is not connected
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index 680882c989..cc49670198 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -399,8 +399,8 @@ RPCErrorCode RPCErrorFromTransactionError(TransactionError terr)
switch (terr) {
case TransactionError::MEMPOOL_REJECTED:
return RPC_TRANSACTION_REJECTED;
- case TransactionError::ALREADY_IN_CHAIN:
- return RPC_TRANSACTION_ALREADY_IN_CHAIN;
+ case TransactionError::ALREADY_IN_UTXO_SET:
+ return RPC_VERIFY_ALREADY_IN_UTXO_SET;
default: break;
}
return RPC_TRANSACTION_ERROR;
diff --git a/src/test/fuzz/kitchen_sink.cpp b/src/test/fuzz/kitchen_sink.cpp
index 4468f358d9..62b49106cd 100644
--- a/src/test/fuzz/kitchen_sink.cpp
+++ b/src/test/fuzz/kitchen_sink.cpp
@@ -23,7 +23,7 @@ using node::TransactionError;
namespace {
constexpr TransactionError ALL_TRANSACTION_ERROR[] = {
TransactionError::MISSING_INPUTS,
- TransactionError::ALREADY_IN_CHAIN,
+ TransactionError::ALREADY_IN_UTXO_SET,
TransactionError::MEMPOOL_REJECTED,
TransactionError::MEMPOOL_ERROR,
TransactionError::MAX_FEE_EXCEEDED,
diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py
index aa179e009d..18b1fc1896 100755
--- a/test/functional/rpc_rawtransaction.py
+++ b/test/functional/rpc_rawtransaction.py
@@ -430,13 +430,13 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(testres['allowed'], True)
self.nodes[2].sendrawtransaction(hexstring=tx['hex'], maxfeerate='0.20000000')
- self.log.info("Test sendrawtransaction/testmempoolaccept with tx already in the chain")
+ self.log.info("Test sendrawtransaction/testmempoolaccept with tx outputs already in the utxo set")
self.generate(self.nodes[2], 1)
for node in self.nodes:
testres = node.testmempoolaccept([tx['hex']])[0]
assert_equal(testres['allowed'], False)
assert_equal(testres['reject-reason'], 'txn-already-known')
- assert_raises_rpc_error(-27, 'Transaction already in block chain', node.sendrawtransaction, tx['hex'])
+ assert_raises_rpc_error(-27, 'Transaction outputs already in utxo set', node.sendrawtransaction, tx['hex'])
def decoderawtransaction_tests(self):
self.log.info("Test decoderawtransaction")