Commit Graph

464 Commits

Author SHA1 Message Date
Tobin C. Harding 2d23e11569
Remove extern crate hashbrown
We no longer have a "hashbrown" feature, the feature gated `pub extern
crate hashbrown` should have been removed when we removed the feature.
2023-03-21 15:14:29 +11:00
Andrew Poelstra 2f404f9b5c
Merge rust-bitcoin/rust-bitcoin#1714: update rust-secp to 0.27.0
bef7992ce5 Update readme to mention pin for 1.47 (Tobin C. Harding)
58033cf14e pin serde dep on 1.47 (Tobin C. Harding)
f5f4a33fa9 pin serde dep on 1.41 (Andrew Poelstra)
ee9b297e98 ci: update dupe check to whitelist syn (Andrew Poelstra)
6aa640ff8d update rust-secp to 0.27.0 (Andrew Poelstra)

Pull request description:

  Also remove the spurious dev-dependency copy of rust-secp, which should've been updated to remove the "recovery" feature in https://www.github.com/rust-bitcoin/rust-bitcoin/pull/545 and then been removed entirely in https://www.github.com/rust-bitcoin/rust-bitcoin/pull/1387

ACKs for top commit:
  Kixunil:
    ACK bef7992ce5
  tcharding:
    ACK bef7992ce5

Tree-SHA512: 7d1bf062dc6920bcafa85311b4b5ed348e31fb20aa21156e545bf7a4cc4c194e2b6dcfd0d3c6db3df337e4e2cd0f7b74f41ea421549521f07080feb88fbd9382
2023-03-20 15:11:12 +00:00
Andrew Poelstra e7521fa225
Merge rust-bitcoin/rust-bitcoin#1710: Support weight prediction in `const` context
00b46d6d9d Indent functions (Martin Habovstiak)
d56d202aeb Support weight prediction in `const` context (Martin Habovstiak)

Pull request description:

  **Notes for reviewers:**
  This is something that I want to use in my code and hopefully reasonably easy to review, so if this can get into 0.30 that'd be really nice. No hard feelings if it doesn't.
  I tried to put extra effort into making review easier by:
  * intentionally "mis-formatting" the first commit so diff is smaller and easy to understand - see individual commits.
  * copying patterns from non-const fn to const fn so it's obviously correct (includes same variable names)
  * not bothering with the array trick in `VarInt::len` and simply accepting the limitation of Rust 1.46+ (I use 1.48 BTW).

  **Description**

  Some smart contracts or simplified wallets statically know the sizes of
  transactions or inputs. The possible approaches to handling them so far
  were re-computing the values (and hoping the optimizer will const fold
  them) or using a simple constant which may be harder to understand and
  get right. It's much nicer to just use a `const` but our code didn't
  support it until now.

  This change adds methods that can compute the prediction in `const`
  context for Rust versions >= 1.46.0 which allow use of loops (and
  conditions but those could be workaround anyway).

  As a side effect of this, the change also adds `const` to `VarInt::len`
  in Rust 1.46+. While this one could be made unconditional using array
  trick it's probably not worth it because of the planned MSRV bump.

ACKs for top commit:
  apoelstra:
    ACK 00b46d6d9d
  tcharding:
    ACK 00b46d6d9d

Tree-SHA512: 5509886a68b4de5227db0e28d92a40be8de64592e0b189c519213db21bcfe98ca03d9a1936b1024729b97db69e8ec0b55fac870a7ce9bab0d0c9a47b2087990f
2023-03-19 13:22:34 +00:00
Tobin C. Harding 58033cf14e
pin serde dep on 1.47 2023-03-19 12:15:56 +11:00
Andrew Poelstra f5f4a33fa9
pin serde dep on 1.41 2023-03-18 22:10:18 +00:00
Andrew Poelstra ee9b297e98
ci: update dupe check to whitelist syn 2023-03-18 22:08:45 +00:00
Andrew Poelstra 6aa640ff8d
update rust-secp to 0.27.0
Also remove the spurious dev-dependency copy of rust-secp, which
should've been updated to remove the "recovery" feature in
https://www.github.com/rust-bitcoin/rust-bitcoin/pull/545 and
then been removed entirely in https://www.github.com/rust-bitcoin/rust-bitcoin/pull/1387
2023-03-18 22:01:42 +00:00
junderw 4924148dc6
Swap out `Work::log2` implementation for `U256::to_f64` 2023-03-17 14:10:00 -07:00
Martin Habovstiak 00b46d6d9d Indent functions
This fixes indentatiion that was intentionally "messed up" to make code
review easier.
2023-03-17 08:16:21 +01:00
Martin Habovstiak d56d202aeb Support weight prediction in `const` context
Some smart contracts or simplified wallets statically know the sizes of
transactions or inputs. The possible approaches to handling them so far
were re-computing the values (and hoping the optimizer will const fold
them) or using a simple constant which may be harder to understand and
get right. It's much nicer to just use a `const` but our code didn't
support it until now.

This change adds methods that can compute the prediction in `const`
context for Rust versions >= 1.46.0 which allow use of loops (and
conditions but those could be workaround anyway).

As a side effect of this, the change also adds `const` to `VarInt::len`
in Rust 1.46+. While this one could be made unconditional using array
trick it's probably not worth it because of the planned MSRV bump.

Note: this commit is intentionally unformatted to make diff easier to
understand. Formatting will be done in future commit.
2023-03-17 08:16:17 +01:00
Salvatore Ingala 2961c0c589
Exclude usage of atomic types if not supported for the target
The gate is only added for Rust >= v1.60, since earlier versions don't support #[cfg(target_has_atomic = ...)]
2023-03-16 22:42:15 +01:00
Martin Habovstiak a6188a90c0 Improve QR code formatting documentation
It wasn't obvious that displaying address with alternate formatting
upper cases bech32 addresses.

This change adds information about this and also a note about the
compatibility of various wallets.
2023-03-15 06:45:58 +01:00
Andrew Poelstra edcb6fb81f
Merge rust-bitcoin/rust-bitcoin#1700: update internals CHANGELOG for release
51f2f8483c rename bitcoin-internals to bitcoin-private (Andrew Poelstra)
ca3b4330e8 specify `internals` version in other Cargo.toml files (Andrew Poelstra)
be02045561 update internals CHANGELOG for release (Andrew Poelstra)

Pull request description:

  .

ACKs for top commit:
  Kixunil:
    ACK 51f2f8483c
  tcharding:
    ACK 51f2f8483c

Tree-SHA512: 6eca1dded06da2567f4f7b032b800f8dbd5f6ea768693eb70c7853a06ae7e19be109fbeaf2af45a196180597f7e122b85e8f0abaa702ec60e1b72868c5a74db9
2023-03-14 19:12:05 +00:00
Andrew Poelstra 37b02199e6
Merge rust-bitcoin/rust-bitcoin#1707: Add a method to `pow::Target` for returning difficulty as an f64.
2158f88f1d Add a method to `pow::Target` for returning difficulty as an f64. (junderw)

Pull request description:

  Closes #1703

  This adds a conversion function to U256 to get an f64. We use the method shown in the following blog post.

  https://blog.m-ou.se/floats/

  Target::MAX was converted to a f64 and set as a const that is verified in a unit test.

  The code is rather confusing, so I took a crack at explaining it in my comments as well. Please let me know if you want it cleaned up some more.

ACKs for top commit:
  apoelstra:
    ACK 2158f88f1d
  tcharding:
    ACK 2158f88f1d

Tree-SHA512: 7c0e82bd1756950c1c6dfb9da91fd71b276e2e7dc8a33e69112f87b87e358240f0f7c4894d24ab228e149d862938833a2e65e345ce2712a78dc86dec197da34f
2023-03-14 18:25:38 +00:00
Andrew Poelstra 51f2f8483c
rename bitcoin-internals to bitcoin-private 2023-03-13 16:02:12 +00:00
Steven Roose 9dd4c54a74
Fix CI builds where default features are added accidentally 2023-03-12 20:24:55 +00:00
junderw 2158f88f1d
Add a method to `pow::Target` for returning difficulty as an f64.
This adds a conversion function to U256 to get an f64. We use the method shown in the following blog post. https://blog.m-ou.se/floats/
Target::MAX was converted to a f64 and set as a const that is verified in a unit test.
2023-03-10 07:54:36 -07:00
yancy f0a3aad5b8 Add tests to Weight type 2023-03-09 17:00:22 +01:00
Andrew Poelstra ca3b4330e8
specify `internals` version in other Cargo.toml files 2023-03-08 15:02:31 +00:00
yancy b311e96603 Fix weight subtract bug 2023-03-08 12:22:50 +01:00
Andrew Poelstra 9ffbbb8efb
Merge rust-bitcoin/rust-bitcoin#1694: release bitcoin_hashes 0.12
bfd401c96e bitcoin_hashes: add CHANgELOG (Andrew Poelstra)
d1b7b54e3a bump bitcoin-hashes version to 0.12 (Andrew Poelstra)

Pull request description:

  It was a little tricky to bump the version number because of https://github.com/rust-bitcoin/rust-bitcoin/issues/1553. There are a couple other things I considered trying, which maybe we'll do for future releases, but I believe this works for now.

  Maybe should wait for #1111.

ACKs for top commit:
  tcharding:
    ACK bfd401c96e
  sanket1729:
    utACK bfd401c96e. ChangeLog looks good to me, did not review whether all noteworthy changes were included.

Tree-SHA512: d2104fc93e364415ae955e8123e6087c1eaa4c955aeaf4647ead051a223563326f66c0e278d68f64335e22c9d0af9b296dc3b744cd9d82d206844461fe7bf9c9
2023-03-08 02:13:45 +00:00
Andrew Poelstra d6134248df
Merge rust-bitcoin/rust-bitcoin#1690: Add tests for the FeeRate type
e3f95ee22b Add tests for the FeeRate type (yancy)

Pull request description:

  Adds some tests for the `FeeRate` type.

ACKs for top commit:
  apoelstra:
    ACK e3f95ee22b
  tcharding:
    ACK e3f95ee22b
  Kixunil:
    ACK e3f95ee22b

Tree-SHA512: 74d6597c747d5aa62a6510bf9fa8de971f89ad56f571aadd496f6487e80cc88bb2b5a1c6bcfed825d09d18ca2310b2bfd6fdbe330f2760369d167a653d26bef8
2023-03-08 01:07:48 +00:00
Andrew Poelstra e9e8be3acc
Merge rust-bitcoin/rust-bitcoin#1692: Add constants to `InputWeightPrediction`
3eb648df01 Add constants to `InputWeightPrediction` (Martin Habovstiak)

Pull request description:

  There are several common spends in Bitcoin that have known input weight predictions. It can be useful to have these as constants, so this change adds them. However, this only adds native segwit ones as the others are slowly fading away and might clutter the API.

  If anyone wants other constants, please write them for me, their value is not that great to me so I'm not motivated to figure out the correct numbers. :)

  This would be nice to add to 0.30 since it's small and easy but not critical.

ACKs for top commit:
  apoelstra:
    ACK 3eb648df01
  tcharding:
    ACK 3eb648df01
  sanket1729:
    ACK 3eb648df01

Tree-SHA512: 51d2cd2ecef7e6b79f9d4b52319e34b908fe8b5a337551dc2088994feeafc9c3ca87884c3db8369f8bd002947d6d14b373f08ef1419db282713206ed6f1b309a
2023-03-08 00:37:05 +00:00
Andrew Poelstra cfc4fd943f
Merge rust-bitcoin/rust-bitcoin#1695: fix clippy lint
4a2f11cc49 fix clippy lint (Andrew Poelstra)

Pull request description:

  Looks like a new clippy lint landed.

ACKs for top commit:
  yancyribbens:
    ACK 4a2f11cc49
  tcharding:
    ACK 4a2f11cc49
  sanket1729:
    utACK 4a2f11cc49

Tree-SHA512: 04fd77c2daeeeed99ea854731d73bcb43fbe5fbdba2e241a93a5058ca81f05dfbf6759d055236a8c70c58331d2b93d0fafd81e7cd631b636f881d9a0b1cdc5ca
2023-03-07 21:11:52 +00:00
Martin Habovstiak 3eb648df01 Add constants to `InputWeightPrediction`
There are several common spends in Bitcoin that have known input weight
predictions. It can be useful to have these as constants, so this change
adds them. However, this only adds native segwit ones as the others are
slowly fading away and might clutter the API.
2023-03-07 09:50:13 +01:00
Tobin C. Harding c1360067e9
Enable formatting in CI
Enable formatting in CI by doing:

- Add a section to the `test.sh` scripts to run the formatter (guarded by
  the env variable `DO_FMT`) for all crates (bitcoin, hashes, internals).
- Add `DO_FMT` to the nightly `Tests` CI job.
2023-03-07 08:57:32 +11:00
yancy e3f95ee22b Add tests for the FeeRate type 2023-03-06 10:30:45 +01:00
Tobin C. Harding 61c560baba
Improve the DO_BENCH error message
Benchmarking requires a non-stable toolchain not a nightly toolchain
i.e., includes beta.

Improve the error output to indicate as such.
2023-03-06 10:22:31 +11:00
Tobin C. Harding a11cf07501
Run the formatter
Various formatting issues have crept into the codebase because we do not
run the formatter in CI.

In preparation for enabling formatting checks in CI run `cargo +nightly
fmt` to fix current formatting issues. No changes other than those
create by the formatter.
2023-03-06 10:22:29 +11:00
Andrew Poelstra 4a2f11cc49
fix clippy lint 2023-03-05 17:19:03 +00:00
Andrew Poelstra d1b7b54e3a
bump bitcoin-hashes version to 0.12
Because we have rust-secp in the loop, we need to update rust-secp, push
a new tag, and use that here, to ensure that the direct dependency on
bitcoin_hashes, and the rust-secp version, are compatible.
2023-03-05 13:40:20 +00:00
Andrew Poelstra 10eb0da1ef
Merge rust-bitcoin/rust-bitcoin#1533: Implement support for Hidden nodes in taproot trees and Fix taproot serde bugs
74022baa44 Rename ScriptLeaf to LeafNode (sanket1729)
289dc1e7f5 Remove serde for taprootspendinfo (sanket1729)
a397ab0c19 Remove serde for ScriptLeaf (sanket1729)
9affda3012 Introduce Hidden leaves in ScriptLeaves (sanket1729)
22bc39a143 Fix serde for TaprootMerkleBranch (sanket1729)
38ed9bdf49 MOVE ONLY: Move TapTree to taproot module (sanket1729)

Pull request description:

  This PR changes/removes the serde implementation for the following types

  - TaprootSpendInfo: Removed. This data structure contains derived information for taproot spending that cannot be validated easily. To elaborate, `TaprootSpendInfo` is constructed from a tree, but loses information about the tree structure and maintains handy information like `script_control_block_map`, cached tweaked key, Merkle root etc.
  - TaprootBuillder: Removed. Hard to implement and not very useful.
  - TapTree: Modified to check invariants.
  - NodeInfo: Now implements serde with support for Hidden nodes
  - ScriptLeaf: Removed serde. Users should not directly construct this. This is just an output iterator item of `TapTree::script_leaves()`

  Data structure changes:

  - Introduced `LeafNode`: Supports Hidden leaves. Has serde implemented
  - Cleanly separate `TapTree` and `NodeInfo`:  `TapTree` is a full BIP370 compatible tree with no hidden nodes. `NodeInfo` is a tree that can potentially contain hidden leaves.
  - Added `NodeInfo::leaf_nodes`: Iterator that iterates over known and hidden leaves of `NodeInfo`.
  - Updated `TapTree::script_leaves`: Iterator that is guaranteed to output known leaves.

ACKs for top commit:
  tcharding:
    ACK 74022baa44
  apoelstra:
    ACK 74022baa44

Tree-SHA512: 919ea5bf60dc0cd8431301c1b744b046d1d781b3bed302b83a600cfa644216b6c682752795d463646b2723ac8661879284f557862a67e4572fd965fcf3dc194d
2023-03-04 13:41:37 +00:00
Andrew Poelstra 1679ad878d
Merge rust-bitcoin/rust-bitcoin#1685: Improve the public API for Feerate and Weight
b0b0cdb46c Improve the public API for Feerate and Weight (yancy)

Pull request description:

  Small nit for https://github.com/rust-bitcoin/rust-bitcoin/pull/1627/ to re-export `Weight` and `FeeRate` to shorten the use path.

  ```
  use bitcoin::Weight;
  use bitcoin::FeeRate;
  ````

ACKs for top commit:
  tcharding:
    ACK b0b0cdb46c
  Kixunil:
    ACK b0b0cdb46c
  apoelstra:
    ACK b0b0cdb46c

Tree-SHA512: 81e508c980c4f37e3791d26616459608dd60e5a6255ef28b3a049c1d27281b2853b92474d42f10031254c8c46878adf666eb709826aa4ffde1b4b3542451e080
2023-03-04 01:55:53 +00:00
Andrew Poelstra ea606d93a0
Merge rust-bitcoin/rust-bitcoin#1682: Include address in Error::NetworkValidation
73e876ffd4 Include address in Error::NetworkValidation (Subhradeep Chakraborty)

Pull request description:

  Fixes: #1677

  ## Change
  In `bitcoin/src/address.rs`, a new field `address` is added to the enum variant `Error::NetworkValidation`. Also, the implementation of `Display` trait for `Error` is updated to print the `address` field.

  However, to print the `address` through `Display`, either the reference is needed or `Address` and `Payload` both need to derive the `Copy` trait. Since I am little new to both the rust-bitcoin codebase and rust itself, I am confused about choosing between the two and have moved with the first one. Would appreciate any feedback on this.

ACKs for top commit:
  Kixunil:
    ACK 73e876ffd4
  tcharding:
    ACK 73e876ffd4
  apoelstra:
    ACK 73e876ffd4

Tree-SHA512: dd53b8648bccc8372c829e56817402fb02a9d51d1dffc854f24e68814bbefe7ea777f67aefb0d170762dbf6cdd50bd3ec55af325a1ffc21b1241d1df5531cd24
2023-03-03 16:09:21 +00:00
Subhradeep Chakraborty 73e876ffd4 Include address in Error::NetworkValidation 2023-03-02 20:46:48 +05:30
yancy b0b0cdb46c Improve the public API for Feerate and Weight 2023-03-02 09:57:36 +01:00
sanket1729 74022baa44 Rename ScriptLeaf to LeafNode
ScriptLeaf feels like leaf has to be a script, but it can a hidden
subtree. LeafNode conveys this better
2023-03-01 16:59:13 -08:00
sanket1729 289dc1e7f5 Remove serde for taprootspendinfo
Implementing this for spendinfo is really complicated because it
contains some cached data without retaining the components that are used
to compute them.

Users should serde the 1) NodeInfo and 2) internal key and reconstruct
TaprootSpendInfo from it.
2023-03-01 16:58:24 -08:00
sanket1729 a397ab0c19 Remove serde for ScriptLeaf
This was incorrect and not needed. Users should not be able to create
only tree leaves directly without going through the tree construction in
rust-bitcoin
2023-03-01 16:58:24 -08:00
sanket1729 9affda3012 Introduce Hidden leaves in ScriptLeaves
Cleanly separate `TapTree` and `NodeInfo`. Fix serde not respecting
invariants for several data structures

Repurpose some tests from removed taproot builder for taptree
2023-03-01 16:58:24 -08:00
sanket1729 22bc39a143 Fix serde for TaprootMerkleBranch 2023-03-01 16:57:56 -08:00
sanket1729 38ed9bdf49 MOVE ONLY: Move TapTree to taproot module 2023-03-01 16:57:55 -08:00
Andrew Poelstra 2cf1a4c088
Merge rust-bitcoin/rust-bitcoin#1678: Improve the public API
42b07586ac Improve the public API (Tobin C. Harding)

Pull request description:

  We created the `crypto` crate as a container for cryptography modules with the idea that it may be split out into a separate crate. There is no reason for users of the lib to know about this module. Also, we have two `taproot` modules, one in `crypto` and one at the crate root, this makes for un-ergonomic usage of the lib.

  Improve the public API by doing:

  - Make the `crypto` module private (`pub(crate)`).
  - Re-export `crypto::taproot::Signature` (and `Error`) from `crate::taproot`

  Fix: #1668

ACKs for top commit:
  apoelstra:
    ACK 42b07586ac
  Kixunil:
    ACK 42b07586ac

Tree-SHA512: 5713b98b2a48d2776cdd6ca2c0e798d6e2df604d780e5182bd770fb2df807cf1f65bc24663ee6f7734fc1e0c80494c5a87dc60e44c83acefcffec7f059203a47
2023-03-01 15:42:36 +00:00
Tobin C. Harding 42b07586ac
Improve the public API
We created the `crypto` crate as a container for cryptography modules
with the idea that it may be split out into a separate crate. There is
no reason for users of the lib to know about this module. Also, we have
two `taproot` modules, one in `crypto` and one at the crate root, this
makes for un-ergonomic usage of the lib.

Improve the public API by doing:

- Make the `crypto` module private (`pub(crate)`).
- Re-export `crypto::taproot::Signature` (and `Error`) from
  `crate::taproot`
2023-03-01 09:28:42 +11:00
Andrew Poelstra 5ad2bec626
Merge rust-bitcoin/rust-bitcoin#1679: Add constant for coinbase maturity
7d1645aea0 Add constant for coinbase maturity (benthecarman)

Pull request description:

  Not sure if this is the best place to put this but it is nice to have a constant for this instead of having other libraries make their own (ie https://github.com/lightningdevkit/rust-lightning/pull/1924#pullrequestreview-1222807626)

ACKs for top commit:
  tcharding:
    ACK 7d1645aea0
  apoelstra:
    ACK 7d1645aea0

Tree-SHA512: 5ac2a3359cadd303158c66ba45db8f4bf8cc80b6c19604262999ff361fd0bd98e2a4851c57da1962cb5c74f5789a85c8b3861f1742706a60ce1fbc57c3c200cc
2023-02-28 22:01:34 +00:00
benthecarman 7d1645aea0
Add constant for coinbase maturity 2023-02-28 05:37:10 -06:00
Andrew Poelstra 13143d0f6f
Merge rust-bitcoin/rust-bitcoin#1675: Add utils to convert ChainHash to a Network
56569b32ef Add utils to convert ChainHash to a Network (benthecarman)

Pull request description:

ACKs for top commit:
  Kixunil:
    ACK 56569b32ef
  tcharding:
    ACK 56569b32ef

Tree-SHA512: a489fcb1c1208db4271076d88288658988a63209e56e7433bde82d7d5719450433348fcc3cb6aae59ffa6ed8aff510d6b031c6899d5cf64c503a53b2d4c692b8
2023-02-27 23:55:24 +00:00
benthecarman 56569b32ef
Add utils to convert ChainHash to a Network 2023-02-27 12:28:04 -06:00
Andrew Poelstra 4d8ba9be31
Merge rust-bitcoin/rust-bitcoin#1577: Re-name hash inner/byte methods
161273b209 Re-name hash inner/byte methods (Tobin C. Harding)
324b6f264b Use `into` for hash argument (Tobin C. Harding)

Pull request description:

  Currently we have an associated type on hash types `Inner` with accompanying methods `into_inner`, `from_inner`, `as_inner`. Also, we provide a way to create new wrapped hash types. The use of 'inner' becomes ambiguous with the addition of wrapped types because the inner could be the inner hash type or the `Inner` byte array of the inner wrapped hash type.

  In an effort to make the API more clear and uniform do the following:

  - Rename `Inner` -> `Bytes`
  - Rename `*_inner` -> `*_byte_array`
  - Rename the inner hash to/from methods to `*_raw_hash`

  Correct method prefix `into_` -> `to_` because theses methods convert owned `Copy` types.

  Add the trait Bound `Copy` to the `Bytes` type because we rely on this trait bound for the conversion methods to be correctly named according to convention.

  Because of the dependency hole created by `secp256k1` this patch changes the secp dependency to a git tag dependency that includes changes to the hashes calls required so that we can get green lights on CI in this repo.

  Fix: #1554

ACKs for top commit:
  Kixunil:
    ACK 161273b209
  apoelstra:
    ACK 161273b209

Tree-SHA512: b51b851a1855e6a26a7ef8ccb9f554723d4cc39b368812703587a50e81e7ab49714a81696af0be743b947f09e1fca227a5331b6735912c5b0d5cd0178905f006
2023-02-27 17:28:14 +00:00
Andrew Poelstra a40427b177
Merge rust-bitcoin/rust-bitcoin#1676: Fix docs for UnknownMagic to be accurate
a4b5fb4002 Fix docs for UnknownMagic to be accurate (benthecarman)

Pull request description:

  I assume the old docs are a copy-paste error, strings are not involved when this error is encountered.

ACKs for top commit:
  Kixunil:
    ACK a4b5fb4002
  apoelstra:
    ACK a4b5fb4002

Tree-SHA512: b2b71f81be8a0d979b15471e7262e01284443e05626b26a19236fd25581700d9e37409576a4b73d5bb537c49ae83a4b7d40f0888dff078b07bd7550026cd778a
2023-02-27 15:54:07 +00:00