Skip to content
This repository has been archived by the owner on Feb 29, 2024. It is now read-only.

SDK Doc: Message details for cross-chain sending ethereum transact messages. #107

Open
hackfisher opened this issue Jun 8, 2022 · 11 comments
Assignees

Comments

@hackfisher
Copy link
Contributor

hackfisher commented Jun 8, 2022

  1. Set message.dispatch_fee_payment == DispatchFeePayment::AtTargetChain because for the evm transact call to be dispatched successfully, we must have enough gas in dispatch origin, and we will need customize pay_dispatch_fee closure in runtime, to transfer enough fee (gas_price * gas_limit) from relayer to dispatch origin.
		fn dispatch(
			relayer_account: &AccountIdOf<ThisChain<B>>,
			message: DispatchMessage<Self::DispatchPayload, BalanceOf<BridgedChain<B>>>,
		) -> MessageDispatchResult {
			let message_id = (message.key.lane_id, message.key.nonce);
			pallet_bridge_dispatch::Pallet::<ThisRuntime, ThisDispatchInstance>::dispatch(
				B::BRIDGED_CHAIN_ID,
				B::THIS_CHAIN_ID,
				message_id,
				message.data.payload.map_err(drop),
				|dispatch_origin, dispatch_weight| {
					// For evm.transact message, transfer fee(gas_limit* gas_price) from relayer account to dispatch origin.
					// Be care about the precision diff
				},
			)
		}

Continue use message.dispatch_fee_payment == DispatchFeePayment::AtSourceChain

if pay_dispatch_fee_at_target_chain && pay_dispatch_fee(&dispatch_origin, &call).is_err() {

Will not be called in our case.

  1. For all message in darwinia network, the dispatch fee should be prepaid to Fee Market pallet on source chain when sending message, and allocated to the actrual dispatch relayer on confirmation/settlement.
  • For non evm.transact messages, the dispatch relayer will help pay for the msg's actually weight on target chain by including the msg's actual weight in receive_messages_proof extrinsic' PostDispatchInfo. These message should set message.dispatch_fee_payment == DispatchFeePayment::AtSourceChain

  • For evm.transact messages, the dispatch relayer will help pay for the msg's gas limit * gas_price by transferring gas on target chain to dispatch_origin(in Ethereum format).

  1. Since the PostDispatchInfo of evm transact is Pay::NO, the actual weight of evm transact is only for validation, the fees will be charged in evm executor's gas meter, so we should reset the actual weight for PostDispatchInfo if their fee payment value are Pay::NO.

TODO: Make changes to #105

let actual_call_weight = extract_actual_weight(&result, &dispatch_info);

@hackfisher hackfisher changed the title SDK Doc: Message details for cross-chain sending ethereum address. SDK Doc: Message details for cross-chain sending ethereum transact messages. Jun 8, 2022
@hackfisher
Copy link
Contributor Author

hackfisher commented Jun 8, 2022

As mentioned in #101 comment, here is point 4:

  1. How to set message.weight? And how to set gas_limit and gas_price for evm.transact messages?

For non evm.transact messages, message.weight is already supported and is to limit max weight of the message for dispatch.

For evm.transact messages, message.weight is also the only settings in message to limit checked by bridge-dispatch, but be careful here, is gas_limit is the actual limit that works in execution.

So to make they consist, we should have an extra check that ensure

  1. gas_to_weight(gas_limit) <= message.weight
  2. gas_price >= ThisRuntime::WeightToFee::calc(gas_to_weight(1)) * pallet_transaction_payment::Pallet::<ThisRuntime>::next_fee_multiplier() * 10**9

Note: 10**9 is for decimal conversion.

@wuminzhe
Copy link
Collaborator

wuminzhe commented Jun 8, 2022

According to my understanding, we only have DispatchFeePayment::AtSourceChain.

when cross-chain call ethereum.transact.
We set message.dispatch_fee_payment = DispatchFeePayment::AtTargetChain .
But, the dispatch fee paid by relayer still. The dispatch fee is not transferred to relayer at target chain.

So, maybe we can remove the DispatchFeePayment.

@wuminzhe
Copy link
Collaborator

wuminzhe commented Jun 8, 2022

For all message in darwinia network, the dispatch fee should be prepaid to Fee Market pallet on source chain when sending message, and allocated to the actrual dispatch relayer on confirmation/settlement.

if DispatchFeePayment::AtTargetChain, will the prepaid dispatch fee be send back to the sender?

@wuminzhe
Copy link
Collaborator

wuminzhe commented Jun 8, 2022

  1. sender prepay dispatch fee to relayers(market) at the source chain

  2. a relayer dispatch message.call with dispatch_origin_of_sender at the target chain

    • message.call == non evm.transact
      the relayer pay for the dispatch fee. There is no fee transfer.
    • message.call == evm.transact
      transfer the dispatch fee(gas fee) from relayer_account to dispatch_origin_of_sender.
      dispatch_origin_of_sender pay gas himself.
      the relayer will not pay for the dispatch fee.

@boundless-forest
Copy link
Member

I need to deep into that logic, then discuss it later. A little complicated

@wuminzhe
Copy link
Collaborator

wuminzhe commented Jun 9, 2022

gas_price >= ThisRuntime::WeightToFee::calc(gas_to_weight(1)) * pallet_transaction_payment::Pallet::::next_fee_multiplier() * 10**9

Now, ethereum pallet only need the gas_price >= min_gas_price. updated it?

if gas_price < base_fee {
	return Err(InvalidTransaction::Payment.into());
}

@hackfisher

@hackfisher
Copy link
Contributor Author

  1. sender prepay dispatch fee to relayers(market) at the source chain

  2. a relayer dispatch message.call with dispatch_origin_of_sender at the target chain

    • message.call == non evm.transact
      the relayer pay for the dispatch fee. There is no fee transfer.
    • message.call == evm.transact
      transfer the dispatch fee(gas fee) from relayer_account to dispatch_origin_of_sender.
      dispatch_origin_of_sender pay gas himself.
      the relayer will not pay for the dispatch fee.

Make sense.

@hackfisher
Copy link
Contributor Author

hackfisher commented Jun 16, 2022

  1. gas_limit * gas_price could not be too large.

#134 (comment)

@hackfisher
Copy link
Contributor Author

  1. Warn that even if the nonce is set wrong, not continuous increase, then the message will still fail, and the gas in the message will still be consumed( Though most of them will go to message sender's remote account). This is different with the situation of sending Ethereum transactions to node pool.

darwinia-network/darwinia-common#1267 (comment)

@hackfisher
Copy link
Contributor Author

  1. We do not support payable (value > 0) ethereum tx message for now. But it is possible in future.

This could be an attack to relayer, to run out of their balances.

Solution:

Do not support payable calls t.value > 0 for now.

Originally posted by @hackfisher in darwinia-network/darwinia-common#1267 (comment)

if value is set to non-zero, it means transfer from the sender address on the target chain derived from dapp contract address on the source chain.
but if the the sender address has no enough tokens, the transact will fail?

Originally posted by @wuminzhe in darwinia-network/darwinia-messages-sol#170 (comment)

@hackfisher
Copy link
Contributor Author

For message_transact, the gas fee should not larger than MaxUsableBalanceFromRelayer, otherwise, this massage will fail.

if fee > decimal_convert(MaxUsableBalanceFromRelayer::get(), None) {
								return Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(2u8)));
							}

For relayer, he should ensure enough funds at his account for dispatching message_transact, otherwise he could failed to receive/relay this message, latter relayer can continue relay this message as soon as he have enough funds in his account.

ensure!(
							evm_ensure_can_withdraw(
								relayer_account,
								cmp::min(
									fee,
									decimal_convert(MaxUsableBalanceFromRelayer::get(), None)
								),
								WithdrawReasons::TRANSFER
							)
							.is_ok(),
							TransactionValidityError::Invalid(InvalidTransaction::Payment)
						);

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
No open projects
Status: No status
Development

No branches or pull requests

4 participants
@hackfisher @wuminzhe @boundless-forest and others