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

adjust liquidstaking on-chain part with xcm-transact #440

Closed
6 tasks done
mclyk opened this issue Aug 23, 2021 · 9 comments
Closed
6 tasks done

adjust liquidstaking on-chain part with xcm-transact #440

mclyk opened this issue Aug 23, 2021 · 9 comments
Assignees

Comments

@mclyk
Copy link
Contributor

mclyk commented Aug 23, 2021

Motivation

Since XCM v2 is onboarding, we should consider integrating with it in our liquidstaking design.

Suggested Solution

  • deploy westend relaychain and heiko parachain
  • do some research and test about transact
  • integrate with xcm-simulator in XCM test code
  • write document about xcm-v2
  • adjust the design of liquidstaking on-chain part
  • discuss with team
@mclyk mclyk self-assigned this Aug 23, 2021
@mclyk
Copy link
Contributor Author

mclyk commented Aug 23, 2021

Refer to #326
Bugs when test: #444 #445
Design about LiquidStaking include xcm/transact #502

@mclyk
Copy link
Contributor Author

mclyk commented Aug 25, 2021

Success: transact from parachain code, invoke relaychain system.remark
1 transact_remark_success.jpg

@mclyk
Copy link
Contributor Author

mclyk commented Aug 25, 2021

Failed: transact failed from parachain, invoke relaychain staking.bond
2 transact_failed_bond.jpg

@mclyk
Copy link
Contributor Author

mclyk commented Aug 25, 2021

Success: transact success from parachain via XCM message, invoke relaychain staking.bond
3 transact_success.jpg

@mclyk
Copy link
Contributor Author

mclyk commented Aug 26, 2021

Here is the xcm transact pallet with xcm-simulator:
https://github.com/MrPai/parallel/tree/release-v0.9.9/pallets/xcm

After testing, there may be some bugs about Encode/Decode in rust code. for example, when using 1_000_000 as an argument, decoding is ok, however, 1_000_000_000 leads the decoding wrong.

@mclyk
Copy link
Contributor Author

mclyk commented Sep 2, 2021

1. Concept

  • XCMP Cross-Chain Message Passing secure message passing between parachains.
  • VMP Vertical Message Passing message passing between the Relay-chain itself and a parachain.
    • UMP Upward Message Passing message passing from a parachain to the Relay-chain.
    • DMP Downward Message Passing message passing from the Relay-chain to a parachain.
  • Xcm Message Types
    Include all message types that can be delivered between relaychain and parachain, parachain and parachain.
    • WithdrawAsset
    • ReserveAssetDeposit
    • TeleportAsset
    • Transact
      This link will show more detailed types and info about the message, and here is the code.
  • MultiAsset
    Define what kind of asset could be effective in the current xcm message.
    • None
    • All
    • AllFungible
    • ConcreteFungible
      This link will show more detailed types and info about the MultiAsset, and here is the code.
  • Orders
    Describe what operations will be executed in the current xcm message
    • Null
    • DepositAsset
    • DepositReserveAsset
    • BuyExecution
      This link will show more detailed types and info about the Orders, and here is the code.
  • MultiLocation
    Define the relative path between two locations
    • Null
    • X1(Junction)
    • X2(Junction, Junction)
    • X3(Junction, Junction, Junction)
      This link will show more detailed types and info about the MultiLocation, and here is the code.
  • Junction
    Define the exact location
    • Parent
    • Parachain
    • AccountId32
      This link will show more detailed types and info about the Junction, and here is the code.

A typical XCM message looks like this:
Xcm_Message_Types { MultiAsset, Orders[ MultiLocation (Junction) ] }
above is really a simple example to show the structure of an XCM message.

2. XCM Versions

XCM-v0
xcm-v0 now works on Kusama, the version is release-v0.9.9.
XCM-v1
xcm-v1 has been raised in this PR-2815, and the newest version located here.
XCM-v2
xcm-v2 has been improved a lot, the design concept is different from v0/v1, related PR-3629.

3. XCM-v0/v1

Since xcm-v0 is already in Kusama production, and there are no big changes between xcm-v0 and xcm-v1, so basically this chapter will introduce the key part of xcm-v0, include xcm-transfer and xcm-transact.

3.1 xcm-transfer

DMP xcm-transfer, from relaychain to parchain, the implementation code can be found here :
dmp transfer

UMP xcm-transfer, from parachain to relaychain, the implementation code can be found here :
ump transfer

3.2 xcm-transact

Transact is mainly about UMP message, which means from parachain to relaychain.
here are two ways send an xcm-transact message, from polkadot.js UI and from parachain on-chain logic.
From UI

xcm-transact-> staking.bond
transact bond

NOTE: the encoded calldata above should be constructed alone in UI, just like a normal transaction.
From parachain on-chain logic

xcm-transact-> staking.bond

Here is the code link.

4. XCM-v2

As described in this PR-3629, that in XCM-v2, Order and Xcm message type will be equivalence. which means Xcm Message Types and Orders will both be included in instruction.

4.1 Instruction

  • WithdrawAsset
  • ReserveAssetDeposited
  • ReceiveTeleportedAsset
  • QueryResponse
  • Transact
  • DepositReserveAsset
    Here is the detailed code about instruction, where shows more types.

4.2 xcm-QueryResponse

QueryResponse is an important message type in XCM, from it, we can query the status of a former xcm message, or query
balance from relaychain. below is the response type:

pub enum Response {
	/// No response. Serves as a neutral default.
	Null,
	/// Some assets.
	Assets(MultiAssets),
	/// The outcome of an XCM instruction.
	ExecutionResult(result::Result<(), (u32, Error)>),
}

Since QueryResponse is still in development, so below content is referred from its test code.

4.2.1 define a notify callback in the TestPallet
notify link

        let call = pallet_test_notifier::Call::notification_received(0, Default::default());
	let notify = Call::TestNotifier(call);

4.2.2 store the query id in relaychain XcmPallet
invoke report_outcome_notify

        XcmPallet::report_outcome_notify(&mut message, Parachain(PARA_ID).into(), notify, 100);

store query id

        pub fn report_outcome_notify(
			message: &mut Xcm<()>,
			responder: MultiLocation,
			notify: impl Into<<T as Config>::Call>,
			timeout: T::BlockNumber,
		) {
			let dest = T::LocationInverter::invert_location(&responder);
			let notify: <T as Config>::Call = notify.into();
			let max_response_weight = notify.get_dispatch_info().weight;
			**let query_id = Self::new_notify_query(responder, notify, timeout);**
			let report_error = Xcm(vec![ReportError { dest, query_id, max_response_weight }]);
			message.0.insert(0, SetAppendix(report_error));
		}

4.2.3 execute xcm message on relaychain
[code link](https://github.com/paritytech/polkadot/blob/d8d5ce2852/xcm/pallet-xcm/src/tests.rs#L61-L69
NOTE: below returns a QueryResponse xcm message, and its response type is Response::ExecutionResult, this type usually shows whether the xcm execution succeed or failed.

let r = XcmExecutor::<XcmConfig>::execute_xcm(
			Parachain(PARA_ID).into(),
			Xcm(vec![QueryResponse {
				query_id: 0,
				response: Response::ExecutionResult(Ok(())),
				max_weight: 1_000_000,
			}]),
			1_000_000_000,
		);

4.2.4 execute on_response on relaychain XcmPallet
when executing xcm message, notify callback defined in 4.2.1 will be called in on_response , here is the code.
4.2.5 execute notification_received in TestPallet
the function defined in notify callback is notification_received, it will be invoked now. code link

pub fn notification_received(
			origin: OriginFor<T>,
			query_id: QueryId,
			response: Response,
		) -> DispatchResult {
			let responder = ensure_response(<T as Config>::Origin::from(origin))?;
			Self::deposit_event(Event::<T>::ResponseReceived(responder, query_id, response));
			Ok(())
		}

4.2.6 assert event in relaychain XcmPallet and TestPallet
code link

assert_eq!(
			last_events(2),
			vec![
				Event::TestNotifier(pallet_test_notifier::Event::ResponseReceived(
					Parachain(PARA_ID).into(),
					0,
					Response::ExecutionResult(Ok(())),
				)),
				Event::XcmPallet(crate::Event::Notified(0, 4, 2)),
			]
		);

Now it's the process of the QueryResponse.

4.3 summarize-QueryResponse

According to above process, let's image if the TestPallet is a parachain pallet, and the response type is Response.Assets(MultiAssets), then the process about query balance will look like this:
<1> parachain send an UMP message, query relaychain account balance
<2> relaychain store this query with an ID, and a parachain callback function
<3> relaychain read the balance on-chain and consume the query id
<4> relaychain send a DMP message with a balance amount, invoking parachain callback
<5> parachain store the balance
The above process is inferred from the XCM-v2 test code and may be adjusted, only for reference.

5. Conclusion

(2021-09-02)
Xcm-transfer and Xcm-transact work well in Xcm-v0 now, and it has already been launched in Kusama production, so our Liquidstaking can adjust according to it.
Xcm-QueryResponse is not well supported and is still in development. so for now in Liquidstaking we still need to feed relaychain staking reward and slash to our parachain.

@mclyk
Copy link
Contributor Author

mclyk commented Sep 3, 2021

It seems like xcm-v1 will be included in Polkadot release-v0.9.10, please check this PR-3763. its status is draft for now.

@mclyk
Copy link
Contributor Author

mclyk commented Sep 3, 2021

Subsequent works will be tracked by #502, will close this issue now.

@mclyk mclyk closed this as completed Sep 3, 2021
@yz89
Copy link
Contributor

yz89 commented Sep 3, 2021

Excellent document 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants