Skip to content

Conversation

@Rajil1213
Copy link
Contributor

Description

This PR adds the foundational structures for the core bridge implementation as it is supposed to work in devnet. This includes the core bridge types, traits and some very basic implementation outlines (see the operator::Execute trait). Much of this is still a work in progress and far from perfect but should be a good enough starting point for the rest of the implementation.

The following traits will be covered in separate PRs:

  • Bridge client database traits for checkpointing and signature aggregation (EXP-158)
  • Bridge transaction assembly (EXP-128)

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature/Enhancement (non-breaking change which adds functionality or enhances an existing one)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactor

Checklist

  • I have performed a self-review of my code.
  • I have commented my code where necessary.
  • I have updated the documentation if needed.
  • My changes do not introduce new warnings.
  • I have added tests that prove my changes are effective or that my feature works.
  • New and existing tests pass with my changes.

Related Issues

EXP-83

Notes for Reviewers

A lot of files have been changed, most of which are new ones. So, it should be okay to squash-merge this PR so as to avoid rebasing hell for others.

@Rajil1213 Rajil1213 self-assigned this Aug 14, 2024
@codecov
Copy link

codecov bot commented Aug 14, 2024

Codecov Report

Attention: Patch coverage is 36.74497% with 377 lines in your changes missing coverage. Please review.

Project coverage is 57.43%. Comparing base (61363b5) to head (24fd3df).
Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
bin/bridge-client/src/rpc_server.rs 0.00% 57 Missing ⚠️
crates/bridge-sig-manager/src/state.rs 0.00% 49 Missing ⚠️
crates/primitives/src/bridge.rs 0.00% 43 Missing ⚠️
crates/primitives/src/l1.rs 84.55% 40 Missing ⚠️
crates/bridge-tx-builder/src/builder.rs 0.00% 29 Missing ⚠️
crates/bridge-tx-builder/src/deposit.rs 0.00% 28 Missing ⚠️
bin/bridge-client/src/main.rs 0.00% 25 Missing ⚠️
...ates/bridge-exec/src/withdrawal_handler/handler.rs 0.00% 15 Missing ⚠️
crates/bridge-sig-manager/src/signature.rs 0.00% 13 Missing ⚠️
bin/bridge-client/src/args.rs 0.00% 12 Missing ⚠️
... and 20 more
@@            Coverage Diff             @@
##           master     #230      +/-   ##
==========================================
- Coverage   58.20%   57.43%   -0.78%     
==========================================
  Files         133      157      +24     
  Lines       14404    14977     +573     
==========================================
+ Hits         8384     8602     +218     
- Misses       6020     6375     +355     
Files with missing lines Coverage Δ
crates/rpc/types/src/types.rs 0.00% <ø> (ø)
bin/bridge-client/src/errors.rs 0.00% <0.00%> (ø)
crates/bridge-exec/src/book_keeping/errors.rs 0.00% <0.00%> (ø)
crates/bridge-exec/src/config/errors.rs 0.00% <0.00%> (ø)
crates/bridge-exec/src/deposit_handler/errors.rs 0.00% <0.00%> (ø)
...rates/bridge-exec/src/withdrawal_handler/errors.rs 0.00% <0.00%> (ø)
crates/primitives/src/buf.rs 78.57% <0.00%> (-0.48%) ⬇️
crates/primitives/src/errors.rs 0.00% <0.00%> (ø)
crates/rpc/api/src/lib.rs 0.00% <0.00%> (ø)
crates/state/src/bridge_state.rs 15.38% <0.00%> (+0.16%) ⬆️
... and 21 more

... and 2 files with indirect coverage changes

Copy link
Contributor

@delbonis delbonis left a comment

Choose a reason for hiding this comment

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

I have some concerns about this architecture pushing impl details into this deeply nested trait hierarchy.

What this is actually doing is making it a requirement that all of the logic is bottled into a single type and we're implicitly exposing implementation details by making the traits dependent on each other. It also means that it's hard to test just a subset of the functionality of part of the ball of state, because then you'd have to reimplement that functionality on another type that only implements the traits that you're testing. This is some really scary coupling because it's also a lot more implicit and the components are all flattened out into a one type.

Especially, for example, if you wanted write unit tests for the middle of 3 layers of the traits, it would be fairly straightforward to peel off the top layer of the impl, but less obvious how to abstract out the underlying layer. Each of these traits should be split out into its own system so it can be tested in isolation independently of any others, and (if need be) mocking out its dependencies. The low-level logic for signing transactions should be outside of this trait system, so we can test it directly without the need for mocking anything.

I would go back to the drawing board on the internal architecture of the operator client. Start from the bottom up with the core loop of polling/tracking for duties, only implement things concretely and then abstract things out. When it comes time to do transaction assembly, build the transaction assembly first and then figure out how to integrate it. I have some design guidelines in a few of the bridge-related tickets that might help frame it better.

@Rajil1213
Copy link
Contributor Author

Rajil1213 commented Aug 15, 2024

@delbonis

This is some really scary coupling because it's also a lot more implicit and the components are all flattened out into a one type.

Yeah, there are distinct functionalities here such as the deposit handling is very different from the withdrawal handling. So having separate traits made sense in that regard. But ultimately, it is the bridge client that performs all the duties which means all the traits are coupled together and that is just bad.

Each of these traits should be split out into its own system so it can be tested in isolation independently of any others, and (if need be) mocking out its dependencies

How would this work? Are you saying, there'd be distinct types that implement each of these traits? A DepositHandler struct that implements the HandleDeposit trait? I could make that work but it would need to share at least the rpc client and a database handle with the WithdrawalHandler.

The low-level logic for signing transactions should be outside of this trait system, so we can test it directly without the need for mocking anything.

Yeah this is the case even now. The express-bridge-txm crate exists at the lowest-level of the crate-hierarachy. It depends only on the express-primitives crate and all the other bridge crates depend on it.

I would go back to the drawing board on the internal architecture of the operator client. Start from the bottom up with the core loop of polling/tracking for duties, only implement things concretely and then abstract things out. When it comes time to do transaction assembly, build the transaction assembly first and then figure out how to integrate it. I have some design guidelines in a few of the bridge-related tickets that might help frame it better.

The approach I took was to go the other way around -- start with the high-level end-to-end structure and then, peeling back the layers to the point where there is a function that needs to be implemented later. Of course, things are likely to change when we actually start implementing the guts of the client. Do you think the scaffolding itself should change beyond refactorings discussed above? For example, I see the individual deposit and withdrawal traits sticking around even though how they compose together might change.

@delbonis
Copy link
Contributor

Are you saying, there'd be distinct types that implement each of these traits? A DepositHandler struct that implements the HandleDeposit trait? I could make that work but it would need to share at least the rpc client and a database handle with the WithdrawalHandler.

Yes this is how this is normally done in Rust and it's how we do it in the main rollup client codebase.

start with the high-level end-to-end structure and then, peeling back the layers to the point where there is a function that needs to be implemented later. Of course, things are likely to change when we actually start implementing the guts of the client.

This issue with this is we don't know if we've taken the right approach with some until we've implemented it, and already we've baked in a fairly rigid relationship between the different components. If you can even really call them separate components, since it'd all have to be on of a single type.

Do you think the scaffolding itself should change beyond refactorings discussed above? For example, I see the individual deposit and withdrawal traits sticking around even though how they compose together might change.

Will DM for further discussion on these points.

Rajil1213 added a commit that referenced this pull request Aug 19, 2024
This is based on the discussion in PR
[#230](#230)
@Rajil1213 Rajil1213 force-pushed the feat/168-create-basic-scaffolding-for-bridge-core-impl branch from 05d1d0f to 3cce9c2 Compare August 20, 2024 07:56
Rajil1213 added a commit that referenced this pull request Aug 20, 2024
This is based on the discussion in PR
[#230](#230)
@Rajil1213 Rajil1213 force-pushed the feat/168-create-basic-scaffolding-for-bridge-core-impl branch 2 times, most recently from 10d5690 to eccabfe Compare August 20, 2024 20:28
@Rajil1213 Rajil1213 force-pushed the feat/168-create-basic-scaffolding-for-bridge-core-impl branch from 190d76a to 794feb2 Compare August 22, 2024 08:04
Copy link
Contributor

@delbonis delbonis left a comment

Choose a reason for hiding this comment

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

I know this PR is somewhat on hold pending lower-level impls but I have some more comments since there's been some iteration on it.

Copy link
Contributor

@bewakes bewakes left a comment

Choose a reason for hiding this comment

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

Just a few queries.

@Rajil1213 Rajil1213 mentioned this pull request Aug 23, 2024
11 tasks
@Rajil1213 Rajil1213 force-pushed the feat/168-create-basic-scaffolding-for-bridge-core-impl branch from 9e83d24 to bee83b3 Compare September 5, 2024 18:26
@Rajil1213
Copy link
Contributor Author

Rajil1213 commented Sep 5, 2024

Okay, I've made a final round of changes on this PR. Also brought in a few traits and primitives from #269 (some of it might change but nothing a rebase cannot fix later). All the CI checks are passing and it's up to date with master.

@storopoli
Copy link
Member

I think we can merge this and start working on the fresh tickets that are in this sprint and unlocked by this PR.

Copy link
Member

@storopoli storopoli left a comment

Choose a reason for hiding this comment

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

ACK 24fd3df
But, please squash merge these 60 commits

@delbonis delbonis merged commit ad78104 into master Sep 5, 2024
@storopoli storopoli deleted the feat/168-create-basic-scaffolding-for-bridge-core-impl branch September 5, 2024 20:01
neon-smith-tsmmn added a commit to neon-smith-tsmmn/alpen that referenced this pull request Sep 27, 2025
* feat(bridge): create basic scaffolding (WIP)

* refactor: move bridge-db to db

* chore(bridge): add main fn stubs

* chore(bridge): add bridge binaries to project Cargo.toml

* refactor: move all binaries to bin

This is as per [cargo package
layout](https://doc.rust-lang.org/cargo/guide/project-layout.html)

* fix: correct typo

* refactor: rename rpc-service to rpc-api for consistency

* fix: resolve merge conflict in db crate

* fix: rename bridge crates to use express

* feat(bridge-rpc): create bridge rpc traits

* refactor(bridge-rpc): move bridge-rpc-api inside rpc subdirectory

* refactor(bridge-rpc): move deposit structs into txm and split rpc

* feat(bridge-rpc): bootstrap bridge client in operator mode via stubs

* refactor: remove unnecessary RPCs based on new archi

* fix: remove duplicates after rebase

* feat(bridge-rpc): add basic traits/types

* fix(bridge-exec): move duty to bridge-state to remove cyclic deps

* feat(bridge-txm): create deposit and reimbursement traits

* refactor(bridge-txm): update l2 address type for multiple els

* feat(bridge-exec): lay out types/traits with some basic impl

* revert: move original bins back to root level

Reverts 0efa8579 so as to reduce rebase hell for others.

* fix: udpate struct locations after rebase

* fix(primitives): convert error type for borsh

* refactor(bridge): improve types/traits

This is based on the discussion in PR
[#230](alpenlabs/alpen#230)

* refactor(bridge-rpc): rename `BridgeRpcImpl` to `BridgeRpc`

* refactor(bridge-state): update and use output types for withdrawal

* refactor(bridge-txm): use consistent naming

The `signature_handler` is really a manager and not a handler. The crate
is called `express-bridge-txm`, so the name of the directoy should be
the same.

* refactor(bridge): add `P2PMessage` to duties and remove `DepositRequest`

* chore: reorganize workspace members list

* chore(primitives): remove duplicate deps, add anyhow

* refactor(primitives, state): add TweakedTrKey type for `WithdrawalOutput`

* refactor(primitives): rename `TweakedTrPubkey` to `XOnlyPk`

* refactor(bridge-rpc): update rpc trait

* refactor(bridge-txm): add pubkeys arg to construct deposit tx

* refactor(bridge-exec): remove redundant error display

* refactor(bridge-exec): use AsRef<Path> instead of PathBuf

* refactor(bridge-state): use XOnlyPk for dest_pk

* chore: sort workspace members

* refactor(bridge-client): convert `mode` to positional arg

* refactor(bridge-rpc): rename method

* refactor(bridge-exec): remove challenger exec

* fix(bridge-exec): convert methods to pure funcs and remove relay methods

* refactor(bridge-exec): remove pk path from config

* refactor: implement Deref/DerefMut for BitcoinAmount

* refactor: convert version to an enum

* refactor(bridge-exec): use NetworkChecked addr

* Revert "refactor: implement Deref/DerefMut for BitcoinAmount"

This reverts commit 96aec67910f0f0f1d2f2ce5530e024c741adf2e7.

* chore: cleanup unused imports

* fix: resolve rebase issue

* refactor(bridge-client): replace clap with argh

:(

* chore(bridge-rpc): add TODO to refactor RPCs

* chore(withdrawal-handler): update PR reference

* refactor(bridge-txm): split crate into builder and signer

* refactor(bridge-exec): change signatures based on new types

* docs(bridge-client): add note on using `express-tasks`

* refactor(bridge-rpc): use new types

* refactor(bridge-state): change type definitions for consistency

* refactor(bridge-exec): use proper error messages

* feat(primitives): add bridge primitives

* feat(primitives): add concrete error types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants