-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Unify CWalletTx construction #9680
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
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.
mapWallet.at()
can throw so I guess it should be avoided and replaced with mapWallet.find()
, to test the returned iterator.
Needs rebase.
src/qt/walletmodel.cpp
Outdated
@@ -578,9 +578,9 @@ void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vect | |||
for (const COutPoint& outpoint : vOutpoints) | |||
{ | |||
if (!wallet->mapWallet.count(outpoint.hash)) continue; | |||
int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain(); | |||
int nDepth = wallet->mapWallet.at(outpoint.hash).GetDepthInMainChain(); | |||
if (nDepth < 0) continue; |
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.
Isn't this condition taking advantage of the dummy CWalletTx
? If so replace .at()
with .find()
and test the iterator.
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.
Isn't this condition taking advantage of the dummy CWalletTx? If so replace .at() with .find() and test the iterator.
Dummy constructor isn't called here because of the count check above.
src/qt/walletmodel.cpp
Outdated
if (nDepth < 0) continue; | ||
COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true /* spendable */, true /* solvable */, true /* safe */); | ||
COutput out(&wallet->mapWallet.at(outpoint.hash), outpoint.n, nDepth, true /* spendable */, true /* solvable */, true /* safe */); |
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.
Another lookup? With the above suggestion it can be avoided.
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.
Another lookup? With the above suggestion it can be avoided.
It looks like this is done in your PR #11039. I'll review that PR, so this PR can be limited to replacing [] lookups with at() lookups.
src/wallet/feebumper.cpp
Outdated
@@ -246,7 +246,7 @@ bool CFeeBumper::commit(CWallet *pWallet) | |||
currentResult = BumpFeeResult::MISC_ERROR; | |||
return false; | |||
} | |||
CWalletTx& oldWtx = pWallet->mapWallet[txid]; | |||
CWalletTx& oldWtx = pWallet->mapWallet.at(txid); |
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.
Replace with .find(txid)
above (before .count()
) and test if exists, also avoids 2nd lookup.
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.
Replace with .find(txid) above (before .count()) and test if exists, also avoids 2nd lookup.
Also seems to be taken care of in #11039.
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.
Thanks very much for the review. Rebased 2245b37 -> 51b93a9 (pr/makewtx.4 -> pr/makewtx.5), just fixing minor merge conflicts.
src/qt/walletmodel.cpp
Outdated
@@ -578,9 +578,9 @@ void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vect | |||
for (const COutPoint& outpoint : vOutpoints) | |||
{ | |||
if (!wallet->mapWallet.count(outpoint.hash)) continue; | |||
int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain(); | |||
int nDepth = wallet->mapWallet.at(outpoint.hash).GetDepthInMainChain(); | |||
if (nDepth < 0) continue; |
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.
Isn't this condition taking advantage of the dummy CWalletTx? If so replace .at() with .find() and test the iterator.
Dummy constructor isn't called here because of the count check above.
src/qt/walletmodel.cpp
Outdated
if (nDepth < 0) continue; | ||
COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true /* spendable */, true /* solvable */, true /* safe */); | ||
COutput out(&wallet->mapWallet.at(outpoint.hash), outpoint.n, nDepth, true /* spendable */, true /* solvable */, true /* safe */); |
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.
Another lookup? With the above suggestion it can be avoided.
It looks like this is done in your PR #11039. I'll review that PR, so this PR can be limited to replacing [] lookups with at() lookups.
src/wallet/feebumper.cpp
Outdated
@@ -246,7 +246,7 @@ bool CFeeBumper::commit(CWallet *pWallet) | |||
currentResult = BumpFeeResult::MISC_ERROR; | |||
return false; | |||
} | |||
CWalletTx& oldWtx = pWallet->mapWallet[txid]; | |||
CWalletTx& oldWtx = pWallet->mapWallet.at(txid); |
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.
Replace with .find(txid) above (before .count()) and test if exists, also avoids 2nd lookup.
Also seems to be taken care of in #11039.
Great! I've always been wary of this projects' gratuitous use of So concept ACK at least - haven't been able to review all the changes in detail. |
8fc4343
to
0a8204b
Compare
0a8204b
to
1cf7f53
Compare
src/wallet/rpcwallet.cpp
Outdated
@@ -379,7 +379,7 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request) | |||
return ret; | |||
} | |||
|
|||
static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew, const CCoinControl& coin_control) | |||
static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, const CCoinControl& coin_control, mapValue_t mapValue, std::string fromAccount, CTransactionRef& txNew) |
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.
Given that the argument txNew
seems to be only used to store the resulting output in, wouldn't it be more convenient to make it the return type rather than an argument?
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.
Given that the argument txNew seems to be only used to store the resulting output in, wouldn't it be more convenient to make it the return type rather than an argument?
Forgot to respond to this comment, but this was a good idea, and I implemented it in a previous update to the PR: a0a4d82 -> f16d28c (pr/makewtx.11 -> pr/makewtx.12)
Nice! |
a0a4d82
to
f16d28c
Compare
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.
utACK f16d28c
src/qt/walletmodel.cpp
Outdated
return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(state.GetRejectReason())); | ||
|
||
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); | ||
ssTx << *newTx->tx; | ||
ssTx << **newTx; |
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 think the extra dereference isn't needed here; serializing a std::shared_ptr<X>
should work, if X
is serializable.
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.
Done in d070a69
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.
Added 1 commit f16d28c -> d070a69 (pr/makewtx.12 -> pr/makewtx.13, compare)
Squashed d070a69 -> 1dc99fb (pr/makewtx.13 -> pr/makewtx.14)
Rebased 1dc99fb -> fe84e57 (pr/makewtx.14 -> pr/makewtx.15)
Rebased fe84e57 -> 857a50a (pr/makewtx.15 -> pr/makewtx.16)
Rebased 857a50a -> d8f17e6 (pr/makewtx.16 -> pr/makewtx.17)
Rebased d8f17e6 -> 1531d0d (pr/makewtx.17 -> pr/makewtx.18)
Rebased 1531d0d -> 0c6ee54 (pr/makewtx.18 -> pr/makewtx.19)
Rebased 0c6ee54 -> b110df7 (pr/makewtx.19 -> pr/makewtx.20)
Rebased b110df7 -> 7bae52b (pr/makewtx.20 -> pr/makewtx.21)
1dc99fb
to
fe84e57
Compare
fe84e57
to
857a50a
Compare
d8f17e6
to
1531d0d
Compare
b110df7
to
7bae52b
Compare
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.
Concept ACK 7bae52b
src/wallet/test/accounting_tests.cpp
Outdated
@@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) | |||
|
|||
wtx.mapValue["comment"] = "z"; | |||
pwalletMain->AddToWallet(wtx); | |||
vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]); | |||
vpwtx.push_back(&pwalletMain->mapWallet.at(wtx.GetHash())); |
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.
The commit message seems to suggest .at()
will cause compile-time errors for non-existent keys, but from what I understand at()
will throw runtime out_of_range
exceptions. This change in behavior seems okay, but I don't have great context here -- are we alright with these lines now being liable to throw runtime exceptions?
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.
Oops, commit message is mistaken, it should say "runtime exceptions" not "compile errors". But the change is intentional because it should be preferable to throw exceptions if invalid txids are looked up instead of creating empty map entries with null CTransactionRef pointers that might later get dereferenced.
ACK 7bae52b Cloned this branch, compiled, and ran |
Updated commit message 7bae52b -> a5a2e7e (pr/makewtx.21 -> pr/makewtx.22), no other changes. |
ACK a5a2e7e |
Rebased a5a2e7e -> da94a51 (pr/makewtx.22 -> pr/makewtx.23) due to conflict with #12421 causing travis build failures. |
Construct CWalletTx objects in CWallet::CommitTransaction, instead of having callers do it. This ensures CWalletTx objects are constructed in a uniform way and all fields are set. This also makes it possible to avoid confusing and wasteful CWalletTx copies in bitcoin#9381 There is no change in behavior.
No change in behavior in the normal case. But buggy mapWallet lookups with invalid txids will now throw exceptions instead of inserting dummy entries into the map, and potentially causing segfaults and other failures. This also makes it a compiler error to use the mapWallet[hash] syntax which could create dummy entries.
Needs rebase |
Rebased 8fcd24e -> 2c08d0b (pr/makewtx.24 -> pr/makewtx.25) for #12607. |
Added 1 commits 2c08d0b -> d0b8536 (pr/makewtx.25 -> pr/makewtx.26, compare) implementing suggestion from #9381 (comment). |
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.
utACK a128bdc
utACK b4bc32a |
b4bc32a [wallet] Get rid of CWalletTx default constructor (Russell Yanofsky) a128bdc [wallet] Construct CWalletTx objects in CommitTransaction (Russell Yanofsky) Pull request description: Two commits: - `Construct CWalletTx objects in CommitTransaction` moves a bunch of CWalletTx initialization into CWallet::CommitTransaction to dedup some code and avoid future inconsistencies in how wallet transactions are created. - `Get rid of CWalletTx default constructor` does what is described and eliminates the possibility of empty transaction entries being inadvertently created by mapWallet[hash] accesses. Both of these changes were originally part of #9381 Tree-SHA512: af3841c4f0539e0662d81b33c5369fc70aa06ddde1c59cb00fb21c9e4c7d9ff47f1edc5040cb463af1333838802c56b3ef875b939e2b804ee45b8e0294a4371c
* [wallet] Construct CWalletTx objects in CommitTransaction Construct CWalletTx objects in CWallet::CommitTransaction, instead of having callers do it. This ensures CWalletTx objects are constructed in a uniform way and all fields are set. This also makes it possible to avoid confusing and wasteful CWalletTx copies in bitcoin#9381 There is no change in behavior. * [wallet] Get rid of CWalletTx default constructor No change in behavior in the normal case. But buggy mapWallet lookups with invalid txids will now throw exceptions instead of inserting dummy entries into the map, and potentially causing segfaults and other failures. This also makes it a compiler error to use the mapWallet[hash] syntax which could create dummy entries. * Apply suggestions from code review Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com> Co-authored-by: Russell Yanofsky <russ@yanofsky.org> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Two commits:
Construct CWalletTx objects in CommitTransaction
moves a bunch of CWalletTx initialization into CWallet::CommitTransaction to dedup some code and avoid future inconsistencies in how wallet transactions are created.Get rid of CWalletTx default constructor
does what is described and eliminates the possibility of empty transaction entries being inadvertently created by mapWallet[hash] accesses.Both of these changes were originally part of #9381