Skip to content

Commit 83d4fb7

Browse files
committed
[packages] return DIFFERENT_WITNESS for same-txid-different-witness tx
The previous interface required callers to guess that the tx had been swapped and look up the tx again by txid to find a `MEMPOOL_ENTRY` result. This is a confusing interface. Instead, explicitly tell the caller that this transaction was `DIFFERENT_WITNESS` in the result linked to the mempool entry's wtxid. This gives the caller all the information they need in 1 lookup, and they can query the mempool for the other transaction if needed.
1 parent 38146a4 commit 83d4fb7

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

src/validation.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,9 +1274,10 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package,
12741274
// transaction for the mempool one. Note that we are ignoring the validity of the
12751275
// package transaction passed in.
12761276
// TODO: allow witness replacement in packages.
1277-
auto iter = m_pool.GetIter(wtxid);
1277+
auto iter = m_pool.GetIter(txid);
12781278
assert(iter != std::nullopt);
1279-
results.emplace(txid, MempoolAcceptResult::MempoolTx(iter.value()->GetTxSize(), iter.value()->GetFee()));
1279+
// Provide the wtxid of the mempool tx so that the caller can look it up in the mempool.
1280+
results.emplace(wtxid, MempoolAcceptResult::MempoolTxDifferentWitness(iter.value()->GetTx().GetWitnessHash()));
12801281
} else {
12811282
// Transaction does not already exist in the mempool.
12821283
txns_new.push_back(tx);

src/validation.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,12 @@ struct MempoolAcceptResult {
161161
VALID, //!> Fully validated, valid.
162162
INVALID, //!> Invalid.
163163
MEMPOOL_ENTRY, //!> Valid, transaction was already in the mempool.
164+
DIFFERENT_WITNESS, //!> Not validated. A same-txid-different-witness tx (see m_other_wtxid) already exists in the mempool and was not replaced.
164165
};
166+
/** Result type. Present in all MempoolAcceptResults. */
165167
const ResultType m_result_type;
168+
169+
/** Contains information about why the transaction failed. */
166170
const TxValidationState m_state;
167171

168172
// The following fields are only present when m_result_type = ResultType::VALID or MEMPOOL_ENTRY
@@ -173,6 +177,10 @@ struct MempoolAcceptResult {
173177
/** Raw base fees in satoshis. */
174178
const std::optional<CAmount> m_base_fees;
175179

180+
// The following field is only present when m_result_type = ResultType::DIFFERENT_WITNESS
181+
/** The wtxid of the transaction in the mempool which has the same txid but different witness. */
182+
const std::optional<uint256> m_other_wtxid;
183+
176184
static MempoolAcceptResult Failure(TxValidationState state) {
177185
return MempoolAcceptResult(state);
178186
}
@@ -185,6 +193,10 @@ struct MempoolAcceptResult {
185193
return MempoolAcceptResult(vsize, fees);
186194
}
187195

196+
static MempoolAcceptResult MempoolTxDifferentWitness(const uint256& other_wtxid) {
197+
return MempoolAcceptResult(other_wtxid);
198+
}
199+
188200
// Private constructors. Use static methods MempoolAcceptResult::Success, etc. to construct.
189201
private:
190202
/** Constructor for failure case */
@@ -201,6 +213,10 @@ struct MempoolAcceptResult {
201213
/** Constructor for already-in-mempool case. It wouldn't replace any transactions. */
202214
explicit MempoolAcceptResult(int64_t vsize, CAmount fees)
203215
: m_result_type(ResultType::MEMPOOL_ENTRY), m_vsize{vsize}, m_base_fees(fees) {}
216+
217+
/** Constructor for witness-swapped case. */
218+
explicit MempoolAcceptResult(const uint256& other_wtxid)
219+
: m_result_type(ResultType::DIFFERENT_WITNESS), m_other_wtxid(other_wtxid) {}
204220
};
205221

206222
/**
@@ -210,7 +226,7 @@ struct PackageMempoolAcceptResult
210226
{
211227
const PackageValidationState m_state;
212228
/**
213-
* Map from (w)txid to finished MempoolAcceptResults. The client is responsible
229+
* Map from wtxid to finished MempoolAcceptResults. The client is responsible
214230
* for keeping track of the transaction objects themselves. If a result is not
215231
* present, it means validation was unfinished for that transaction. If there
216232
* was a package-wide error (see result in m_state), m_tx_results will be empty.

0 commit comments

Comments
 (0)