Skip to content

Commit

Permalink
Tesseract and doc updates (#367)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wizdave97 authored Jan 16, 2025
1 parent db9e70a commit 73c4a82
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 22 deletions.
9 changes: 2 additions & 7 deletions docs/pages/developers/polkadot/token-gateway.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,10 @@ Let's look at the pallet specific components of the configuration trait: <br/><b

- `Dispatcher`: The should be an implementation of the [`IsmpDispatcher`](/protocol/ismp/dispatcher), it will be used by this pallet dispatch cross-chain requests.<br/><br/>
- `Assets`: This type should be configured with a component that implements the following interfaces, typically this will be `pallet-assets`
- [`fungibles::Create`](https://docs.rs/frame-support/latest/frame_support/traits/tokens/fungibles/trait.Create.html)
- [`fungibles::Inspect`](https://docs.rs/frame-support/latest/frame_support/traits/tokens/fungibles/trait.Inspect.html)
- [`fungibles::Mutate`](https://docs.rs/frame-support/latest/frame_support/traits/tokens/fungibles/trait.Mutate.html)
- [`fungibles::metadata::Mutate`](https://docs.rs/frame-support/latest/frame_support/traits/tokens/fungibles/metadata/trait.Mutate.html) <br/><br/>
- `Currency`: This type should be configured with a component that implements [`Currency`](https://docs.rs/frame-support/latest/frame_support/traits/tokens/currency/trait.Currency.html) interface, typically `pallet-balances`.<br/><br/>
- `AssetAdmin`: This pallet has some functionality for creating new assets. The account configured for this type would be the asset admin and also be responsible for paying the asset registration fees, therefore it should be funded before attempting to create any assets.<br/><br/>
- `AssetIdFactory`: This type should be configured with a component that implements `pallet_token_gateway::types::CreateAssetId`. It should return a unique asset id each time the `AssetIdFactory::create_asset_id` is called.<br/><br/>
- `NativeAssetId`: A constant value that represents the identifier of the native asset.<br/><br/>
- `Decimals`: A constant that represents the precision of the native currency. <br/><br/>
- `EvmToSubstrate`: A type that allows conversion of an EVM account to a substrate account. <br/><br/>
Expand All @@ -31,8 +28,9 @@ Let's look at the pallet specific components of the configuration trait: <br/><b
- `set_token_gateway_addresses`: This priviledged call is used to set the token gateway address for EVM chains.
- `create_erc6160_asset`: This call dispatches a request to Hyperbridge to create multi chain native assets on token gateway deployments
- `update_erc6160_asset`: This call dispatches a request to Hyperbridge to update multi chain native assets on token gateway deployments
- `update_asset_precision`: This priviledged call is used to set or update the precision of an asset deployed on some remote chains.

Priviledged calls must be dispatched by [`AdminOrigin`](https://docs.rs/pallet-ismp/latest/pallet_ismp/pallet/trait.Config.html#associatedtype.AdminOrigin) configured in [`pallet-ismp`](https://docs.rs/pallet-ismp/latest/pallet_ismp).
Priviledged calls must be dispatched by [`CreateOrigin`](https://docs.rs/pallet-token-gateway/latest/pallet_token_gateway/pallet/trait.Config.html#associatedtype.CreateOrigin).


## Integrating the pallet into the Runtime
Expand Down Expand Up @@ -85,9 +83,6 @@ impl pallet_token_gateway::Config for Runtime {
type CreateOrigin = frame_system::EnsureSigned<AccountId>
// The Native asset Id
type NativeAssetId = NativeAssetId;
// A type that provides a function for creating unique asset ids
// A concrete implementation for your specific runtime is required
type AssetIdFactory = ();
// The precision of the native asset
type Decimals = Decimals;
// An implementation that converts an evm account to a substrate account
Expand Down
21 changes: 15 additions & 6 deletions modules/pallets/token-gateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This allows polkadot-sdk chains make cross-chain asset transfers to and from eac

## Overview

The Pallet allows the [`AdminOrigin`](https://docs.rs/pallet-ismp/latest/pallet_ismp/pallet/trait.Config.html#associatedtype.AdminOrigin) configured in [`pallet-ismp`](https://docs.rs/pallet-ismp/latest/pallet_ismp) to dispatch calls for setting token gateway addresses.
The Pallet allows the [`CreateOrigin`](https://docs.rs/pallet-token-gateway/latest/pallet_token_gateway/pallet/trait.Config.html#associatedtype.CreateOrigin) to dispatch calls for setting token gateway addresses, creating and updating assets.
This enables receiving assets from those configured chains. Assets can also be received with a runtime call to be dispatched. This call must be signed by the beneficiary of the incoming assets. Assets can also be sent with some calldata, this calldata is an opaque blob of bytes
whose interpretation is left up to the recipient token gateway implementation. For polkadot-sdk chains, it must be a scale-encoded runtime call, for EVM chains it must be an abi-encoded contract call.

Expand All @@ -16,14 +16,25 @@ The first step is to implement the pallet config for the runtime.
use frame_support::parameter_types;
use ismp::module::IsmpModule;
use ismp::router::IsmpRouter;
use pallet_token_gateway::types::NativeAssetLocation;
parameter_types! {
// A constant that should represent the native asset id
pub const NativeAssetId: u32 = 0;
// Set the correct precision for the native currency
pub const Decimals: u8 = 12;
}
/// A constant value that represents the native asset
/// `NativeAssetLocation::Local` indicates the native asset is custodied locally.
/// `NativeAssetLocation::Remote` indicates that the native asset is custodied on some remote chain.
pub struct NativeAssetId;
impl Get<NativeAssetLocation<u32>> for NativeAssetId {
fn get() -> NativeAssetLocation<u32> {
NativeAssetLocation::Local(0)
}
}
/// Should provide an account that is funded and can be used to pay for asset creation
pub struct AssetAdmin;
Expand All @@ -46,9 +57,6 @@ impl pallet_token_gateway::Config for Runtime {
type AssetAdmin = AssetAdmin;
// The Native asset Id
type NativeAssetId = NativeAssetId;
// A type that provides a function for creating unique asset ids
// A concrete implementation for your specific runtime is required
type AssetIdFactory = ();
// The precision of the native asset
type Decimals = Decimals;
}
Expand Down Expand Up @@ -81,6 +89,7 @@ The pallet requires some setting up before the teleport function is available fo
- `set_token_gateway_addresses` - This call allows the `AdminOrigin` origin to set the token gateway address for supported chains.
- `create_erc6160_asset` - This call dispatches a request to Hyperbridge to create multi chain native assets on token gateway deployments
- `update_erc6160_asset` - This priviledged call dispatches a request to Hyperbridge to update multi chain native assets on token gateway deployments
- `update_asset_precision` - This priviledged call is used to set or update the precision for an asset deployed on a remote chain

## License

Expand Down
6 changes: 5 additions & 1 deletion tesseract/evm/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,11 @@ impl IsmpProvider for EvmClient {
Ok(Box::pin(stream))
}

async fn submit(&self, messages: Vec<Message>) -> Result<Vec<TxReceipt>, Error> {
async fn submit(
&self,
messages: Vec<Message>,
_coprocessor: StateMachine,
) -> Result<Vec<TxReceipt>, Error> {
let queue = self
.queue
.as_ref()
Expand Down
2 changes: 1 addition & 1 deletion tesseract/messaging/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ async fn handle_update(
chain_b.name(), chain_a.name()
);

let res = chain_a.submit(messages.clone()).await;
let res = chain_a.submit(messages.clone(), coprocessor).await;
match res {
Ok(receipts) => {
if let Some(sender) = fee_acc_sender {
Expand Down
2 changes: 1 addition & 1 deletion tesseract/messaging/src/retries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ pub async fn retry_unprofitable_messages(
target: "tesseract",
"Unprofitable Messages Retries: 🛰️ Transmitting ismp messages from {} to {}", hyperbridge.name(), dest.name()
);
if let Ok(receipts) = dest.submit(outgoing_messages).await {
if let Ok(receipts) = dest.submit(outgoing_messages, coprocessor).await {
if !receipts.is_empty() {
// Store receipts in database before auto accumulation
tracing::trace!(target: "tesseract", "Persisting {} deliveries from {}->{} to the db", receipts.len(), hyperbridge.name(), dest.name());
Expand Down
6 changes: 5 additions & 1 deletion tesseract/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,11 @@ pub trait IsmpProvider: ByzantineHandler + Send + Sync {
///
/// Should only return Ok if the transaction was successfully inserted into a block.
/// Should return a list of requests and responses that where successfully processed
async fn submit(&self, messages: Vec<Message>) -> Result<Vec<TxReceipt>, anyhow::Error>;
async fn submit(
&self,
messages: Vec<Message>,
coprocessor: StateMachine,
) -> Result<Vec<TxReceipt>, anyhow::Error>;

/// This method should return the key used to be used to query the state proof for the request
/// commitment
Expand Down
6 changes: 5 additions & 1 deletion tesseract/primitives/src/mocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,11 @@ impl<C: Codec + Send + Sync> IsmpProvider for MockHost<C> {
todo!()
}

async fn submit(&self, _messages: Vec<Message>) -> Result<Vec<TxReceipt>, Error> {
async fn submit(
&self,
_messages: Vec<Message>,
_coprocessor: StateMachine,
) -> Result<Vec<TxReceipt>, Error> {
todo!()
}

Expand Down
12 changes: 10 additions & 2 deletions tesseract/relayer/src/fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,10 @@ async fn deliver_post_request<D: IsmpProvider>(

let mut count = 5;
while count != 0 {
if let Err(e) = dest_chain.submit(vec![Message::Request(msg.clone())]).await {
if let Err(e) = dest_chain
.submit(vec![Message::Request(msg.clone())], hyperbridge.state_machine_id().state_id)
.await
{
log::info!(
"Encountered error trying to submit withdrawal request to {}.\n{e:?}\nWill retry {count} more times.",
dest_chain.state_machine_id().state_id
Expand Down Expand Up @@ -688,7 +691,12 @@ mod tests {
dest_chain.state_machine_id().state_id
);

let result = dest_chain.submit(vec![Message::Request(msg.clone())]).await;
let result = dest_chain
.submit(
vec![Message::Request(msg.clone())],
hyperbridge.state_machine_id().state_id,
)
.await;

tracing::info!("result for {dest}: {result:?}")
}
Expand Down
10 changes: 8 additions & 2 deletions tesseract/substrate/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,14 +648,20 @@ where
Ok(Box::pin(stream))
}

async fn submit(&self, messages: Vec<Message>) -> Result<Vec<TxReceipt>, anyhow::Error> {
async fn submit(
&self,
messages: Vec<Message>,
coprocessor: StateMachine,
) -> Result<Vec<TxReceipt>, anyhow::Error> {
let mut futs = vec![];
let is_hyperbridge = self.state_machine == coprocessor;
for msg in messages.clone() {
let is_consensus_message = matches!(&msg, Message::Consensus(_));
let call = vec![msg].encode();
let extrinsic = Extrinsic::new("Ismp", "handle_unsigned", call);
// We don't compress consensus messages
if is_consensus_message {
// We only consider compression for hyperbridge
if is_consensus_message || !is_hyperbridge {
futs.push(send_unsigned_extrinsic(&self.client, extrinsic, false));
continue;
}
Expand Down

0 comments on commit 73c4a82

Please sign in to comment.