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

Quick draft of router pallet using moonbeam ethereum_xcm.transact and LCMP ethereum.message_transact #1090

Closed
hackfisher opened this issue Aug 8, 2022 · 10 comments
Assignees

Comments

@hackfisher
Copy link
Contributor

hackfisher commented Aug 8, 2022

A.

LCMP(crab_contract_origin, crab_parachain_router_pallet.route(moonbase_chain, ethereum_xcm.transact(,...) ))

crab_parachain_router_pallet

route(origin, chain, call)

{
forward & send xcm message to chain using XCM_Instruction(origin, ?, call)
}

B.

XCM(Instruction::Transact(moonbase_contract_origin, ?, crab_parachain_router_pallet.route(crab_chain, ethereum.message_transact(....)) ))

crab_parachain_router_pallet

route(origin, chain, call)

{
forward & send LCMP message to crab chain using LCMP call ethereum.message_transact(....)
}

forwarded origin should be compatible/derived or the same?

@hackfisher
Copy link
Contributor Author

The route_id for transaction support, should be chain + origin_contract_address + message/route_nonce_in_contract.

If the route delivered/failed/success to forward, it should be recorded, then transactional roll back in application level may work.

If the message on target chain delivered, it should be recorded, if it successfully get dispatch, it can be recored.

If the route failed or the message_on_target_chain failed(how to know this in target chain?*), the message can roll back.

Q: How to know a message failed on target chain?

A: The message is delivered but not recorded.

@jiguantong
Copy link
Member

jiguantong commented Aug 9, 2022

Moonbeam has forked polkadot and modified the config of xcm executor, CallDispatcher trait commit

@xiaoch05
Copy link
Contributor

xiaoch05 commented Aug 9, 2022

If the xcm messages are ordered inside the queue, then a lost message can be proven lost by subsequent unlost messages.
This way we only need to produce message loss proofs in the target chain to do the rollback operation, and can leave that operation entirely to the application layer itself.

@jiguantong
Copy link
Member

jiguantong commented Aug 12, 2022

The xcm messages are sent and processed in order. @xiaoch05

  1. Insert xcm into OutboundXcmpMessages
  2. OutboundXcmpMessages > HrmpOutboundMessages
  3. CollectionInfo for relay
  4. ParachainInherentData horizontal_messages
  5. Sort by relay block_number and paraId, this sort is a stable sort that does not affect messages in the same block sent by the same chain

@jiguantong
Copy link
Member

encoded call: 0x0d0001010100a10f0214010400010200e520040500130000f444829163451300010200e520040500130000f44482916345000b0103013843726162536d617274436861696e7369626c3908000000000000000000000000000006010700f2052a017d01260000400d03000000000000000000000000000000000000000000000000000000000001004617d470f847ce166019d19a7944049ebb01740000000000000000000000000000000000000000000000000000000000000000001019ff1d21000d010004010100e520

dest: XcmVersionedMultiLocation
{
  V1: {
    parents: 1
    interior: {
      X1: {
        Parachain: 1,000
      }
    }
  }
}
message: XcmVersionedXcm
{
  V2: [
    {
      ReserveAssetDeposited: [
        {
          id: {
            Concrete: {
              parents: 1
              interior: {
                X2: [
                  {
                    Parachain: 2,105
                  }
                  {
                    PalletInstance: 5
                  }
                ]
              }
            }
          }
          fun: {
            Fungible: 5,000,000,000,000,000,000
          }
        }
      ]
    }
    {
      BuyExecution: {
        fees: {
          id: {
            Concrete: {
              parents: 1
              interior: {
                X2: [
                  {
                    Parachain: 2,105
                  }
                  {
                    PalletInstance: 5
                  }
                ]
              }
            }
          }
          fun: {
            Fungible: 5,000,000,000,000,000,000
          }
        }
        weightLimit: Unlimited
      }
    }
    {
      DescendOrigin: {
        X1: {
          AccountKey20: {
            network: {
              Named: CrabSmartChain
            }
            key: 0x7369626c39080000000000000000000000000000
          }
        }
      }
    }
    {
      Transact: {
        originType: SovereignAccount
        requireWeightAtMost: 5,000,000,000
        call: {
          encoded: 0x260000400d03000000000000000000000000000000000000000000000000000000000001004617d470f847ce166019d19a7944049ebb01740000000000000000000000000000000000000000000000000000000000000000001019ff1d2100
        }
      }
    }
    {
      DepositAsset: {
        assets: {
          Wild: All
        }
        maxAssets: 1
        beneficiary: {
          parents: 1
          interior: {
            X1: {
              Parachain: 2,105
            }
          }
        }
      }
    }
  ]
}

@jiguantong
Copy link
Member

jiguantong commented Aug 18, 2022

We can use the above XCM ReserveAssetDeposited instruction to generate CRAB token in moonbase's xcm holding to pay XCM fees and execute transact. For trust, we need to transfer the corresponding CRAB token to moonbase's sovereign account.

DescendOrigin instruction can change the origin.

@xiaoch05
Copy link
Contributor

We can use the above XCM ReserveAssetDeposited instruction to generate CRAB token in moonbase's xcm holding to pay XCM fees and execute transact. For trust, we need to transfer the corresponding CRAB token to moonbase's sovereign account.

DescendOrigin instruction to change the origin.

So we also need a sovereign account on crab smart chain to receive the fee token CRAB, and pay the xcm fee from this account to the moonbase's sovereign account on parachain.

@jiguantong
Copy link
Member

jiguantong commented Aug 19, 2022

xcm::execute_xcm_in_credit: Barrier blocked execution! Error: (). (origin: MultiLocation { parents: 1, interior: X1(Parachain(1000)) }, message: Xcm([DescendOrigin(X1(AccountKey20 { network: Any, key: [203, 133, 49, 188, 11, 124, 143, 65, 181, 92, 244, 233, 70, 152, 195, 123, 19, 5, 151, 185] })), WithdrawAsset(MultiAssets([MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(PalletInstance(5)) }), fun: Fungible(6) }])), BuyExecution { fees: MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(PalletInstance(5)) }), fun: Fungible(6) }, weight_limit: Limited(5000010000) }, Transact { origin_type: SovereignAccount, require_weight_at_most: 5000000000, call: [0, 8, 48, 109, 111, 111, 110, 98, 97, 115, 101, 116, 101, 115, 116] }]), weight_limit: 41666666666, weight_credit: 0)
2022-08-19 09:43:00.039 ERROR tokio-runtime-worker cumulus_pallet_xcmp_queue: Failed to process XCMP-XCM message, caused by Barrier

When we receive the XCM message from moonriver, the first instruction is DescendOrigin. By default, most chains will barrier the DescendOrigin instruction as the first instruction, because it represents the origin of ordinary users. Should we allow it? Or can we just allow moonriver as the sender?
open-web3-stack/open-runtime-module-library#766 (comment)

@jiguantong
Copy link
Member

Store routing failure messages and process them

@xiaoch05
Copy link
Contributor

xiaoch05 commented Sep 1, 2022

  1. Network Structure
    From Crab Smart Chain (CSC) to Moonriver, the message is forwarded through Crab Parachain. User send the message to Route Pallet on Parachain via LCMP protocol, which is decoded by Route Pallet and forwarded to Moonriver via XCM; the process is similar from Moonriver to CSC.
    router
  2. SDK is required on CSC and on Moonriver to provide entry and exit points for DAPP messages.
  • endpoint
    The interfaces needed to integrate message sending and receiving, permission verification, endpoints on the source and target chains appear in pairs and they trust with each other.
  • origin
    Endpoint needs to pass the identity (origin) of the user to the target chain, which will be routed by Crab Parachain, the origin may be derived in the process of passing, the source origin may not be restored on the target chain, but can be verified, the SDK needs to provide a verification interface for the origin on the target chain.
    • from CSC to Moonriver
      Origin(20)→DVM Derived(32)→LCMP Derived Origin(32)→Moonriver Derived(20)
    • from Moonriver to CSC
      Origin(20)→Moonriver Derived(32)→LCMP Derived Origin(32)→DVM Derived(20)
    • SDK needs to provide an interface for deriving these addresses on Crab Parachain
    • The Route Pallet needs to assemble the command to modify the origin, which is the LCMP derived account on the Crab Parachain, when forwarding XCM messages
  • message encode/decode
    • On the CSC side, the SDK wraps the contract call on the target chain Moonriver as an XCM message on Crab Parachain and sends the message to the route Pallet using LCMP.
    • On the Moonriver side, the SDK wraps the contract call on the target chain CSC into an LCMP message on the Crab Parachain, which can directly call the sendMessage interface of the LCMP without going through the route Pallet.
  1. Fee
    The fees are paid using Crab, which is a Native Token on CSC and Crab Parachain, and an xc20 Token on Moonriver
  • Fee for single-hop messages
    • Paid by the user account on the start chain of the current message
    • The user here refers to the user of the routed message, e.g. a certain DAPP contract
  • Fee payment account
    The derived account of the user account on the chain through which the message passes is considered to be the same account, which needs to pay the fee for the message on each chain.
    For example, when a message is forwarded from CSC to Moonriver, the user's derived account from CSC to Crab Parachain is used to pay for this forwarding fee when the message is forwarded to Moonriver from Crab Parachain.
  • Router
    When the router forwards the message, it directly deducts the derived account of the current user on the parachain to pay the fee, and if the deduction is found to fail, the message is discarded.
  • Fee prepayment
    The user (DAPP) needs to pre-deposit a sufficient fee into the derived account on the crab parachain to cover the message forwarding cost and check if the balance is sufficient before sending the message.
    This fee can be further charged by the DAPP from its own users and deposited to the Crab Parachain at the call to the CSC<>Crab Parachain token bridge interface.
  • SDK provides routing fee parameters for users
    Users can specify a maximum fee when sending messages to prevent unreasonable real-time fee deductions
  1. Transaction Atomicity
    The assurance of transaction atomicity is left to the application layer, and the router is implemented to ensure that messages are executed in order whenever possible.
  • The sender side of the application maintains an incremental transferId. The transferId is incremented for each message, the message content and the corresponding transferId are saved.
  • The receiver maintains a latestTransferId, and saves the transferId of all successfully received messages.
    When the message is successfully received by the target, the target end determines whether the transferId of the message is larger than the latestTransferId, and if it is larger, it accept the message and saves the transferId, while updating the latestTransferId; otherwise, it rejects the message and the transaction ends.
    When a message is lost when transfer, the application layer cannot sense the loss of the message and needs to wait for or trigger the next successfully received message. When the subsequent message transaction is completed, the latestTransferId of the target end is larger than the transferId of the lost message. This determines that the message is lost and the user can initiate a rollback operation at the target end. The original sender receives the rollback message, verify the message and then performs the rollback, and the transaction completes.

@AurevoirXavier AurevoirXavier transferred this issue from darwinia-network/darwinia-parachain Mar 30, 2023
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

No branches or pull requests

5 participants