Commit graph

1515 commits

Author SHA1 Message Date
Andrew Poelstra
b3bba59059 Merge 0553d75268 into merged_master (Bitcoin PR bitcoin/bitcoin#22154) 2021-07-29 02:50:04 +00:00
Andrew Poelstra
0afcb6d978 Merge 5c2e2afe99 into merged_master (Bitcoin PR bitcoin/bitcoin#21365)
This introduces Taproot wallet support. I fixed all the merge conflicts
and ensured that the tests pass, but this is still using the old sighash
(before Russell/Sanket/I redid it) so is not actually production ready.
Will be fixed when we bring Elements #1002 in.
2021-08-03 20:43:53 +00:00
Andrew Poelstra
1a0a945459 Merge 7c561bea52 into merged_master (Bitcoin PR bitcoin/bitcoin#21935) 2021-07-25 23:50:09 +00:00
Andrew Poelstra
18986689be Merge 907d636e5e into merged_master (Bitcoin PR bitcoin/bitcoin#21353) 2021-07-21 20:30:59 +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 Poelstra
013eaeaca2 Merge 7076bba841 into merged_master (Bitcoin PR bitcoin-core/gui#346) 2021-07-18 09:43:00 +00:00
Andrew Poelstra
5f8081db1a Merge ecddd12482 into merged_master (Bitcoin PR bitcoin/bitcoin#18418) 2021-07-18 03:10:21 +00:00
Andrew Poelstra
81eb03b40c Merge 7aa41fc581 into merged_master (Bitcoin PR bitcoin/bitcoin#22042) 2021-07-17 19:14:17 +00:00
Andrew Poelstra
8b34c974c3 Merge 6b254814c0 into merged_master (Bitcoin PR bitcoin/bitcoin#17331)
This removes a lot of the craziness that was added during the 0.21
rebase 240f03f586 (Bitcoin PR #17290)
as well as a lot of other upstream craziness. It's a very positive
change but will probably be a bear to review.

There are two places where I (purposely) nontrivially changed the
logic beyond what the upstream PR did:

    1. When setting the change output positions, I used a uniform
       distribution for all change outputs and also obeyed the user's
       `change_position` choice. The old code was non-uniform and
       had a bug where it would offset the change position.

       For non-policy assets, I do not create zero-sized change
       since we would just remove them later. For the policy asset,
       I do sometimes create zero-sized change since the upstream
       logic expects it to exist.

    2. Rather than "reblinding whenever something changes" we blind
       once for size/fee estimation purposes and then again at the
       end after all potential adjustments have been made. The
       resulting code should be closer to upstream.

       We should really redo this code though because our use of the
       `BlindDetails` structure is very confusing and stateful.

    3. We consider whether or not we're using CT/CA when estimating
       the size of change outpust. This is because we now use branch
       and bound far more often (yay!) which selects coins such that
       there will be no change output. This is implemented however
       by adding a change output then dumping it to fees ... meaning
       that if we dramatically overestimate the size of a change out
       then we'll end up dramatically dumping too many coins to fees.

There are another couple small things, which I apologize for .. this
PR took me 2 hours to get compiling and 11 hours to get working(!!)
and some things got away from me.

One fun thing is that I changed CWallet::SelectCoinsMinConf to gate
an addition on coin_selection_params.m_subtract_fee_outputs ... this
is actually an upstream bug that I'll file whenever I get around to
producing a test that triggers it. (A bit hard as I have to gin up
a scenario where branch-and-bound fails to hit this codepath.)

Also, in test/functional/wallet_bumpfee.py I had to change the feerate
required to force selection to add another input from 500 to 800. I
don't know why and I don't care to figure it out.
2021-07-17 02:42:16 +00:00
Andrew Poelstra
e552043a9a Merge d4c409cf09 into merged_master (Bitcoin PR bitcoin/bitcoin#20773) 2021-07-11 07:37:55 +00:00
Andrew Poelstra
9096687c0e Merge 386ba92e83 into merged_master (Bitcoin PR bitcoin/bitcoin#21910) 2021-07-10 02:10:19 +00:00
Andrew Poelstra
d56bdbd28f Merge 32692d2681 into merged_master (Bitcoin PR bitcoin/bitcoin#21359)
I hacked up rpc_fundrawtransaction.py a little bit because our `get_address`
method here depends on nobody having called `createwallet` on a particular
node ... the "correct" fix for this would be to redo the Elements changes
to this functional test for the 0.20+ createwallet changes, but because
there will be big future changes to this test (in Elements #900 (PSET))
I did the quick/hacky thing, and will defer cleanups to a separate
post-rebase PR.
2021-07-08 16:08:49 +00:00
Andrew Poelstra
400268064d Merge f8176b768a into merged_master (Bitcoin PR bitcoin/bitcoin#21836) 2021-07-08 08:34:10 +00:00
Andrew Poelstra
3850e85010 Merge 32f1f021bf into merged_master (Bitcoin PR bitcoin/bitcoin#21817) 2021-07-07 02:29:25 +00:00
Andrew Poelstra
a8362769f4 Merge d9ae6ec892 into merged_master (Bitcoin PR bitcoin/bitcoin#21759) 2021-07-03 20:38:21 +00:00
Andrew Poelstra
95e11d5a9d Merge e7af2f35af into merged_master (Bitcoin PR #21666) 2021-06-30 12:53:47 +00:00
Andrew Poelstra
1c58e32ee6 Merge 4132193617 into merged_master (Bitcoin PR #21040) 2021-06-27 21:04:51 +00:00
Andrew Poelstra
26fd4eb181 Merge a9d1b40d53 into merged_master (Bitcoin PR #21415) 2021-06-27 15:02:35 +00:00
Andrew Poelstra
b1fab9a7e6 Merge d25e28c20b into merged_master (Bitcoin PR #21083) 2021-06-27 14:26:06 +00:00
Andrew Poelstra
d16103e6c4 Merge b650c9140e into merged_master (Bitcoin PR #21141) 2021-06-27 01:12:01 +00:00
Andrew Poelstra
8c54b98b25 Merge e0bc27a14c into merged_master (Bitcoin PR #21404) 2021-06-26 22:39:09 +00:00
Andrew Poelstra
14685bfef5 Merge 6c156e49cb into merged_master (Bitcoin PR #18842) 2021-06-26 14:38:38 +00:00
Andrew Poelstra
24a86af27b Merge a8b0892b74 into merged_master (Bitcoin PR #20536)
This PR adds a new functional test which unfortunately we need to disable
because it triggers an unrelated Elements bug (assertation failure when
attempting a large fundrawtransaction).

See https://github.com/ElementsProject/elements/issues/880
2021-06-26 14:25:24 +00:00
Andrew Poelstra
578ee6183f Merge a9335e4f12 into merged_master (Bitcoin PR #16546)
There are a few layers of bullshit to this PR.

First, there is the fact that it adds a functional test gated on a new
config flag which is disabled by default, so it actually adds broken
code with no tests, waiting to ruin your day 520 PRs later when #21935
enables the broken test.

Second, the test appears to be superficially nonsensical because it
generates two transactions from different wallets and tries to compare
them for byte-for-byte equality, which doesn't make sense (at least)
because change outputs are randomly located...so something fishy is
going on.

Of course, in Elements the transactions are *not* equal half the time
because the outputs are permuted, which may have let me quickly figure
out the issue, except...

Third, there is a red herring of a bug where the two transactions have
slightly different feerates. This turns out to be caused by
CWallet::CalculateMaximumSignedTxSize using differently sized dummy
transactions depending on whether watchonly outputs are included (this
fact is conveniently disguised by #17211 slightly changing this logic;
this is an unmerged PR in Core that Elements has a backport of an old
version of). And the two wallets have different watchonly settings.

A sub-red-herring is the fact that this bug results in a discrepancy
of 0.25 vbytes, so it does not appear in Core but does appear in
Elements (there is a 3/16 probability that we should be so unlucky...
we are).

But this is all irrelevant, because...

Fourth, this test is actually super bullshit. The way it works is by
constructing a PSBT legitimately, saving this to disk, then re-"signs"
using the external signer interface by using a mock signer that
COMPLETELY REPLACES THE TRANSACTION UNDER CONSTRUCTION. So it doesn't
matter what the fee output looks like and it doesn't matter what the
order of the outputs. Core does not detect this malfeasance and
neither does Elements. For some reason, Core has a functional test
that explicitly checks that you can do this even though it is insane
and it is hard to think of non-malicious reasons to do it.

Fifth, while Elements fails to detect that its external signer is
actually changing the transaction out from under it, it DOES assume
that this won't happen. In CWallet::SignPSBT it blithely un-replaces
the transaction, which undermines the functional test.

Sixth, the original PR where this test was introduced has comments
locked, so anyone who spent six hours reverse-engineering this idiotic
broken test, and is still feeling charitable enough to discuss it with
the Core developors, can go pound sand.

Anyway, just disabled the broken test and move on with our lives.
2021-07-27 00:19:01 +00: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
699dfcd8ad Opportunistically use bech32m change addresses if available
If a transaction as a segwit output, use a bech32m change address if
they are available. If not, fallback to bech32. If bech32 change
addresses are unavailable, fallback to the default address type.
2021-06-22 21:53:11 -04:00
Andrew Chow
0262536c34 Add OutputType::BECH32M
Bech32m addresses need their own OutputType

We are not ready to create DescriptorScriptPubKeyMans which produce
bech32m addresses. So don't allow generating them.
2021-06-22 21:53:11 -04:00
Andrew Chow
177c15d2f7 Limit LegacyScriptPubKeyMan address types
Make sure that LegacyScriptPubKeyMan can only be used for legacy,
p2sh-segwit, and bech32 address types.
2021-06-22 21:53:11 -04:00
Andrew Poelstra
a0fc7ebcf2 Merge 7dc4807691 into merged_master (Bitcoin PR #20040)
This is a really non-trivial wallet refactor "effective value" which has been
in the Core queue for a pretty long time. There were a ton of merge conflicts
but they were mostly mechanical (all the benchmarks) or "take the Core side
of the diff" (most of wallet.cpp).

The two nontrivial things were:
  * In `SelectCoinsMinConf` in wallet.cpp I had to slightly move the asset
    filtering logic (but I didn't change it)
  * In `OutputGroup::Insert' in coinselection.cpp I changed the effective
    value computation to only consider policyAsset values
2021-06-20 13:56:56 +00:00
Andrew Poelstra
76075ee96a Merge 45952dab9d into merged_master (Bitcoin PR #20932) 2021-06-18 15:00:45 +00:00
Samuel Dobson
5c2e2afe99
Merge bitcoin/bitcoin#21365: Basic Taproot signing support for descriptor wallets
458a345b05 Add support for SIGHASH_DEFAULT in RPCs, and make it default (Pieter Wuille)
c0f0c8eccb tests: check spending of P2TR (Pieter Wuille)
a2380127e9 Basic Taproot signing logic in script/sign.cpp (Pieter Wuille)
49487bc3b6 Make GetInputUTXO safer: verify non-witness UTXO match (Pieter Wuille)
fd3f6890f3 Construct and use PrecomputedTransactionData in PSBT signing (Pieter Wuille)
5cb6502ac5 Construct and use PrecomputedTransactionData in SignTransaction (Pieter Wuille)
5d2e22437b Don't nuke witness data when signing fails (Pieter Wuille)
ce9353164b Permit full precomputation in PrecomputedTransactionData (Pieter Wuille)
e841fb503d Add precomputed txdata support to MutableTransactionSignatureCreator (Pieter Wuille)
a91d532338 Add CKey::SignSchnorr function for BIP 340/341 signing (Pieter Wuille)
e77a2839b5 Use HandleMissingData also in CheckSchnorrSignature (Pieter Wuille)
dbb0ce9fbf Add TaprootSpendData data structure, equivalent to script map for P2[W]SH (Pieter Wuille)

Pull request description:

  Builds on top of #22051, adding signing support after derivation support.

  Nothing is changed in descriptor features. Signing works for key path and script path spending, through the normal sending functions, and PSBT-based RPCs. However, PSBT usability is rather low as no extensions have been defined to convey Taproot-specific information, so all script information must be known to the signing wallet.

ACKs for top commit:
  achow101:
    re-ACK 458a345b05
  fjahr:
    Code review ACK 458a345b05
  Sjors:
    ACK 458a345b05

Tree-SHA512: 30ed212cf7754763a4a81624ebc084c51727b8322711ac0b390369213c1a891d367ed8b123882ac08c99595320c11ec57ee42304ff22a69afdc3d1a0d55cc711
2021-06-18 09:12:44 +12:00
Andrew Poelstra
acf709b3ab Merge bd6af53e1f into merged_master (Bitcoin PR #20480)
what a trainwreck of a programming language..
2021-06-17 15:15:29 +00:00
Andrew Poelstra
e5cb4cb00e Merge f13e03cda2 into merged_master (Bitcoin PR #20584) 2021-06-16 20:58:56 +00:00
Sjors Provoost
4455145e26
refactor: reduce #ifdef ENABLE_EXTERNAL_SIGNER usage
In particular this make the node interface independent on whether external signer support is compiled.
2021-06-16 10:48:58 +02:00
Sjors Provoost
7d9453041b
refactor: clean up external_signer.h includes
Co-Authored-By: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
2021-06-16 10:48:38 +02:00
Andrew Poelstra
0a58119253 Merge 68c7acf6bb into merged_master (Bitcoin PR #20671) 2021-06-15 16:40:45 +00:00
Andrew Poelstra
0d66f6cf42 Merge af4ce674da into merged_master (Bitcoin PR #20635) 2021-06-14 23:58:34 +00:00
Andrew Poelstra
939d8ee135 Merge ade38b6ee8 into merged_master (Bitcoin PR #20588)
o.O apparently the `tx_aux` argument to `createrawpegin` was literally unused
2021-06-14 02:19:09 +00:00
Andrew Poelstra
ee43c19115 Merge 736eb4d808 into merged_master (Bitcoin PR #19982) 2021-06-14 00:27:44 +00:00
Pieter Wuille
458a345b05 Add support for SIGHASH_DEFAULT in RPCs, and make it default
For non-Taproot signatures, this is interpreted as SIGHASH_ALL.
2021-06-12 12:38:17 -07:00
Pieter Wuille
fd3f6890f3 Construct and use PrecomputedTransactionData in PSBT signing 2021-06-12 12:25:28 -07:00
Andrew Poelstra
a3b6f760ed Merge e98d1d6740 into merged_master (Bitcoin PR #19425) 2021-06-11 19:06:47 +00:00
Andrew Poelstra
2ec2763700 Merge 80d4231e16 into merged_master (Bitcoin PR #19980) 2021-06-10 21:23:06 +00:00
W. J. van der Laan
907d636e5e
Merge bitcoin/bitcoin#21353: interfaces: Stop exposing wallet destdata to gui
f5ba424cd4 wallet: Add IsAddressUsed / SetAddressUsed methods (Russell Yanofsky)
62252c95e5 interfaces: Stop exposing wallet destdata to gui (Russell Yanofsky)
985430d9b2 test: Add gui test for wallet receive requests (Russell Yanofsky)

Pull request description:

  Stop giving GUI access to destdata rows in database. Replace with narrow API just for saving and reading receive request information.

  This simplifies code and should prevent the GUI from interfering with other destdata like address-used status. It also adds some more GUI test coverage.

  There are no changes in behavior.

ACKs for top commit:
  jarolrod:
    tACK f5ba424cd4
  laanwj:
    Code review ACK f5ba424cd4

Tree-SHA512: 5423df4786e537a59013cb5bfb9e1bc29a7ca4b8835360c00cc2165a59f925fdc355907a4ceb8bca0285bb4946ba235bffa7645537a951ad03fd3b4cee17b6b0
2021-06-03 15:57:30 +02:00
Samuel Dobson
55a156fca0
Merge bitcoin/bitcoin#21207: MOVEONLY: CWallet transaction code out of wallet.cpp/.h
c7bd5842e4 MOVEONLY: CWallet transaction code out of wallet.cpp/.h (Russell Yanofsky)

Pull request description:

  This commit just moves function 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 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.

ACKs for top commit:
  Sjors:
    re-utACK c7bd5842e4
  fjahr:
    utACK c7bd5842e4
  promag:
    Code review ACK c7bd5842e4, verified move only claim.
  meshcollider:
    Dimmed-zebra-check and functional test run ACK c7bd5842e4

Tree-SHA512: 4981de6911cb1196774db375494355cc9af59b52456129c002d264a77cd9ed6175f8ecbb6b2f492a59a4d5a0def21a39d96fa79c9f4d99be0992985f553be32f
2021-05-30 22:00:40 +12:00
Hennadii Stepanov
bfb53ddda9
scripted-diff: Fix ellipsis after pr20773
-BEGIN VERIFY SCRIPT-
sed -i 's|_("Loading wallet...")|_("Loading wallet…")|' src/wallet/*.cpp
-END VERIFY SCRIPT-
2021-05-27 13:46:36 +03:00
fanquake
ecddd12482
Merge bitcoin/bitcoin#18418: wallet: Increase OUTPUT_GROUP_MAX_ENTRIES to 100
e6fe1c37d0 rpc: Improve avoidpartialspends and avoid_reuse documentation (Fabian Jahr)
8f073076b1 wallet: Increase OUTPUT_GROUP_MAX_ENTRIES to 100 (Fabian Jahr)

Pull request description:

  Follow-up to #17824.

  This increases OUTPUT_GROUP_MAX_ENTRIES to 100 which means that OutputGroups will now be up to 100 outputs large, up from previously 10. The main motivation for this change is that during the PR review club on #17824 [several participants signaled](https://bitcoincore.reviews/17824.html#l-339) that 100 might be a better value here.

  I think fees should be manageable for users but more importantly, users should know what they can expect when using the wallet with this configuration, so I also tried to clarify the documentation on `-avoidpartialspends` and `avoid_reuse` a bit. If there are other additional ways how or docs where users can be made aware of the potential consequences of using these parameters, please let me know. Another small upside is that [there seem to be a high number of batching transactions with 100 and 200 inputs](https://miro.medium.com/max/3628/1*sZ5eaBSbsJsHx-J9iztq2g.png)([source](https://medium.com/@hasufly/an-analysis-of-batching-in-bitcoin-9bdf81a394e0)) giving these transactions a bit of a larger anonymity set, although that is probably a very weak argument.

ACKs for top commit:
  jnewbery:
    ACK e6fe1c37d0
  Xekyo:
    retACK e6fe1c37d0
  rajarshimaitra:
    tACK `e6fe1c3`
  achow101:
    ACK e6fe1c37d0
  glozow:
    code review ACK https://github.com/bitcoin/bitcoin/pull/18418/commits/e6fe1c37d0a2f8037996dd80619d6c23ec028729

Tree-SHA512: 79685c58bafa64ed8303b0ecd616fce50fc9a2b758aa79833e4ad9f15760e09ab60c007bc16ab4cbc4222e644cfd154f1fa494b0f3a5d86faede7af33a6f2826
2021-05-26 19:32:51 +08: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
Gregory Sanders
881a3e2e17 Replace size/weight estimate tuple with struct for named fields 2021-05-26 07:33:09 +08:00
Samuel Dobson
6b254814c0
Merge bitcoin/bitcoin#17331: Use effective values throughout coin selection
51a3ac242c Have OutputGroup determine the value to use (Andrew Chow)
6d6d278475 Change SelectCoins_test to actually test SelectCoins (Andrew Chow)
9d3bd74ab4 Remove CreateTransaction while loop and some related variables (Andrew Chow)
6f0d5189af Remove use_bnb and bnb_used (Andrew Chow)
de26eb0e1f Do both BnB and Knapsack coin selection in SelectCoinsMinConf (Andrew Chow)
01dc8ebda5 Have KnapsackSolver actually use effective values (Andrew Chow)
bf26e018de Roll static tx fees into nValueToSelect instead of having it be separate (Andrew Chow)
cc3f14b27c Move output reductions for fee to after coin selection (Andrew Chow)
d97d25d950 Make cost_of_change part of CoinSelectionParams (Andrew Chow)
af5867c896 Move some calculations to common code in SelectCoinsMinConf (Andrew Chow)
1bf4a62cb6 scripted-diff: rename some variables (Andrew Chow)

Pull request description:

  Changes `KnapsackSolver` to use effective values instead of just the nominal txout value. Since fees are taken into account during the selection itself, we finally get rid of the `CreateTransaction` loop as well as a few other things that only were only necessary because of that loop.

  This should not change coin selection behavior at all (except maybe remove weird edge cases that were caused by the loop). In order to keep behavior the same, `KnapsackSolver` will select outputs with a negative effective value (as it did before).

ACKs for top commit:
  ryanofsky:
    Code review ACK 51a3ac242c. Looks good to go!
  instagibbs:
    review ACK https://github.com/bitcoin/bitcoin/pull/17331/commits/51a3ac242c92e69b59df26f8f9e287b31e5c3b0f
  meshcollider:
    re-light-utACK 51a3ac242c

Tree-SHA512: 372c27e00edcd5dbf85177421ba88f20bfdaf1791b6e3dc022c44876ecc379403e2375ed69e71c512c49e6af87641001ff385c4b25ab93684b3a08a53bf3824e
2021-05-26 01:35:43 +12:00