- 
                Notifications
    
You must be signed in to change notification settings  - Fork 21
 
EXP-83 Create basic scaffolding for bridge core impl #230
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
EXP-83 Create basic scaffolding for bridge core impl #230
Conversation
There was a problem hiding this 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.
          
 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. 
 How would this work? Are you saying, there'd be distinct types that implement each of these traits? A  
 Yeah this is the case even now. The  
 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.  | 
    
          
 Yes this is how this is normally done in Rust and it's how we do it in the main rollup client codebase. 
 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. 
 Will DM for further discussion on these points.  | 
    
05d1d0f    to
    3cce9c2      
    Compare
  
    10d5690    to
    eccabfe      
    Compare
  
    190d76a    to
    794feb2      
    Compare
  
    There was a problem hiding this 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.
There was a problem hiding this 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.
This reverts commit 96aec67.
9e83d24    to
    bee83b3      
    Compare
  
    | 
           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.  | 
    
| 
           I think we can merge this and start working on the fresh tickets that are in this sprint and unlocked by this PR.  | 
    
There was a problem hiding this 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
* 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
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::Executetrait). 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:
Type of Change
Checklist
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.