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

Statemine reserve location and universal alias #841

Merged
merged 7 commits into from
May 30, 2023

Conversation

alistair-singh
Copy link
Contributor

@alistair-singh alistair-singh commented May 22, 2023

Cumulus Companion: Snowfork/cumulus#27

Resolves: SNO-496

# Allow messages to be sent from ETH to Substrate.
add_universal_alias
# Allow NativeTokens contract to ReserveAssetDeposited xcm instruction.
add_reserve_location $(address_for NativeTokens)
Copy link
Collaborator

@vgeddes vgeddes May 23, 2023

Choose a reason for hiding this comment

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

I forgot to sync with you about this. The problem is that we can't use the contract address for NativeTokens as the reserve location. If we replace NativeTokens with an upgraded contract, that will break the config on Statemint.

Instead, since the reserve location is largely symbolic, I would just use a dummy address for now.

When BridgeHub forwards XCM messages to Statemint, we can make our router say these messages originated from the dummy address too (rather than from OutboundQueue.sol). Statemint will inspect the origin of incoming messages to ensure they are the owners of the assets in ForeignAssets pallet.

At some point in the next week or two, we can replace the dummy address with the address of a real contract in our stack. This will just be a do-nothing contract, with the only property being that it was deployed by us.

contract Snowbridge {}

Copy link
Contributor Author

@alistair-singh alistair-singh May 23, 2023

Choose a reason for hiding this comment

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

I was thinking that for upgrades we would just add the new NativeTokens contract address as a reserve location using the same add_reserve_location extrinsic, potentially even in the same call which sends the upgrade message across the bridge. The bridge-transfer pallet can have both versions of the contract added and can be run back to back. Once upgrade is complete we can remove the old contract address using remove_reserve_location extrinsic.

Do you see any problems with this approach?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could also use vault contracts as a reserve location as they live forever and actually hold funds. So maybe a better choice than a dummy address.

Copy link
Collaborator

@vgeddes vgeddes May 23, 2023

Choose a reason for hiding this comment

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

I was thinking that for upgrades we would just add the new NativeTokens contract address as a reserve location using the same add_reserve_location extrinsic, potentially even in the same call which sends the upgrade message across the bridge. The bridge-transfer pallet can have both versions of the contract added and can be run back to back. Once upgrade is complete we can remove the old contract address using remove_reserve_location extrinsic.

Do you see any problems with this approach?

There are various problem with this approach. We can only execute add_reserve_location, etc via governance proposal voted upon by the Polkadot community. It can take weeks to execute a governance proposal.

It makes smart contract upgrades, slower, more brittle. Since it requires two governance proposals: (1) Update the ethereum side, (2) update the polkadot side. Alternatively, if you combine the proposals, then if one subtask fails, you end up with inconsistent state which requires more governance proposals to fix.

Copy link
Collaborator

@vgeddes vgeddes May 23, 2023

Choose a reason for hiding this comment

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

We could also use vault contracts as a reserve location as they live forever and actually hold funds. So maybe a better choice than a dummy address.

Vault contracts are an internal implementation detail. I don't want to expose them in our public API, which could cause problems if ever change our design/implementation later down the line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah I see. I have created this issue to switch to a dummy address.
https://linear.app/snowfork/issue/SNO-450
I think we should defer this for now. While I am focusing on trying to get the round trip transfer done we can continue with using NativeTokens?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It won't work without a dummy address, and we need to update BridgeHub so that the XCM messages it sends to Statemint are seen as coming from a MultiLocation containing the dummy address as a junction.

Because the XCM config in Statemint/Westmint has this constraint:
https://github.com/paritytech/cumulus/pull/2013/files#diff-07287c62dd91150d975f7504bd14cc62d9889c44f7ba8ca44c30c03b05d5b071R383

https://github.com/paritytech/cumulus/blob/c167adde899a1a3818e19cf55dfe9a6b907bff63/parachains/pallets/bridge-transfer/src/impls.rs#L43

It checks that an asset has a multilocation that has the reserve location as a prefix.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

If we replace NativeTokens with an upgraded contract, that will break the config on Statemint.

Seems proxy pattern will fit well into this case, the proxy address of NativeTokens will not change when underlying logic contract upgraded. Another benifit with this pattern is storage isolation so no need for migration when upgrading.

Cons are as Vincent mentioned before a bit brittle and not easy to maintain. #801 (comment)

@alistair-singh alistair-singh force-pushed the alistair/statemine-reserve-location branch 2 times, most recently from a5a4751 to f8cf0da Compare May 24, 2023 19:24
@yrong
Copy link
Contributor

yrong commented May 25, 2023

@yrong
Copy link
Contributor

yrong commented May 25, 2023

Before running deposit funds into Statemint's sovereign account on BridgeHub:
5Ec4AhPZk8STuex8Wsi9TwDtJQxKqzPJRCH7348Xtcs9vZLJ
This is necessary to cover rewards for "execution message" relayers. Messages will be rejected if the account is empty.

How to trigger the Initial funding, is there a script for it?

@alistair-singh
Copy link
Contributor Author

alistair-singh commented May 25, 2023

https://github.com/Snowfork/snowbridge/blob/alistair/statemine-reserve-location/core/packages/test/scripts/send-xcm.sh

No I will remove.

How to trigger the Initial funding, is there a script for it?

I have added the parachain 1000 account into endowed accounts for now in my create tokens branch.

I would assume the entry point for running E2E test is from this file

That is correct however you would need to create a token first.

@alistair-singh alistair-singh force-pushed the alistair/statemine-reserve-location branch from f8cf0da to 320a351 Compare May 25, 2023 11:51
@yrong
Copy link
Contributor

yrong commented May 25, 2023

native_tokens
.lock(weth.address(), 0, recipient.into(), value1)
.value(1000)
.send()
.await
.unwrap()
.await
.unwrap()
.unwrap();
println!("receipt: {:#?}", receipt);
assert_eq!(receipt.status.unwrap().as_u64(), 1u64);

Nit: seems only checks receipt.status here, would it be better also connect to statemint and check token minted there as expected?

Copy link
Contributor

@yrong yrong left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Collaborator

@vgeddes vgeddes left a comment

Choose a reason for hiding this comment

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

+1

Though obviously we will need to select an appropriate reserve location that works for statemint.

@alistair-singh alistair-singh merged commit 0467d5b into main May 30, 2023
@alistair-singh alistair-singh deleted the alistair/statemine-reserve-location branch May 30, 2023 13:35
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