The `as_unchecked` method is never dangerous to call because an
`Address<UncheckedNetwork>` provides a subset of functionality that is
always ok to use. It is only dangerous to go the other way unchecked to
checked.
P2WPKH requires keys to be compressed which introduces error handling
even in cases when it's statically known that a key is compressed. To
avoid it, this change introduces `CompressedPublicKey` which is similar
to `PublicKey` except it's statically known to be compressed.
This also changes relevant code to use `CompressedPublicKey` instead of
`PublicKey`.
An `AddressInner` struct is created when parsing address strings however
address strings do not map 1:1 to `Network` because signet and testnet
use the same bech32 prefix "tb".
We can fix this by inlining the `Payload` variants into `AddressInner`
and adding prefix enums for legacy addresses and a `KnownHrp` for bech32
addresses.
Also enables removing the `AddressEncoding` struct as we can display the
`AddressInner` struct directly. (The `Display` impl is on `AddressInner`
and not directly on address to ignore the `NetworkValidation` wrapper,
may be able to be simplified still further.)
Calling `wpubkey_hash` on a key that is uncompressed is flat out an
error, really it is a programmer error at build time because a segwit
key should never be compressed, however, for historical reasons we do
not enforce this in the type system. As a step towards clarity make it
an error to call `wpubkey_hash` on a an uncompressed pubkey. This adds
documentation and potentially might assist debugging for newer devs.
7d695f6b41 Improve public re-exports (Tobin C. Harding)
33774122e0 Remove public re-exports from private module (Tobin C. Harding)
Pull request description:
Improve the public exports in two ways:
1. Inline re-exports into the docs of the module that re-exports them.
2. Separate public and private use statements
Recently we discussed a way to separate the public and private import statements to make the code more clear and prevent `rustfmt` joining them all together.
Separate public exports using a code block and `#[rustfmt::skip]`. Has the nice advantage of reducing the number of `#[doc(inline)]` attributes also.
1. Modules first, as they are part of the project's structure.
2. Private imports
3. Public re-exports (using `rustfmt::skip` to prevent merge)
Use the format
```rust
mod xyz;
mod abc;
use ...;
pub use {
...,
};
```
This patch introduces changes to the rendered HTML docs.
ACKs for top commit:
apoelstra:
ACK 7d695f6b41
Tree-SHA512: dc9121c0fe282e3035d862beadb89e2d5a374a7dab6b1c3147a9b5960f8bc2f5af49892f0f713f55c645c46f53464c32daf390c11d85c75553b3ea7e0efc8246
Currently we have functions on `Address` that call through to a public
`Payload` type. The `Payload` type is an implementation detail and
should never have been public. In preparation for modifying the
`AddressInner` and removing `Payload` altogether lets move all the
functionality from `Payload` into `Address` - this is basically just
code moves so it is feasible to review with some confidence.
This is an API breaking change because it makes `Payload` private and
also removes from the pubic `Address` API functions that accept and
return `Payload`. Apart from that the changes can be seen as
refactoring.
The `AddressEncoding` type exists solely to assist us in implementing
`Display` on `Address`, it may have been used in the past by alt-coins
back when we had a more tolerant outlook on supporting them. Nowadays
we explicitly do not support alts.
Improve the public exports in two ways:
1. Inline re-exports into the docs of the module that re-exports them.
2. Separate public and private use statements
Recently we discussed a way to separate the public and private import
statements to make the code more clear and prevent `rustfmt` joining
them all together.
Separate public exports using a code block and `#[rustfmt::skip]`. Has
the nice advantage of reducing the number of `#[doc(inline)]` attributes
also.
1. Modules first, as they are part of the project's structure.
2. Private imports
3. Public re-exports (using `rustfmt::skip` to prevent merge)
Use the format
```rust
mod xyz;
mod abc;
use ...;
pub use {
...,
};
```
This patch introduces changes to the rendered HTML docs.
Update the `bech32` dependency to use the newly release beta version.
The main fix here is silent, a bug fix in `bech32` that was being hit by
our fuzzing suite.
On our way to v1.0.0 we are defining a standard for our error types,
this includes:
- Uses the following derives (unless not possible, usually because of `io::Error`)
`#[derive(Debug, Clone, PartialEq, Eq)]`
- Has `non_exhaustive` unless we really know we can commit to not adding
anything.
Furthermore, we are trying to make the codebase easy to read. Error code
is write-once-read-many (well it should be) so if we make all the error
code super uniform the users can flick to an error and quickly see what
it includes. In an effort to achieve this I have made up a style and
over recent times have change much of the error code to that new style,
this PR audits _all_ error types in the code base and enforces the
style, specifically:
- Is layed out: definition, [impl block], Display impl, error::Error impl, From impls
- `error::Error` impl matches on enum even if it returns `None` for all variants
- Display/Error impls import enum variants locally
- match uses *self and `ref e`
- error::Error variants that return `Some` come first, `None` after
Re: non_exhaustive
To make dev and review easier I have added `non_exhaustive` to _every_
error type. We can then remove it error by error as we see fit. This is
because it takes a bit of thinking to do and review where as this patch
should not take much brain power to review.
We would like the codebase to be optimized for readability not ease of
development, as such code that is write-once-read-many should not use
macros.
Currently we use the `impl_std_error` macro to implement
`std::error::Error` for struct error types. This makes the code harder
to read at a glance because one has to think what the macro does.
Remove the `impl_std_error` macro and write the code explicitly.
The `address::Error` is module level general, we can make the code
easier to maintain and easier to stabalize by splitting the parse error
out of the general error.
Create a `ParseError` that is returned by `FromStr for Address`. Remove
the now unused variants from the general `address::Error`.
In an effort to reduce the number of lines of code import the error
variants locally within the `Display` impl on `Error`.
Refactor only, no logic changes.
Split the error code out of `address/mod.rs` and into
`address/error.rs`. Code move only, no changes other than to
imports/exports etc. to make it build.