Too early NotifyWalletLoaded() call in CWallet::Create() results the
notification goes before DescriptorScriptPubKeyMans were created and
added to an encrypted wallet.
Co-authored-by: Andrew Chow <achow101-github@achow101.com>
Github-Pull: bitcoin/bitcoin#24711
Rebased-From: 0c12f0116c
The external input test with specifying input weight would make a
pessimistic estimate of the input weight. However this would result in a
test failure as it is sometimes too pessimistic when an ECDSA signature
ends up being smaller than usual. To correct this, we can calculate the
input weight more accurately.
Github-Pull: #24454
Rebased-From: 8a04a386f7
If the user has unchecked "Allow incoming connections" in
`Settings->Options...->Network` then `fListen=false` is saved in
`~/.config/Bitcoin/Bitcoin-Qt.conf`. This flips `-listen` to `false`
during startup, but leaves `-listenonion` to `true`.
This flipping of `-listen` is done in `OptionsModel::Init()` after
`InitParameterInteraction()` has been executed which would have flipped
`-listenonion`, should it have seen `-listen` being `false`
(this is a difference between `bitcoind` and `bitcoin-qt`).
Fixes: https://github.com/bitcoin-core/gui/issues/567
Github-Pull: bitcoin-core/gui#568
Rebased-From: 7f90dc26c8
PSBT signing was changed to use SIGHASH_DEFAULT by default in #22514.
The signet miner script sets the sighash type of the created PSBT to
SIGHASH_ALL, hence this leads to a sighash mismatch when the
`walletprocesspsbt` RPC is called. Fix this by explicitly passing the
correct sighash type.
Note that the same change was needed in one of our functional tests,
see commit d3992669df.
Reported by gruve-p.
Github-Pull: bitcoin#24553
Rebased-From: 12cc020
This was changed in #22818 from 0 to 1. Since it changes
BLOCK_OPT_WIT of the genesis block, older versions of bitcoin
core would not read regtest directories created with newer versions
without a reindex.
Github-Pull: bitcoin#24527
Rebased-From: 5ce3057
Just add tests. No changes to application behavior. Tests will be
updated in the next commit changing & improving current behavior.
Include a Qt test for GUI startup crash reported by Rspigler in
https://github.com/bitcoin/bitcoin/issues/24457 caused by GetArg
behavior that happens if settings.json contains an integer value for any
of the configuration options which GUI settings can currently clash with
(-dbcache, -par, -spendzeroconfchange, -signer, -upnp, -natpmp, -listen,
-server, -proxy, -proxy, -onion, -onion, -lang, and -prune).
Github-Pull: bitcoin/bitcoin#24498
Rebased-From: 84b0973e35
There is a crashing bug in psbt.h which works as follows. This occurs in
the psbt_deserialize_input fuzz test, which deserializes an input and
then tries to reserialize it. Here a PSET input may contain a mainchain
transaction, which is where our trouble is.
The process is as follows:
1. On line 901, we create a CTransactionRef, which is a newtype around
std::shared_ptr<CTransaction> which defaults to being null.
2. On line 903 we then call `UnserializeFromVector` to populate this,
where this is a helper function which attempts to read some number of
objects from a byte vector, i.e. a length-prefixed blob.
3. HOWEVER, `UnserializeFromVector` when given an empty vector, decides
that it has successfully deserialized zero elements, and returns.
4. Then, on line 904 we assign the CTransactionRef, which is a valid
std::shared_ptr whose internal pointer is NULL, to `m_peg_in_tx`,
which is a variant of monostate, Bitcoin::CTransactionRef, and
CTransactionRef. Its variant changes from the default monostate
to CTransactionRef.
5. Then, on line 419, we call `std::get_if<CTransactionRef>` on this
object, which returns a std::optional<CTransactionRef>. Because
`m_peg_in_tx` is in the `CTransactionRef` variant, this succeeds,
returning a true std::optional containing a valid std::shared_ptr
which contains a NULL pointer.
6. Then, on line 420, we call `if (peg_in_tx)`, which is true, because
we have a true std::optional. We then dereference it on line 423,
which is perfectly legal, to get our std::shared_ptr, and pass this
shared pointer to SerializeToVector.
7. SerializeToVector passes through like 6 layers of serialize.h
obfuscation and eventually dereferences the shared pointer, but
because it's NULL, this is a NULL pointer dereference, and we get a
crash.
There are two lessons here:
1. Don't use C++. As I say in acf709b3ab,
where I introduced some of the offending code here (but only by
replacing boost stuff with their STL equivalents; the bug existed
before I did this), "what a trainwreck of a language".
2. Don't use `UnserializeFromVector` and expect it to throw if the data
you're deserializing is malformed. If it's malformed in the sense of
being empty, it will "succeed" and silently do nothing.
I glanced at every other instance of UnserializeFromVector to check what
will happen when it's passed an empty string. I believe there are no
other cases where it will fail to initialize a NULL pointer, so I
believe that this will not cause other crashes. But I also believe that
the behavior in this case is almost always wrong and that we parse
malformed PSETs in crazy and incorrect ways all over the place.
If anybody has a problem with this, I encourage you to go review the
Bitcoin PSBT2 PRs, which this stuff is based on, which have been
languishing in rebase hell for the better part of a decade. Don't blame
the author for not writing perfect code in a hostile language with no
support.
After this PR I ran the fuzzer for 16 hours on a 192-thread machine (so
3072 CPU-hours) and didn't see any more crashes.
ubsan doesn't like assigning arbitrary uint8_t values to bool. It's easy
to avoid doing, so do it. (We do this specifically in PSET since that's
Elements-specific code, but the same issue is present in Bitcoin in the
Unserialize impl for bool in serialize.h. Upstream this is only used in
the wallet database, where it may be that non 0/1 values are impossible
(absent a corrupt wallet).