Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core, proto)!: add bech32m addresses #1124

Merged
merged 17 commits into from
Jun 7, 2024

Conversation

SuperFluffy
Copy link
Member

@SuperFluffy SuperFluffy commented May 30, 2024

Summary

Adds bech32m addresses.

Background

bech32m encoded addresses are the de-facto standard in cosmos. By using a "astria" prefix (in the human readable prefix, bech32 HRP sense) we align astria with the rest of the cosmos ecosystem.

Changes

  • Add a field bech32m to astria.primitive.v1.Address
  • Deprecate astria.primitive.v1.Address.inner
  • Change std::fmt::Display for Address to use bech32m encoding
  • Serialize Address in terms of its protobuf-json mapping
  • Update the Address:try_from_raw constructor to allow ingesting protobufs that have their inner or bech32m or populated. inner and bech32m are mutually exclusive, only one may be set.
  • Protobufs with inner set are assumed to have prefix "astria".
  • Introduce an AddressBuilder type state builder that requires both a prefix and array/byte slice be set.
  • Update all services to the new way of constructing addresses, but with the prefix "astria" set everywhere
  • Add a SignedTransaction::address method that constructs an address from the verification key and the chain_id stored in the unsigned transaction's transaction_params::chain_id.
  • Provide a builder for TransactionParams enforcing that chain IDs are have hrp compatible names.

Testing

  • update snapshot tests for address-as-json serialization
  • add unit tests:
    • addresses with only bytes are accepted
    • addresses with only bech32m are accepted
    • addresses with both bytes and bech32m are are rejected
    • protobufs created from the common Address type only have bech32m populated
    • various tests to assert Address invariants (mainly maximum length of prefix + fixed-size address always being encodeable to a string)
    • updated all tests that somehow make use of addresses (mainly sequencer, bridge-withdrawer, composer)

Breaking Changelist

This patch is marked breaking because the sequencer snapshot tests are triggered. They all contain actions that themselves contain protobuf address. This patch is backward but not forward compatible.

Related Issues

closes #943

@SuperFluffy SuperFluffy marked this pull request as ready for review May 30, 2024 14:57
@SuperFluffy SuperFluffy requested review from a team, joroshiba and noot as code owners May 30, 2024 14:57
@github-actions github-actions bot added the proto pertaining to the Astria Protobuf spec label May 30, 2024
@SuperFluffy SuperFluffy added the core pertaining to the astria-core crate label May 30, 2024
Copy link
Collaborator

@noot noot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good!

@github-actions github-actions bot added the sequencer pertaining to the astria-sequencer crate label Jun 4, 2024
@SuperFluffy SuperFluffy changed the title feat(core, proto): add bech32m addresses feat(core, proto)!: add bech32m addresses Jun 4, 2024
crates/astria-core/src/primitive/v1/mod.rs Outdated Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are the app_hashes changing? I would expect the data hash to change but not the app_hash?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It contains a SudoAddressChangeAction, which itself contains new_address: Address. Hence the change.

@SuperFluffy SuperFluffy requested a review from noot June 6, 2024 16:26
@github-actions github-actions bot added the composer pertaining to composer label Jun 6, 2024
@SuperFluffy
Copy link
Member Author

SuperFluffy commented Jun 6, 2024

After the review comments I received from @joroshiba and @noot I went back to the drawing board and made the Address type prefix aware. This lead to some far reaching changes that I am listing here:

  1. I have added a deprecated = true flag to the astria::primitive::v1::Address::inner field.
  2. protobuf Addresses with an inner field set are assumed to have "astria" as their prefix.
  3. Address::inner and Adress::bech32m are mutually exclusive: only one may be set.
  4. When going from the common Address type to the protobuf Address message type, only bech32m is populated, inner is left empty.

All services assume a prefix of "astria", but it will be easy to make that configurable.

@@ -147,28 +140,28 @@ impl VerificationKey {
// Silence the clippy lint because the function body asserts that the panic
// cannot happen.
#[allow(clippy::missing_panics_doc)]
pub fn address(&self) -> &Address {
self.address.get_or_init(|| {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the memoization for the time being. We can bring it back later.

@SuperFluffy SuperFluffy requested a review from joroshiba June 7, 2024 09:26
@@ -961,7 +961,7 @@ impl App {
/// Executes a signed transaction.
#[instrument(name = "App::execute_transaction", skip_all, fields(
signed_transaction_hash = %telemetry::display::base64(&signed_tx.sha256_of_proto_encoding()),
sender = %signed_tx.verification_key().address(),
sender = %telemetry::display::base64(&signed_tx.verification_key().address_bytes()),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this display as bech32?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't right now because all we have is the sender (and hence the verification key), but no prefix, and hence no bech32m.

I am not sure how to address this at this point.

@@ -62,13 +62,16 @@ impl PartialOrd for TransactionPriority {
pub(crate) struct EnqueuedTransaction {
tx_hash: [u8; 32],
signed_tx: Arc<SignedTransaction>,
address: Address,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems weird, is this for caching purposes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So signed_tx.verification_key().address() was used somewhere in this mempool module - I would need to read the code again, but basically I have replaced all instances of .address() by this Address. Maybe that's actually unnecessary and the new address_bytes() would be sufficient.

@SuperFluffy SuperFluffy enabled auto-merge June 7, 2024 20:14
@SuperFluffy SuperFluffy added this pull request to the merge queue Jun 7, 2024
Merged via the queue into main with commit ab8705f Jun 7, 2024
41 checks passed
@SuperFluffy SuperFluffy deleted the superfluffy/bech32-addresses branch June 7, 2024 20:26
steezeburger added a commit that referenced this pull request Jun 10, 2024
* main:
  fix: ignore RUSTSEC-2021-0139 (#1171)
  chore(sequencer-relayer)!: remove functionality to restrict relaying blocks to only those proposed by a given validator (#1168)
  chore(metrics): update `metric_name` macro to handle a collection of names (#1163)
  fix(bridge-withdrawer): skip linting generated contract code (#1172)
  fix(core, sequencer): prefix removal source non-refund ics20 packet (#1162)
  chore(docs): add sequencer-relayer doc to specs (#1126)
  feat(bridge-withdrawer): sync logic (#1165)
  chore(withdrawer): replace contracts with `astria-bridge-contracts` submodule (#1164)
  feat(sequencer)!: implement bridge sudo and withdrawer addresses (#1142)
  feat(sequencer): implement refund to rollup logic upon ics20 transfer refund (#1161)
  feat(bridge-withdrawer): bridge withdrawer startup (#1160)
  feat(core, proto)!: add bech32m addresses (#1124)
  feat(withdrawer): bridged ERC20 token withdrawals (#1149)
  feat(sequencer-relayer)!: add chain IDs for sequencer and Celestia to config env vars (#1063)
  test(bridge-withdrawer): add submitter tests (#1133)
  chore: bump penumbra deps (#1159)
  feat(sequencer): implement `bridge/account_last_tx_hash` abci query (#1158)
  fix(withdrawer): use block subscription in batcher; send to destination_chain_address (#1157)
  fix(withdrawer): update AstriaWithdrawer to check that withdrawal value is sufficient (#1148)
  chore(ci): build bridge withdrawer images (#1156)
github-merge-queue bot pushed a commit that referenced this pull request Jun 26, 2024
## Summary
This patch allows configuring the base address prefix in sequencer's
genesis file and enforces this prefix in all actions.

Similar to the native fee, the base prefix is set once during
`init-chain` and is then available globally and never changed.

## Background
#1124 changed astria addresses
from opaque bytes to bech32m addresses, which themselves are encoded as
strings on the wire. Where previously sequencer implicitly assumed that
all addresses were `"astria"` prefixed bech32m addresses, this is now
enforced.

## Changes
- Update sequencer `GenesisState` to use the canonical serde
implementation of all `astria-core` types.
- Add a field `.address_prefixes.base` to the `GenesisState`.
- Ensure that all addresses in `GenesisState` are consistenst with the
prefix.
- Inject the genesis base address prefix into sequencer's global state.
- Add a check for the global address prefix to all sequencer actions
that carry a `astria.primitive.v1.core.Address` (this is done via
`AppHandler::check_stateless`). These are specifically:
    - `TransferAction`
    - `SudoAddressChangeAction`
    - `BridgeLockAction`
    - `BridgeSudoChangeAction`
    - `BridgeUnlockAction`
    - `InitBridgeAccountAction`
    - `IbcRelayerChangeAction`
- Slightly change all storage keys that use addresses to be explicit
about using bytes and provide snapshot tests (specifically in
`accounts::state_ext`, `bridge::state_ext`, `ibc::state_ext`)
- Removed: unsigned transaction parameters no longer require a bech32m
chain ID name
- Update composer, bridge-withdrawer to have a configurable address
prefix:
    - `ASTRIA_BRIDGE_WITHDRAWER_SEQUENCER_ADDRESS_PREFIX`
    - `ASTRIA_COMPOSER_SEQUENCER_ADDRESS_PREFIX`
- Update all `astria-cli` commands to take a configurable prefix.

## Testing
+ Update all tests and ensure they still run.
+ Add tests for genesis construction.
+ Add genesis snapshot tests.
+ Add snapshots tests for IBC denoms (to accompany the genesis snapshot)

## Breaking Changelist
This change is breaking at the network level requiring sequencer
re-genesis. Non-bech32m addresses in actions are now rejected, as well
as addresses that have a prefix other then the one set at genesis. In
addition, the storage key for all collections involving an address have
changed.

---------

Co-authored-by: Jordan Oroshiba <jordan@astria.org>
joroshiba pushed a commit that referenced this pull request Jun 26, 2024
## Summary
Removes the non-bech32m address bytes field.

## Background
The change introduced in #1124
is a breaking change that ripples through the rest of the Astria stack.
While in principle we can keep the non-bech32m address around for
backward compatibility, in practice it's cleaner to regenesis.

## Changes
- Remove `astria.primitive.v1.Address.inner`, reserving its number and
name.

## Testing
Updates and removed all unit tests. All blackbox tests that use
addresses in some form still work.

## Breaking Changelist
Since this is protobuf breaking it is also network breaking.
github-merge-queue bot pushed a commit that referenced this pull request Sep 4, 2024
## Summary
Added a lazily-initialized field `address_bytes` to `VerificationKey`.

## Background
Testing showed that `address_bytes` was called multiple times on a given
`VerificationKey` (up to 11 times in some cases). Each time the key's
bytes were being hashed, so this change ensures that hashing only
happens once for a given verification key instance.

Note that this was implemented previously in #1111 and was then reverted
in #1124. However, when reverted, the manual impls of `PartialEq`, `Eq`,
`PartialOrd`, `Ord` and `Hash` were left as-is, as were the unit tests
for these. Hence this PR doesn't need to make any changes to these trait
impls or tests.

## Changes
- Added `address_bytes: OnceLock<[u8; ADDRESS_LEN]>` to
`VerificiationKey`.

## Testing
No new tests required.  

## Related Issues
Closes #1351.
jbowen93 pushed a commit that referenced this pull request Sep 6, 2024
## Summary
Added a lazily-initialized field `address_bytes` to `VerificationKey`.

## Background
Testing showed that `address_bytes` was called multiple times on a given
`VerificationKey` (up to 11 times in some cases). Each time the key's
bytes were being hashed, so this change ensures that hashing only
happens once for a given verification key instance.

Note that this was implemented previously in #1111 and was then reverted
in #1124. However, when reverted, the manual impls of `PartialEq`, `Eq`,
`PartialOrd`, `Ord` and `Hash` were left as-is, as were the unit tests
for these. Hence this PR doesn't need to make any changes to these trait
impls or tests.

## Changes
- Added `address_bytes: OnceLock<[u8; ADDRESS_LEN]>` to
`VerificiationKey`.

## Testing
No new tests required.  

## Related Issues
Closes #1351.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
composer pertaining to composer core pertaining to the astria-core crate proto pertaining to the Astria Protobuf spec sequencer pertaining to the astria-sequencer crate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

change addresses to bech32
3 participants