-
Notifications
You must be signed in to change notification settings - Fork 129
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
Make relay CLI generic #849
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 didn't have the brainpower to look at this as in depth as I wanted to today. I do have a couple of thoughts though:
- My gut says no to the macros, but it might just be PTSD from the Substrate ones
- Please don't refactor the whole CLI in this PR, the diff is already large enough 😄
I'll also try and do some thinking about how we can architect this so that multi-network support isn't such a pain
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.
In general it looks all right.
Before we merge this I would like to see the TODOs have issues attached to them so any of us can pick them up and help with this effort.
I'll take another look after this leaves the draft state.
spec_name: sp_version::create_runtime_str!("westend"), | ||
impl_name: sp_version::create_runtime_str!("parity-westend"), | ||
authoring_version: 2, | ||
spec_version: 50, |
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.
Do we need to make sure we keep up with the spec_version
changes in the Westend runtime?
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.
Yup, but I think it will be covered by a test in Polkadot repo. Alternatively the relayer could query a running node and make sure this matches.
relays/bin-substrate/src/cli/mod.rs
Outdated
|
||
/// Bridge Message Payload type. | ||
/// | ||
/// TODO [ToDr] This should be removed in favour of target-specifc types. |
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.
Can you elaborate on what you mean here?
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.
In case we have multiple bridges the MessagePayload
type will be different.
For instance for RialtoToWestend
and RialtoToMillau
the MessagePayload
and encode_call
will look quite differently.
The TODO is there cause it's not the right way to abstract the code, however since right now we don't have a chain with two bridges that include MessageLanes it's good enough, but I already have an idea how to improve it, hence the TODO.
|
||
/// Numeric value of SS58 format. | ||
fn ss58_format() -> u16; | ||
|
||
/// Parse CLI call and encode it to be dispatched on this specific chain. | ||
fn encode_call(call: crate::rialto_millau::cli::Call) -> Result<Self::Call, String>; |
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.
Shouldn't this call type be generic?
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.
If you mean the fact that it has rialto_millau
in the module path, then yes. The Call
is in fact already generic, but I wanted to avoid moving all the types to top-level cli/mod.rs
file just yet. Will be fixed later when the rialto_millau
module is dissolved.
@@ -19,68 +19,24 @@ | |||
use frame_support::weights::Weight; |
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.
With your follow up PRs this file will end up being replaced by an enum + macro combo, right?
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.
Each sub-command will have it's own module in src/cli/
and there is going to be less duplication. I expect the entire file to be removed after the refactor is finished.
} | ||
} | ||
} | ||
|
||
async fn run_relay_messages(command: cli::RelayMessages) -> Result<(), String> { | ||
match command { | ||
cli::RelayMessages::MillauToRialto { |
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.
This will be macro-ified too, right?
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.
Yup. I initially started off with trying to extract the common parts, so that both branches look the same. After that I started moving the code to make it generic, but these commands are still left to do.
/// | ||
/// This will change the `ss58format` of the account to match the requested one. | ||
/// Note that a warning will be produced in case the current format does not match | ||
/// the requested one, but the conversion always succeeds. | ||
pub fn enforce_chain<T: AccountChain>(&mut self) { | ||
pub fn enforce_chain<T: CliChain>(&mut self) { |
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.
Looking back at it I'm not sure if enforce
is the right word to use here, considering that even if the expected format doesn't match this call still "succeeds" (by converting to the right address format)
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.
What do you suggest then? force_convert::<Rialto>()
?
} | ||
} | ||
|
||
impl AccountChain for Rialto { | ||
const NAME: &'static str = "Rialto"; | ||
impl CliChain for Westend { |
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.
This impl
should probably have an issue attached to 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.
How so? We don't really support Westend, the fact that we can't implement all methods means the abstraction is not fine-grained enough (i.e. there are sub-commands that are not even available for westend, but the trait is shared between sub-commands), but I would rather go with coarse abstraction and later on split it if it turns out to be correct.
Co-authored-by: Hernando Castano <[email protected]>
/// A call to the Rialto Bridge Messages pallet to send a message over the bridge. | ||
RialtoSendMessage { | ||
// TODO [#853] Support multiple bridges. | ||
/// A call to the specific Message Lane pallet to send a message over the bridge. |
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.
Quote from #853:
Currently the Call CLI enum, supports BridgeSendMessage variant. However in case there are multiple bridges on one source chain, we need to specify what Target chain we want to send the message to.
I'm a bit confused now - I thought that this variant is to call over the bridge the other bridge (deployed on the target chain) to send other message. So it may be Source --- (M1) ---> Target --- (M2) ---> Source
or Source1 --- (M1) ---> Target --- (M2) ---> Source2
iiuc. So the quote should be the "multiple bridges on the target chain", no?
I guess it was introduced in the PR about printing encoded messages, so it isn't actually used in messages sending. In practice it is only used by the encode-call
subcommand. But since it is available to the send-message
command as well, maybe it worth at least to expand docs a bit - e.g instead of "specific Message Lane pallet" say "Message Lane pallet on the target chain", for payload change it to the "encoded Call of the source chain", etc.
P.S.: 'Message Lane pallet' is also changed to 'Messages pallet' everywhere ;)
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.
Yes, that's a good point. Indeed I was thinking about it from the encode-call
perspective, I'll update the docs.
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.
For me, this goes into the right direction. If anything, I want to see more of this approach. My kind of ideal in the end would be having a bridge
procedural macro, similar to the pallet
macro. Basically generating a specific bridge implementation, batteries (CLI) included.
So I 'approve' but keep this as comment only.
} | ||
|
||
macro_rules! select_bridge { | ||
($bridge: expr, $generic: tt) => { |
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.
generic
is generic here in the sense that it can be an arbitrary closure?
} | ||
|
||
macro_rules! select_bridge { | ||
($bridge: expr, $generic: tt) => { |
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.
Same here w.r.t. to generic
.
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.
It's actually not a closure, but a piece of arbitrary code that will use generic parameters type Source =/ type Target =
that is set in the particular branch of match
statement.
@@ -42,6 +42,19 @@ pub enum Error { | |||
Custom(String), | |||
} | |||
|
|||
impl std::error::Error for Error { |
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.
Perhaps we can agree on using the thiserror
/ anyhow
combo for all our errors and start migrate towards this.
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.
Yes, logged here #857
* ERCSC * update * Update Substrate & Polkadot Co-authored-by: doordashcon <[email protected]> Co-authored-by: Bastian Köcher <[email protected]>
* Start generalizing rialto-millau commands. * cargo fmt --all * Introduce generic balance. * Unify message payloads. * cargo fmt --all * init - generic * Attempt to unify send message. * Start moving things around. * cargo fmt --all * Move init-bridge. * cargo fmt --all * Improve UX of bridge argument. * Fix clippy. * Fix docs and scripts. * Add docs. * Apply suggestions from code review Co-authored-by: Hernando Castano <[email protected]> * Fix copyright. * Add issue numbers. * More todos. * Update comments. Co-authored-by: Hernando Castano <[email protected]>
* Start generalizing rialto-millau commands. * cargo fmt --all * Introduce generic balance. * Unify message payloads. * cargo fmt --all * init - generic * Attempt to unify send message. * Start moving things around. * cargo fmt --all * Move init-bridge. * cargo fmt --all * Improve UX of bridge argument. * Fix clippy. * Fix docs and scripts. * Add docs. * Apply suggestions from code review Co-authored-by: Hernando Castano <[email protected]> * Fix copyright. * Add issue numbers. * More todos. * Update comments. Co-authored-by: Hernando Castano <[email protected]>
The purpose of this PR is to make it easy to add new chains. It's a follow up on #734.
Initially I thought that we can orient the CLI around various bridges/chains and simply duplicate the code responsible for handling the CLI commands (see
src/rialto_millau
module). Later on I figure that it's quite a lot of code to duplicate, but was still hoping that we can get around this by using some macros.However since the code is split into multiple files it's not that trivial to macro-ify the code + it heavily reduces readability and ability to debug errors.
This PR introduces a different approach, where we try to keep the code generic enough so that a lot of code can be shared without introducing a macro, but all the things that are difficult to make generic, or depend on particular sourceNetwork-targetNetwork bridge pair are resolved via macro-shared code.
The most important part of the PR is the
select_bridge!
macro, which allows us to write some$generic
code, without actually naming all of the types (which would be hard).I've refactored
RelayHeaders
andInitBridge
for now, but since the PR is getting quite big, I've decided to make it a draft and let you decide if I should continue or if we rather review & merge like this and change the rest in a follow up PR.There is a bunch of unaddressed and unassigned
TODOs
for now, and most likely some bash scripts require updating as well.Follow up tasks:
source_*
target_*
CLI methods (e.g. addInto<ConnectionParams>
)