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

Reworked pallets for XCMv3 #791

Merged
merged 38 commits into from
Apr 7, 2023
Merged

Reworked pallets for XCMv3 #791

merged 38 commits into from
Apr 7, 2023

Conversation

vgeddes
Copy link
Collaborator

@vgeddes vgeddes commented Mar 23, 2023

Changes:

  • Channels renamed to Queues
    • OutboundChannel -> OutboundQueue
    • InboundChannel -> InboundQueue
  • Inbound and Outbound queue pallets are now in separate crates
  • Nonces or "Lanes" in queues are know identified by parachain ID rather than parachain MultiLocation
  • In the solidity unit tests, TestToken replaced with WETH9 (Ether wrapped in an ERC20 token).

I also disabled the parachain message relayer. It still needs to be updated to be compatible with these refactorings over the past month.

The ethereum execution message relayer is operational, but still needs more work to be production ready.

Fixes: SNO-396, SNO-402

@vgeddes vgeddes changed the base branch from main to vincent/remove-snowbridge-parachain March 23, 2023 16:39
Base automatically changed from vincent/remove-snowbridge-parachain to main March 24, 2023 17:29
Copy link
Contributor

@alistair-singh alistair-singh 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 so far!

@vgeddes vgeddes marked this pull request as ready for review April 4, 2023 18:20
Copy link
Contributor

@alistair-singh alistair-singh left a comment

Choose a reason for hiding this comment

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

LGTM!


/// Weight information for extrinsics in this pallet
type WeightInfo: WeightInfo;

type Reward: Get<BalanceOf<Self>>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Non blocking: Parity's bridge implementation for rococo-wococo. The fee is configured more dynamically. It still requires governance to change, but it is decoupled from the runtime. It might be useful for us to decouple updating fees from runtime updates as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Nice catch, added ticket in https://linear.app/snowfork/issue/SNO-402

@@ -9,7 +9,7 @@ echo 'Running pre-commit hook...'
chronic typos .

# lint and format for core contracts and typescript codes
(cd core && chronic pnpm lint && chronic pnpm format)
(cd core && chronic pnpm lint)
Copy link
Contributor

@yrong yrong Apr 7, 2023

Choose a reason for hiding this comment

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

Anything break so we remove pnpm format here? AFAIK it will just run the underlying forge fmt so should be fine?

Copy link
Collaborator Author

@vgeddes vgeddes Apr 7, 2023

Choose a reason for hiding this comment

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

I found it a bit confusing for a pre-commit hook to alter the code automatically. I disabled it for that reason.

I would rather we enable "Format on Save" option in VS code. For Solidity:

{
		"[solidity]": {
			"editor.formatOnSave": true,
			"editor.defaultFormatter": "JuanBlanco.solidity" 
		},
		"solidity.formatter": "forge",
}

Then at least we know what changes we are committing when we run "git commit"

"cumulus/**"
"cumulus/**",
"smoketest/src/parachains",
"smoketest/src/contracts",
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have these smoketest scripts ready? can't find in this PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I experimented with writing smoketest scripts in Rust, but deleted the experiment as they were too slow to compile, and Rust's test frameworks are not as good as Golang's.

But see this in case we ever want to generate Rust clients for our pallets and contracts: https://www.notion.so/snowfork/Rust-bindings-b6566f13dd894ac1ac9a347f9bbbf160?pvs=4

<LatestVerifiedBlockNumber<T>>::set(block_number);
// Reward relayer from the sovereign account of the destination parachain
let dest_account = envelope.dest.into_account_truncating();
T::Token::transfer(&who, &dest_account, T::Reward::get(), Preservation::Expendable)?;
Copy link
Contributor

@yrong yrong Apr 7, 2023

Choose a reason for hiding this comment

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

Seems a little confused. Is the transfer logic here correct or just some temp placeholder? Is impl supposed to be some xcm call sent to asset chain?

Copy link
Contributor

@yrong yrong Apr 7, 2023

Choose a reason for hiding this comment

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

And also seems we remove the previous logic <LatestVerifiedBlockNumber<T>>::set(block_number); Is it safe to remove? I would assume we still need some scanner logic to find the unsynced messages and IMO probably useful to narrow the scope of scan down with the checkpoint.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Seems a little confused. Is the transfer logic here correct or just some temp placeholder? Is impl supposed to be some xcm call sent to asset chain?

That's just for rewarding the relayer. We definitely still need to implement the routing of the XCM call.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I temporarily removed the LatestVerifiedBlockNumber logic because the checkpoint logic in the relayer didn't work with multiple lanes (i.e each parachain has its lane and nonce).

So I am may add it back once I rewrite the relayer properly.

}

err = messages.Sync(ctx, eg)
sub, err := contract.WatchMessage(&opts, messages, [][]byte{key})
Copy link
Contributor

@yrong yrong Apr 7, 2023

Choose a reason for hiding this comment

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

So to confirm, WatchMessage here will only subscribe to the latest message events and we still need some scanner logic to find unsynced messages? Also some related comments here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah, this is just a very simple, incomplete implementation that allows us to test the on-chain code. We will need to rewrite it in a future PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Also we may have to modify the execution message relayer to support the optimizations we talked about on slack (execution headers, etc).

Copy link
Contributor

@yrong yrong Apr 7, 2023

Choose a reason for hiding this comment

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

And not sure even if WatchMessage will work here because we can not verify the execution block if it is not finalized in beacon chain yet. so maybe the previous FilterMessage with FilterOpts(i.e. a bounded range) make more sense.
The start of the range should be the LatestVerifiedBlockNumber(though revamp required for multiple lanes support) in message layer and the end is the LatestExecutionHeaderState(also need to optimize as discussed) in beacon layer?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I check here that the execution header has already been imported: https://github.com/Snowfork/snowbridge/pull/791/files#diff-ba222152cf61a695305ad44e12ccc757ffa95a1f6c1c8ee698e21a7650155229R102

But yes, when we re-implement the relayer properly, we will likely use FilterMessage along with the following algorithm:

  1. Check message nonce on Parachain side
  2. Check message nonce on Ethereum side
  3. Compare nonces to determine which messages need to be synced.
  4. Scan Ethereum blocks using FilterMessage to find the OutboundQueue.Message event logs. This is fast, as Ethereum indexes events, so we can almost lookup event logs by nonce:
    event Message(ParaID indexed dest, uint64 indexed nonce, bytes payload);

Then as you say, we will use LatestExecutionHeaderState to check that execution header has been imported first.

@vgeddes vgeddes merged commit 2922b97 into main Apr 7, 2023
@vgeddes vgeddes deleted the vincent/channels-v3 branch April 7, 2023 12:10
@vgeddes vgeddes restored the vincent/channels-v3 branch April 7, 2023 14:54
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.

3 participants