Commit graph

26 commits

Author SHA1 Message Date
Byron Hambly
a20c67310c Merge b1a672d158 into merged_master (Bitcoin PR bitcoin/bitcoin#22337) 2023-04-07 11:57:51 +00:00
Andrew Poelstra
e5e3ec2700
wallet: account for issuances during coin selection
Prior to coin selection we need to indicate that the issuances will take
extra space, otherwise we may fail to select enough coins to cover our
fees, triggering the new "fee needed exceeds fees available" assertion.
2022-09-22 13:20:29 +00:00
Andrew Poelstra
79fd90f064
wallet: extend fix to "dropped change is the last blinded output" case 2022-09-20 21:17:47 +00:00
Andrew Poelstra
fac694be4c
wallet: don't clear out all the blinding data when dropping change
The Elements 22 blinding logic has an edge case where when we drop change,
leaving only a single blinded output, we recompute a bunch of blinding
data to handle the potential for us to have 0 inputs and 1 output to blind.
(BlindTransaction will fail in this case because it cannot make the
transaction balance with only one output to mess with.)

In this recomputation, we dropped more data than we meant to, causing us
to incorrectly blind an output.
2022-09-20 17:40:47 +00:00
Andrew Poelstra
23e91d0ef8
wallet: fix some fee calculation bugs
First, this reverts commit ca2d72ae8b to reinstate
an assertion that was added in Bitcoin #22686. It did not compile because our
`change_and_fee` variable is a map rather than number; I changed it to use
`map_change_and_fee.at(policyAsset)` to match the equivalent change 2 lines down
from a5d97b363b (merge of Bitcoin #22008).

Then fix the following bugs:

1. Change the new test in rpc_fundrawtransaction.py to bump the -maxtxfee value,
   which we'd otherwise exceed, failing the test and masking actual failures.
   (This was just caused by the extreme fee settings of the test combined with
   Elements' large transactions.)
2. Change the fee-output size estimation for `tx_noinputs_size` to be 46 rather
   than 44 bytes; we forgot that even null surjection/rangeproofs need a 0 byte
   when output witnesses are present. This mistake triggered the new assertion.
3. Correct the logic in which change outputs are sometimes dropped even when
   they are the only blinded output in a transaction with blinded inputs. This
   would cause the new test to fail with `bad-txn-inputs-ne-outputs`; I'm very
   surprised that no existing tests hit this.

   (I have an existing comment block in this code where I "promise" that I had
   a good reason for doing something mysterious related to blinding. I was not
   able to reverse-engineer my intention here, though I think it is related to
   this, but since I couldn't understand it I just left this block intact and
   worked around it.)
4. This then triggered the assertion again since the coin selection code
   assumes that sufficiently-small change will always be dropped. If we prevent
   this drop we will have under-funded the transaction.

   To fix this we add Yet Another Flag `may_need_blinded_dummy` in which we add
   extra weight to `tx_noinputs_size` in the case that we're doing a blinded tx
   but have no blind destinations. We turn this off after coin selection if it
   turns out that we don't have any blinded inputs, though ofc at that point
   much of the damage/inefficiency has already been done..
5. Fix some constants in other functional tests which assumed precise fee
   calculations; these precise values changed because of fixes (2) and (4).

There is one new FIXME, which is that the "dummy change" value will now be a
zero-valued OP_RETURN but we still put a full-size rangeproof and surjection
proof on it. There is some plausible privacy benefit to this but not much,
and wasting 5000+ bytes rather than the ~65 needed for an exact-value proof
is not worth it. We will fix this in the future when we overhaul the wallet
blinding logic.
2022-09-20 17:39:24 +00:00
Glenn Willen
2273079c45
elements: Fix build by removing newly-added assertion from upstream that doesn't make sense with assets 2022-09-20 17:38:44 +00:00
Andrew Chow
dfc3e891d7
wallet: Assert that enough was selected to cover the fees
When the fee is not subtracted from the outputs, the amount that has
been reserved for the fee (change_and_fee - change_amount) must be
enough to cover the fee that is needed. It would be a bug to not do so,
so use an assert to make this obvious if such a situation were to occur.

Github-Pull: bitcoin/bitcoin#22686
Rebased-From: d9262324e8
2022-09-20 17:38:44 +00:00
Andrew Poelstra
ba8273ac94 lint: fix non-pylint linter errors
Includes fixing all the spelling mistakes that are our fault,
but not those present upstream in Core.
2021-10-15 00:20:20 +00:00
Andrew Poelstra
b64ca7f411 Merge 6eed792d43 into merged_master (Elements PR ElementsProject/elements#1050)
Conflicts were mostly obvious, except for those in CreateTransactionInternal.
(This function was moved from wallet.cpp to spend.cpp, and substantially
rewritten, between 0.21 and 22.0.) For those I manually applied the changes
from the diff, which wound up taking a slightly different form.

Also had to update the new test because the `addresses` field of the RPC
output was removed.
2021-10-04 15:13:47 +00:00
Andrew Poelstra
92d6f321b8 Merge 388d47f9a3 into merged_master (Elements PR ElementsProject/elements#1010)
Basically just reconstructed the diff since so much code had been moved.
2021-09-18 15:46:10 +00:00
Andrew Poelstra
446f764bae Merge e5ac786d7e into merged_master (Elements PR ElementsProject/elements#1033)
This fixes a bug that was eliminated by #22008 -- although a conceptually
similar one was reintroduced (basically, we do a "test blinding" for fee
estimation, then potentially delete a change output, then we actually blind
the tranasction .... but if removing the change output pushes us into an
edge-case scenario for blinding, Bad Things happen).

Patched in a simple hack. We should fix this properly in a post-22 PR.

Unrelatedly, corrected a comment in the functional test.
2021-09-17 23:22:56 +00:00
Andrew Poelstra
b3bba59059 Merge 0553d75268 into merged_master (Bitcoin PR bitcoin/bitcoin#22154) 2021-07-29 02:50:04 +00:00
Andrew Poelstra
a5d97b363b Merge 58f8b156ed into merged_master (Bitcoin PR bitcoin/bitcoin#22008)
This isn't nearly as bad as it looks -- use `git diff -w` to see past
the indentation changes.
2021-07-23 20:42:38 +00:00
Andrew Poelstra
3d6a5a2182 Merge 55a156fca0 into merged_master (Bitcoin PR bitcoin/bitcoin#21207)
git diff --color-moved=zebra is your friend
2021-07-19 03:15:44 +00:00
Andrew Chow
171366e89b Use bilingual_str for address fetching functions
For GetNewDestination, GetNewChangeDestination, and
GetReservedDestination, use bilingual_str for
errors
2021-07-01 12:57:51 -04:00
Andrew Chow
754f134a50 wallet: Add error message to GetReservedDestination
Adds an error output parameter to all GetReservedDestination functions
so that callers can get the actual reason that a change address could
not be fetched. This more closely matches GetNewDestination. This allows
for more granular error messages, such as one that indicates that
bech32m addresses cannot be generated yet.
2021-06-22 21:57:04 -04:00
Andrew Chow
96c2c9520e scripted-diff: Rename SelectCoinsMinConf to AttemptSelection
SelectCoinsMinConf is a bit of a misnomer now since it really just does
all of the coin selection given some parameters. So rename this to
something less annoying to say and makes a bit more sense.

-BEGIN VERIFY SCRIPT-
sed -i 's/SelectCoinsMinConf/AttemptSelection/g' $(git grep -l SelectCoinsMinConf ./src)
-END VERIFY SCRIPT-
2021-05-30 14:10:10 -04:00
Andrew Chow
b583f73354 Move vin filling to before final fee setting
It's unnecessary to fill in the vin with dummy inputs, calculate the
fee, then fill in the vin with the actual inputs. Just fill the vin with
the actual inputs the first time.
2021-05-30 14:07:49 -04:00
Andrew Chow
d39cac0547 Set m_subtract_fee_outputs during recipients vector loop
Instead of setting this afterwards based on the results from the loop,
just do it inside of the loop itself.

Fixed some styling nearby
2021-05-30 14:06:40 -04:00
Andrew Chow
364e0698a5 Move variable initializations to where they are used
- txNew nLockTime setting to txNew init
- FeeCalc to the fee estimation fetching
- setCoins to prior to SelectCoins
- nBytes to CalculateMaximumSignedTxSize call
- tx_sizes to CalculateMaximumSignedTxSize call
- coin_selection_params.m_avoid_partial_spends to params init
2021-05-30 14:06:13 -04:00
Andrew Chow
32ab430651 Move recipients vector checks to beginning of CreateTransaction
Ensuring that the recipients vector is not empty and that the amounts
are non-negative can be done in CreateTransaction rather than
CreateTransactionInternal. Additionally, these checks should happen as
soon as possible, so they are done at the beginning of
CreateTransaction.
2021-05-30 14:05:42 -04:00
Andrew Chow
cd1d6d3324 Rename nSubtractFeeFromAmount in CreateTransaction
Renamed to outputs_to_subtract_fee_from for clarity.
2021-05-30 14:05:15 -04:00
Andrew Chow
dac21c793f Rename nValue and nValueToSelect
nValue is the sum of the intended recipient amounts, so name it that for
clarity.

nValueToSelect is the coin selection target value, so name it
selection_target for clarity.
2021-05-30 14:03:43 -04:00
Andrew Chow
d2aee3bbc7 Remove extraneous scope in CreateTransactionInternal
These brackets were restricting a scope for no apparent reason. Remove
them and dedent.
2021-05-30 14:01:29 -04:00
Andrew Chow
b2995963b5 Move cs_wallet lock in CreateTransactionInternal to top of function
It isn't necessary to not lock parts of this function. Just lock the
whole thing and get rid of an indent.
2021-05-30 13:59:32 -04:00
Russell Yanofsky
c7bd5842e4 MOVEONLY: CWallet transaction code out of wallet.cpp/.h
This commit just moves functions without making any changes. It can be
reviewed with `git log -p -n1 --color-moved=dimmed_zebra`

Motivation for this change is to make wallet.cpp/h less monolithic and
start to make wallet transaction state tracking comprehensible so bugs
in
https://github.com/bitcoin-core/bitcoin-devwiki/wiki/Wallet-Transaction-Conflict-Tracking
can be fixed safely without introducing new problems.

This commit moves wallet classes and methods that deal with transactions
out of wallet.cpp/.h into better organized files:

- transaction.cpp/.h - CWalletTx and CMerkleTx class definitions
- receive.cpp/.h - functions checking received transactions and computing balances
- spend.cpp/.h - functions creating transactions and finding spendable coins

After #20773, when loading is separated from syncing it will also be
possible to move more wallet.cpp/.h functions to:

- sync.cpp/.h - functions handling chain notifications and rescanning

This commit arranges receive.cpp and spend.cpp functions in dependency
order so it's possible to skim receive.cpp and get an idea of how
computing balances works, and skim spend.cpp and get an idea of how
transactions are created, without having to jump all over wallet.cpp
where functions are not in order and there is a lot of unrelated code.

Followup commit "refactor: Detach wallet transaction methods" in
https://github.com/bitcoin/bitcoin/pull/21206 follows up this PR and
tweaks function names and arguments to reflect new locations. The two
commits are split into separate PRs because this commit is more work to
maintain and less work to review, while the other commit is less work to
maintain and more work to review, so hopefully this commit can be merged
earlier.
2021-05-26 06:32:51 -05:00