-
Notifications
You must be signed in to change notification settings - Fork 37.7k
wallet: do not count wallet utxos as external #24649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I'm not entirely sure that this is what we want to do. When I implemented that external input weight feature, I specifically decided to allow user provided weight to override what the wallet does. This is because if a user were using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe |
Oh indeed. Looking at |
Yes, but it doesn't do so in |
@achow101 added a test case |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
ACK 3b83b8a Thanks for the test case, now I see what the problem is. |
ACK 3b83b8a |
3b83b8a
to
7832e94
Compare
Github-Pull: bitcoin#24649 Rebased-From: b9a2da7
Github-Pull: bitcoin#24649 Rebased-From: 3b83b8a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re-ACK 7832e94
wallet.chain().findCoins(coins); | ||
|
||
for (const CTxIn& txin : tx.vin) { | ||
// if it's not in the wallet and corresponding UTXO is found than select as external output |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit, if you have to rebase or touch something else:
// if it's not in the wallet and corresponding UTXO is found than select as external output | |
// if it's not in the wallet and corresponding UTXO is found, then select as external output |
re-ACK 7832e94 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code reviewed 7832e94
for (const CTxIn& txin : tx.vin) { | ||
coins[txin.prevout]; // Create empty map entry keyed by prevout. | ||
} | ||
wallet.chain().findCoins(coins); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point, we have cs_wallet
locked (lock is few lines above) and inside findCoins
we lock cs_main
Wonder if it's a potential deadlock cause or not. Because, cs_main
should be taking precedence over cs_wallet
in other processes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree it could be a problem in theory, but I'd like to understand the problem better before making a change.
Right now I couldn't find any places in our code that acquire cs_wallet
while holding cs_main
. To experiment I added LOCK(cs_main)
to wallet/rpc/coins.cpp:197
and immediately this triggered our deadlock detection mechanism because it turns out that loadwallet
rpc acquires lock in a different order (first cs_wallet
and then cs_main
).
What is our long-term direction with regards to using cs_main
and cs_wallet
together?
@achow101 any thoughts?
I'm also curious how we should think of these locks in light of multiprocess (cc @ryanofsky )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cs_main
is really for things in node operation and so there should never be a scenario within the wallet where we lock cs_main
before cs_wallet
. That would imply that the node is doing something to the wallet, but the model we (want to) have is the wallet asks for things from the node and otherwise operates asynchronously from the node. So it should always be cs_wallet
before cs_main
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@furszy Looks like the current lock order is fine. Is there anything left before you can ACK this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was thinking on moving the "fetch coins" block of code above the cs_wallet
lock, so both mutexes are locked independently from each other.
But, at this point, it's merely a nit.
for (const CTxIn& txin : tx.vin) { | ||
// if it's not in the wallet and corresponding UTXO is found than select as external output | ||
const auto& outPoint = txin.prevout; | ||
if (wallet.mapWallet.find(outPoint.hash) == wallet.mapWallet.end() && !coins[outPoint].out.IsNull()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: would be better to use wallet.GetWalletTx(hash)
instead of accessing the wallet's map directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do if I have to retouch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 7832e94
(Thanks for the reminder)
for (const CTxIn& txin : tx.vin) { | ||
coins[txin.prevout]; // Create empty map entry keyed by prevout. | ||
} | ||
wallet.chain().findCoins(coins); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was thinking on moving the "fetch coins" block of code above the cs_wallet
lock, so both mutexes are locked independently from each other.
But, at this point, it's merely a nit.
Correctly differentiating between external vs non-external utxos in coin control produces more accurate weight and fee estimations.
Weight for external utxos is estimated based on the maximum signature size, while for the wallet utxos we expect minimal signature due to signature grinding.