Commit Graph

3636 Commits

Author SHA1 Message Date
Andrew Poelstra 6f754df231
fuzz: add fuzzing README
also remove `set -e` from `fuzz-util.sh` because the README suggests
that users sometimes source this into their interactive shell.
2023-04-27 00:24:52 +00:00
Andrew Poelstra f093765efe
fix fuzz.sh and cycle.sh to use generated lists of targets 2023-04-27 00:24:52 +00:00
Andrew Poelstra 6534f22362
fuzz: auto-generate CI and Cargo.toml files 2023-04-27 00:24:52 +00:00
Andrew Poelstra 8021034d86
rename travis-fuzz.sh to fuzz.sh; partially patch CI 2023-04-27 00:24:52 +00:00
Andrew Poelstra 0be75f7edc
move hashes/fuzz into main fuzz/ directory 2023-04-27 00:24:52 +00:00
Andrew Poelstra 5a891dec2d
move bitcoin fuzz targets into bitcoin/ subdirectory 2023-04-27 00:24:52 +00:00
Andrew Poelstra e3111c748b
move bitcoin/fuzz into repo root; add to workspace
This allows testing the fuzztests and making sure that they compile and
tests pass, etc., just using `cargo test --all` in the root.
2023-04-27 00:24:48 +00:00
Peter Todd dd4ad9444e
Hardcode expected weight in txin_txout_weight_tests
Rational: the expected weight is fixed so this both ensures we don't
accidentally change it somehow, and makes it easier to re-use these test
cases in other codebases (eg python-bitcoinlib).
2023-04-26 22:02:03 +00:00
Peter Todd 8b9ec8eb77
Fix policy link 2023-04-26 21:08:26 +00:00
Andrew Poelstra db12853ac2
Merge rust-bitcoin/rust-bitcoin#1814: embedded: Remove error handler
d37845197f embedded: Remove error handler (Tobin C. Harding)

Pull request description:

  Seems we no longer need an explicit error handler, remove it.

  I did not grok the reason (long thread link below) but just removed it and checked that the embedded crates still ran correctly.

  https://github.com/rust-lang/rust/issues/51540

  Fix: #1813

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

Tree-SHA512: 76ce3f346e7e4e62595c6a6c415476b0cabcf27ded8e79a3e0b692a98b12ff9e90bec2841d18790bb62a16c553ad60492fc09e1aa4bf550c7070cd29b5ac1702
2023-04-26 15:17:02 +00:00
Tobin C. Harding d37845197f
embedded: Remove error handler
Seems we no longer need an explicit error handler, remove it.

I did not grok the reason (long thread link below) but just removed it
and checked that the embedded crates still ran correctly.

https://github.com/rust-lang/rust/issues/51540)
2023-04-26 14:29:39 +10:00
Andrew Poelstra 967b58dc2a
Merge rust-bitcoin/rust-bitcoin#1810: Spelling and typo fixes
20b812dc66 Spelling and typo fixes (yancy)

Pull request description:

  Fix some types in Transaction.rs and encode.rs

ACKs for top commit:
  apoelstra:
    ACK 20b812dc66
  Kixunil:
    ACK 20b812dc66
  tcharding:
    ACK 20b812dc66

Tree-SHA512: d613189932ecb760be385c4095723501222cc8cec8b25525b58f76f9486d33fe46ab241bd2c098ea141f0fd12bb52abc677eba4a0cf3fe5b40b515bd75c7237c
2023-04-26 00:46:31 +00:00
Andrew Poelstra 84a075d03a
Merge rust-bitcoin/rust-bitcoin#1796: transaction: Rename is_coin_base to is_coinbase
a54e1ceab1 Apply rustfmt (The rustfmt Tyranny)
38d11ce3da ci: Make release CI search for NEXT.RELEASE instead (Steven Roose)
dad3abd20f transaction: Rename is_coin_base to is_coinbase (Steven Roose)

Pull request description:

  Alternative to https://github.com/rust-bitcoin/rust-bitcoin/pull/1795.

  Keep the old method as deprecated and add doc alias. Also change internal usage of the method.

ACKs for top commit:
  tcharding:
    ACK a54e1ceab1
  apoelstra:
    ACK a54e1ceab1

Tree-SHA512: 52d9729bf83da164556d960f8867cb836ff57a0f619da3dd3620efffb28a974aac23b8085863ab0e072a4bdb2f13ac576efa43ad2eec9a271ad044227f4d00a4
2023-04-24 23:14:39 +00:00
The rustfmt Tyranny a54e1ceab1 Apply rustfmt 2023-04-24 18:20:23 +01:00
yancy 20b812dc66 Spelling and typo fixes 2023-04-24 16:51:10 +02:00
Andrew Poelstra c744e24eb8
Merge rust-bitcoin/rust-bitcoin#1804: extended_tests: Remove stale docs
53d75c7b94 extended_tests: Remove stale docs (Tobin C. Harding)

Pull request description:

  We no longer need to pin `syn`; remove stale docs.

  This is a follow up to #1696

ACKs for top commit:
  Kixunil:
    ACK 53d75c7b94
  apoelstra:
    ACK 53d75c7b94

Tree-SHA512: 9e939860cfb3731942e92a611632f0b24acc88e06a96e905ee2ae50e489d1610f7b9c79e20384196482aad4d5da182f6f919d18726e079a98a667532806d5aae
2023-04-20 22:06:40 +00:00
Tobin C. Harding 53d75c7b94
extended_tests: Remove stale docs
We no longer need to pin `syn`; remove stale docs.
2023-04-20 09:17:10 +10:00
Andrew Poelstra 8440d80a5a
Merge rust-bitcoin/rust-bitcoin#1696: Remove `schemars` pin from manifest
6c61e1019e Fix pinning (schemars and MSRV) (Tobin C. Harding)
c8e38d6a5a hashes: Implement JsonSchema for sha256t::Hash<T> (Tobin C. Harding)

Pull request description:

  This has grown due to now including pinning work also done in https://github.com/rust-bitcoin/rust-bitcoin/pull/1736, I decided to do this because the PRs conflict and doing it all here saves accidentally getting out of sync. And  https://github.com/rust-bitcoin/rust-bitcoin/pull/1764 requires this PR.

  - Patch 1 is unchanged
  - Patch 2 now fixes pinning in bitcoin and hashes CI scripts and in the docs of both as well as the manifest stuff relating to `schemars` - phew.

  Fix: #1687

ACKs for top commit:
  Kixunil:
    ACK 6c61e1019e
  apoelstra:
    ACK 6c61e1019e

Tree-SHA512: eae4aa9700817bab6ad444e07709e8b1a4ffb1625e08be6ba399abde38bf6f8e5ea216a0836e2e26dfaddc76c392802cd016738ea6e753a1bca2584d9d2a9796
2023-04-19 22:18:29 +00:00
Steven Roose 38d11ce3da
ci: Make release CI search for NEXT.RELEASE instead 2023-04-19 16:07:03 +01:00
Steven Roose dad3abd20f
transaction: Rename is_coin_base to is_coinbase
Keep the old method as deprecated and add doc alias.
Also change internal usage of the method.
2023-04-19 16:02:59 +01:00
Tobin C. Harding 6c61e1019e
Fix pinning (schemars and MSRV)
Done as is single patch to make sure all the docs and CI are in sync and
correct.

We currently pin the `schemars` dependency using `<=0.8.3` as well as a
the `dyn-clone` transient dependency in the manifest (`hashes` and the
extended test crate). This is incorrect because it makes usage of the
crate klunky (or possibly impossible) if downstream users wish to use a
later version of `schemars`.

Observe also that we do not have to pin `schemars`, we do however have to pin
the `serde` crate if either `serde` or `schemars` features are enabled.
Do so in CI and document in the readme file within hashes.

Currently we have a pin remaining from the old MSRV (`syn` due to use
of `matches!`).

Fix pinning by:

- Remove pin in manifest for `schemars`
- Fix pinning for MSRV in CI and docs (this includes documenting pinning
  requirements for `schemars` feature because it is related to the other
  pin of `serde`) in both `hashes` readme and main repo readme.
2023-04-19 10:17:18 +10:00
Sergi Delgado Segura aa6a3530a6 Adds as_core_arg serde module to network
The new module provides serde functions to convert from/to Bitcoin Core
network variants

Includes tests suggested by @tcharding
2023-04-17 12:28:13 +02:00
Andrew Poelstra 0af8d45e21
Merge rust-bitcoin/rust-bitcoin#1797: Add predict_weight test for witness address types
8f6317fbab Add predict_weight test for witness address types (yancy)

Pull request description:

  Add a predict_weight test for address types with witness data

ACKs for top commit:
  Kixunil:
    ACK 8f6317fbab
  apoelstra:
    ACK 8f6317fbab

Tree-SHA512: 954908f068d6b0e8f7cc6bc6bffd110d490d7165cf2544ff0f936264761cb1f8e4da1e37fd5a6a34fd8b05f8d72817a3b340bbf968b29c9f538f10853347fdf0
2023-04-14 16:08:31 +00:00
yancy 8f6317fbab Add predict_weight test for witness address types 2023-04-14 12:02:37 +02:00
Andrew Poelstra 3795f60fa8
Merge rust-bitcoin/rust-bitcoin#515: Add Inventory::network_hash() method
3d524e06e4 Add Inventory::network_hash() method (Steven Roose)

Pull request description:

  I'm not positive we won't ever had inv items that are not `sha256d::Hash`, though. I would expect them to stay like that, but we never know.

  Would accept that as a reasonable objection against this helper.

ACKs for top commit:
  apoelstra:
    ACK 3d524e06e4
  tcharding:
    ACK 3d524e06e4

Tree-SHA512: 97d64b08ff99dbec2d907bdb98aa41ede4a15b988551ad8dd87a10ac5c9750ae4d516bb558c1e4f2171612777355c2baf1ffbe671cb92320a1af64d73bd150dd
2023-04-13 23:20:16 +00:00
yancy dff757d7db Comment predict_weight 2023-04-13 17:44:41 +02:00
Steven Roose 3d524e06e4
Add Inventory::network_hash() method 2023-04-13 16:23:22 +01:00
Andrew Poelstra 1ad17a6aa9
Merge rust-bitcoin/rust-bitcoin#1791: ci: Check for remaining NEXT_RELEASE in the release script
b3b57518a0 ci: Check for remaining NEXT_RELEASE in the release script (Steven Roose)

Pull request description:

  The intention here is that we can use the deprecation tag
  `#[deprecated(since = "NEXT_RELEASE")]` and fill in the version number
  at release time.

  Not sure if there is a good place to mention this somewhere in developer docs. I looked into CONTRIBUTING.md but didn't really found a suitable section for this.

ACKs for top commit:
  tcharding:
    utACK b3b57518a0
  apoelstra:
    ACK b3b57518a0

Tree-SHA512: 7c077ee6569d38cf4c518cd5003ba0c09fdf7f98f4fb14fd28b49eb2e1b43eec7833de7abd1e35b9b14451f37de8e36a740a6445e3a5feb34a79cbfb7e63ee9f
2023-04-12 15:04:39 +00:00
Steven Roose b3b57518a0
ci: Check for remaining NEXT_RELEASE in the release script
The intention here is that we can use the deprecation tag
`#[deprecated(since = "NEXT_RELEASE")]` and fill in the version number
at release time.
2023-04-10 21:16:59 +01:00
Andrew Poelstra 36500b4451
Merge rust-bitcoin/rust-bitcoin#1758: CI: Only run release job for release PRs
e223cbe6df CI: Only run release job for release PRs (Tobin C. Harding)

Pull request description:

  Currently we run the release jobs for all PRs, this leads to red CI runs any time we have unreleased changes in one crate used by another i.e., basically days after a release comes out.

  Add a `release.sh` script that has more smarts to try and figure out if the patch series currently ontop of tip of mater contains changes that imply its a release PR. To do so we check for changes to the version field in the manifest of each crate.

ACKs for top commit:
  stevenroose:
    ACK e223cbe6df
  apoelstra:
    ACK e223cbe6df

Tree-SHA512: cc5503f68f9d275989acf8d2e8ff3b2b4ceb73606b8b823e408e4cf0bccbbb6dce0c583917d4dcb4b1b7f1b0bc34293251247d088943a5a6d5e06bf5af2ee8c3
2023-04-10 14:46:00 +00:00
Andrew Poelstra 6bf6898add
Merge rust-bitcoin/rust-bitcoin#1781: hashes: Derive traits on the sha512::Hash type
088fa24be8 hashes: Derive traits on the sha512::Hash type (Tobin C. Harding)

Pull request description:

  For all the other hash types we use derive, by way of the `hash_type!` macro, unless I'm missing something we can do the same for `sha512::Hash`.

ACKs for top commit:
  apoelstra:
    ACK 088fa24be8
  Kixunil:
    ACK 088fa24be8

Tree-SHA512: 3849261a8208c8c6108f4ecc5643940d38289f791d1b360ef4b13d60f72b365cd29f07f625a2d320f188defde848ddd64c8532cae5979e54afbf62f741927185
2023-04-10 04:22:32 +00:00
Steven Roose ed6421c939
address: Add generic serde::Serialize for Address
Otherwise a generic `Address<impl NetworkValidation>` is not
serializable.
2023-04-09 19:02:53 +01:00
Steven Roose 814b9917da
address: Add Sync, Send, Sized and UnPin marker traits on NetworkValidation 2023-04-09 19:02:43 +01:00
Tobin C. Harding 088fa24be8
hashes: Derive traits on the sha512::Hash type
For all the other hash types we use derive, by way of the `hash_type!`
macro, unless I'm missing something we can do the same for
`sha512::Hash`.
2023-04-09 13:36:38 +10:00
Andrew Poelstra e83a2d3422
Merge rust-bitcoin/rust-bitcoin#1742: Use package in manifest and shorten import
fabcde036f Use package in manifest and shorten import (Tobin C. Harding)

Pull request description:

  We can use `package` to rename `bitcoin_hashes` to `hashes` and `bitcoin_internals` to `internals`. This makes imports more terse with no loss of meaning.

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

Tree-SHA512: bc5bff6f7f6bf3b68ba1e0644a83da014081d8c6c9d578c21cb54fdd56a018f68733dd1135d05b590ba193ed9efd12fa9019182c1fed347e604d8548f6ef9103
2023-04-05 14:20:06 +00:00
Andrew Poelstra 8edfc4597b
Merge rust-bitcoin/rust-bitcoin#1765: unsafe address type conversions
29cb34eed7 Refactor Address struct and its methods (Harshil Jani)

Pull request description:

  Closes #1755

  In this PR the `as_unchecked` is added to the Address struct, which returns a reference to the same address but with the type Address<NetworkUnchecked>.  Similarly, the `assume_checked_ref` is added to Address<NetworkUnchecked>, which returns a reference to the same address but with the type Address.

ACKs for top commit:
  tcharding:
    ACK 29cb34eed7
  apoelstra:
    ACK 29cb34eed7

Tree-SHA512: 75ba40883d9fb31026b0e94e8d3fdcf808ff38a4d10f61f99a1e14ddc48358da86bad44cd78563dc67aa5d39382a5493e73c03891317f361f590e39b6257cb84
2023-04-04 17:40:33 +00:00
Tobin C. Harding e223cbe6df
CI: Only run release job for release PRs
Currently we run the release jobs for all PRs, this leads to red CI runs
any time we have unreleased changes in one crate used by another i.e.,
basically days after a release comes out.

Add a `release.sh` script that has more smarts to try and figure out if
the patch series currently ontop of tip of mater contains changes that
imply its a release PR. To do so we check for changes to the version
field in the manifest of each crate.
2023-04-04 12:49:59 +10:00
Andrew Poelstra 350b413e59
Merge rust-bitcoin/rust-bitcoin#1773: Make `sha256t_hash_newtype!` evocative of the output.
91f45a214f Replace hardcoded values with compile-time hashing (Martin Habovstiak)
095b7958dd Make `sha256t_hash_newtype!` evocative of the output. (Martin Habovstiak)

Pull request description:

  The Rust API guidelines state that macros should be evocative of the
  output, which is a sensible recommendation. We already had this for
  `hash_newtype!` macro but didn't for sha256t version.

  This changes the macro to have this syntax:

  ```rust
  sha256t_hash_newtype! {
      // Order of these structs is fixed.
      /// Optional documentation details here. Summary is auto-generated.
      /*pub*/ struct Tag = raw(MIDSTATE_BYTES, LEN);

      /// Documentation here
      #[hash_newtype(forward)] // optional, default is backward
      /*pub*/ struct HashType(/* attributes allowed here */ _);
  }
  ```

  Closes https://github.com/rust-bitcoin/rust-bitcoin/issues/1427

  Depends on #1769

  How do you like the syntax? Is weird `struct Foo = bar(..);` acceptable?

ACKs for top commit:
  tcharding:
    ACK 91f45a214f
  apoelstra:
    ACK 91f45a214f

Tree-SHA512: f6b555b20311a4c1cb097bc296c92459f6fbe16ba102d8c977eb2383dbcae3cc8ffce32e3cb771e7e22197fda26379971aa4feaadc5e2e70d37fa690ae8b8859
2023-04-03 18:21:58 +00:00
Andrew Poelstra 142b4fc431
Merge rust-bitcoin/rust-bitcoin#1771: Use slice patterns
873501a85f Use slice patterns (Martin Habovstiak)

Pull request description:

  Some code looks better with slice patterns. This changes `bip32` to use them.

ACKs for top commit:
  apoelstra:
    ACK 873501a85f
  tcharding:
    ACK 873501a85f

Tree-SHA512: 2e91b21d0f943c04f592112f241444ba3b1b1dad47ea6bea162f62cfbcaf98e383257cad144072b3807aaa0c122dabab638ac10b1cc1f5179727a5f05aac0659
2023-04-03 15:48:35 +00:00
Andrew Poelstra cd9f706cb1
Merge rust-bitcoin/rust-bitcoin#1769: Implement computing SHA256 in const context
42d3ae05be Implement computing SHA256 in const context (Martin Habovstiak)

Pull request description:

  Computing hashes in const fn is useful for esily creating tags for `sha256t`. This adds `const fn` implementation for `sha256::Hash` and the algorithm for computing midstate of tagged hash in `const` context.

  Part of #1427

  I'd like to make sha256t evocative of the output after this which would also do the thing we want to do with #1427 (awkward language to bypass GH automatically closing it...) I'm thinking of this:

  ```rust
  sha256t_newtype_hash! {
  // optional attrs
  /*pub*/ struct TagName = "tag_str"; // weird syntax but I guess OK-ish?

  // optional attrs
  /*pub*/ struct HashName(_); // allowed to elide the type because it's implied; maybe also allow writing it?
  }
  ```

  What do you think? I was also thinking about this alternative:

  ```rust
  sha256t_newtype_hash! {
  // optional attrs
  /*pub*/ struct TagName;

  const TAG: Tag = from_str("tag_str"); // allows for having from_raw([...]) or even from_hex([...])

  // optional attrs
  /*pub*/ struct HashName(_); // allowed to elide the type because it's implied; maybe also allow writing it?
  }
  ```

  Which looks more natural but maybe too much boilerplate? Which one do you like? Any better ideas? Heads up sanket1729

  Also FYI tcharding this is the kind of post-1.48 change I was thinking about. :)

ACKs for top commit:
  apoelstra:
    ACK 42d3ae05be
  tcharding:
    ACK 42d3ae05be

Tree-SHA512: 437f3160e53104fcdf94c6e09ca6722ea2fe1032429b4701e578dded665cb9cab45cc68ee718b8925075c05dff231c0b898dc03949ef57b831666c68e38950a6
2023-04-03 15:10:19 +00:00
Andrew Poelstra f34f308f4b
Merge rust-bitcoin/rust-bitcoin#1774: Update clippy MSRV configuration
8b4280d5ef Update clippy MSRV configuration (Martin Habovstiak)

Pull request description:

  We've upgraded MSRV but didn't update clippy config, so some things that could be improved aren't caught by clippy. This updates the config and fixes the new issues.

  I also `rg '1\.41\.1'`ed for interesting changes and found one additional improvement.

ACKs for top commit:
  apoelstra:
    ACK 8b4280d5ef
  tcharding:
    ACK 8b4280d5ef

Tree-SHA512: 337ca099ca1a4b8b5d230c802bc455a5e0bbc3436066e41577c5b67f8d7fedede6f7a446b208da067ffc2cc2cebcbc187404846c295e9d89798f11dc66d34e34
2023-04-03 13:41:49 +00:00
Harshil Jani 29cb34eed7 Refactor Address struct and its methods
This commit refactors the Address struct and its methods to improve
its functionality and usability.The AddressInner struct now holds
the payload and network, and the PhantomData<V> type is used to track
the network validation state.

Also as_unchecked and assume_checked_red methods are added to allow
conversion between checked and unchecked network validation state.

Signed-off-by: Harshil Jani <harshiljani2002@gmail.com>
2023-04-03 15:24:45 +05:30
Martin Habovstiak 91f45a214f Replace hardcoded values with compile-time hashing
Previous changes enabled passing the string used as a tag into
`sha256t_hash_newtype!` macro rather than hard-coding midstate. This
commit takes advantage of it and replaces the hard-coded values with
compile-time executed (`const`) hashing.
2023-04-02 17:01:10 +02:00
Martin Habovstiak 095b7958dd Make `sha256t_hash_newtype!` evocative of the output.
The Rust API guidelines state that macros should be evocative of the
output, which is a sensible recommendation. We already had this for
`hash_newtype!` macro but didn't for sha256t version.

This changes the macro to have this syntax:

```rust
sha256t_hash_newtype! {
    // Order of these structs is fixed.
    /// Optional documentation details here. Summary is auto-generated.
    /*pub*/ struct Tag = raw(MIDSTATE_BYTES, LEN);

    /// Documentation here
    #[hash_newtype(forward)] // optional, default is backward
    /*pub*/ struct HashType(/* attributes allowed here */ _);
}
```

Closes #1427
2023-04-02 17:00:52 +02:00
Martin Habovstiak 8b4280d5ef Update clippy MSRV configuration
We've upgraded MSRV but didn't update clippy config, so some things that
could be improved aren't caught by clippy. This updates the config and
fixes the new issues.

I also `rg '1\.41\.1'`ed for interesting changes and found one
additional improvement.
2023-04-02 16:28:10 +02:00
Martin Habovstiak 42d3ae05be Implement computing SHA256 in const context
Computing hashes in const fn is useful for esily creating tags for
`sha256t`. This adds `const fn` implementation for `sha256::Hash` and
the algorithm for computing midstate of tagged hash in `const` context.

Part of #1427
2023-04-02 01:35:12 +02:00
Martin Habovstiak 873501a85f Use slice patterns
Some code looks better with slice patterns. This changes `bip32` to use
them.
2023-04-02 01:08:03 +02:00
Tobin C. Harding c8e38d6a5a
hashes: Implement JsonSchema for sha256t::Hash<T>
The derived implementation of `JsonSchema` recently stopped working as
described here:

https://github.com/rust-bitcoin/rust-bitcoin/pull/1696#issuecomment-1458670415

Implement the suggestion.
2023-03-31 11:09:07 +11:00
Andrew Poelstra c7f970d8dc
Merge rust-bitcoin/rust-bitcoin#1760: Add per crate release notes link
1187e10299 Add per crate release notes link (Tobin C. Harding)

Pull request description:

  In #1759 we fixed the link to the bitcoin changelog, we can go one step further and add links for each of the crates.

ACKs for top commit:
  apoelstra:
    ACK 1187e10299
  Kixunil:
    ACK 1187e10299
  sanket1729:
    ACK 1187e10299

Tree-SHA512: 10c79c2e633c130855b321d7644b639d7f5fde9dbe94ee54005c34f7ac0821bab714d8a09a6480bfc5363cadc05eeb6dc052409b62e744aae130b7955d9d250d
2023-03-30 19:58:55 +00:00
Andrew Poelstra 895db71156
Merge rust-bitcoin/rust-bitcoin#1763: Use doc_auto_cfg
a189942c64 Use doc_auto_cfg (Tobin C. Harding)

Pull request description:

  If we use `#![cfg_attr(docsrs, feature(doc_auto_cfg))]` instead of `#![cfg_attr(docsrs, feature(doc_cfg))]` we no longer need to manually mark types with `#[cfg_attr(docsrs, doc(cfg(feature = "std")))]`.

  Sweeeeeet.

  Props to pezcore for the lesson :)

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

Tree-SHA512: 1ced1e09f5d1733b362b83ca650d3f52c89eb57e78e8437f74c496d89776548f8c50feab6750352342e2abe680434681de2c126ce36a81dda21397b9695d4d4e
2023-03-30 16:56:49 +00:00