Skip to content

Commit

Permalink
Extract common bridging payment code
Browse files Browse the repository at this point in the history
  • Loading branch information
ByteNacked committed Sep 16, 2024
1 parent d3fb836 commit 19fb48b
Show file tree
Hide file tree
Showing 28 changed files with 331 additions and 497 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ members = [
"gear-programs/bridging-payment/src/wasm",
"gear-programs/bridging-payment-vara-supply",
"gear-programs/bridging-payment-vara-supply/src/wasm",
"gear-programs/bridging-payment-common",
"gear-programs/vft-gateway",
"gear-programs/vft-gateway/src/wasm",
"gear-programs/vft-treasury",
Expand Down Expand Up @@ -41,6 +42,7 @@ bridging_payment = { path = "gear-programs/bridging-payment" }
bridging_payment_wasm = { path = "gear-programs/bridging_payment/src/wasm" }
bridging_payment_vara_supply = { path = "gear-programs/bridging-payment-vara-supply" }
bridging_payment_vara_supply_wasm = { path = "gear-programs/bridging-payment-vara-supply/src/wasm" }
bridging_payment_common = { path = "gear-programs/bridging-payment-common" }
vft-gateway-app = { path = "gear-programs/vft-gateway" }
vft_gateway_wasm = { path = "gear-programs/vft-gateway/src/wasm" }
vft-treasury-app = { path = "gear-programs/vft-treasury" }
Expand Down
14 changes: 14 additions & 0 deletions gear-programs/bridging-payment-common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "bridging_payment_common"
version.workspace = true
edition.workspace = true

[dependencies]
sails-rs.workspace = true
parity-scale-codec.workspace = true
scale-info.workspace = true
gstd.workspace = true

[features]
default = []
gtest_macros = []
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,26 @@ use sails_rs::prelude::*;
pub enum Error {
SendFailure,
ReplyFailure,
ReplyTimeout,
ReplyHook,
InvalidMessageStatus,
MessageNotFound,

// Vara supply bridge errors
RequestToTreasuryDecode,
TreasuryMessageProcessingFailed,

// Ethereum supply bridge errors
TransferTokensDecode,
TokensTransferFailure,
TokensRefunded,
TransferTokensFailed,

// Gateway errors
RequestToGateWayDecode,
PayloadSize,
MintTokensDecode,
ReplyTimeout,
TokensRefunded,
TransactionFailure,
FailureInVftGateway,
ReplyHook,
GatewayMessageProcessingFailed,
InvalidMessageStatus,
MessageNotFound,
TransferTokensFailed,
}
141 changes: 141 additions & 0 deletions gear-programs/bridging-payment-common/src/gtest_macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#[macro_export]
macro_rules! create_function {
($name:ident, $method:expr) => {
fn $name(&self, from: u64, error: bool);
};

($name:ident, $method:expr, $($param_name:ident: $param_type:ty),*) => {
fn $name(&self, from: u64, $($param_name: $param_type,)* error: bool);
};
}

pub use create_function;

#[macro_export]
macro_rules! implement_function {
($name:ident, $prefix:expr, $method:expr) => {
fn $name(&self, from: u64, error: bool) {
let payload = [
$prefix.encode(),
$method.encode(),
]
.concat();
let result = self.send_bytes(from, payload);

if error {
assert!(result.main_failed());
} else {
assert!(!result.main_failed());
}
}
};
($name:ident, $prefix:expr, $method:expr, $($param_name:ident: $param_type:ty),*; $with_value:expr) => {
fn $name(&self, from: u64, $($param_name: $param_type,)* error: bool) {
let payload = [
$prefix.encode(),
$method.encode(),
($($param_name,)*).encode(),
]
.concat();

let result = if $with_value {
self.send_bytes_with_value(from, payload, FEE)
} else {
self.send_bytes(from, payload)
};

if error {
assert!(result.main_failed());
} else {
assert!(!result.main_failed());
}
}
};
}

pub use implement_function;

#[macro_export]
macro_rules! create_query_function {
// Match functions with parameters
($fn_name:ident, $return_type:ty, $($param_name:ident: $param_type:ty),*) => {
fn $fn_name(&self, $($param_name: $param_type),*) -> $return_type;
};
// Match functions without parameters
($fn_name:ident, $return_type:ty) => {
fn $fn_name(&self) -> $return_type;
};
}

pub use create_query_function;

#[macro_export]
macro_rules! implement_token_query {
($fn_name:ident, $query_name:expr, $return_type:ty) => {
fn $fn_name(&self) -> $return_type {
let query = ["Vft".encode(), $query_name.encode()].concat();
let result = self.send_bytes(ADMIN_ID, query.clone());

let log_entry = result
.log()
.iter()
.find(|log_entry| log_entry.destination() == ADMIN_ID.into())
.expect("Unable to get query reply");

let query_reply = <(String, String, $return_type)>::decode(&mut log_entry.payload())
.expect("Unable to decode reply");
query_reply.2
}
};

($fn_name:ident, $query_name:expr, $return_type:ty, $($param_name:ident: $param_type:ty),*) => {
fn $fn_name(&self, $($param_name: $param_type),*) -> $return_type {
let query = ["Vft".encode(), $query_name.encode(), ($($param_name),*).encode()].concat();
let result = self.send_bytes(ADMIN_ID, query.clone());

let log_entry = result
.log()
.iter()
.find(|log_entry| log_entry.destination() == ADMIN_ID.into())
.expect("Unable to get query reply");

let query_reply = <(String, String, $return_type)>::decode(&mut log_entry.payload())
.expect("Unable to decode reply");
query_reply.2
}
};
}

pub use implement_token_query;

#[macro_export]
macro_rules! create_ft_mock {
($name:ident, $handle_result:expr) => {
#[derive(Debug)]
pub struct $name;

impl WasmProgram for $name {
fn init(&mut self, _payload: Vec<u8>) -> Result<Option<Vec<u8>>, &'static str> {
Ok(None)
}

fn handle(&mut self, _payload: Vec<u8>) -> Result<Option<Vec<u8>>, &'static str> {
$handle_result
}

fn handle_reply(&mut self, _payload: Vec<u8>) -> Result<(), &'static str> {
unimplemented!()
}

fn handle_signal(&mut self, _payload: Vec<u8>) -> Result<(), &'static str> {
unimplemented!()
}

fn state(&mut self) -> Result<Vec<u8>, &'static str> {
unimplemented!()
}
}
};
}

pub use create_ft_mock;
25 changes: 25 additions & 0 deletions gear-programs/bridging-payment-common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#![no_std]

pub mod error;
#[cfg(feature = "gtest_macros")]
pub mod gtest_macros;
pub mod refund;
pub mod utils;

use sails_rs::prelude::*;

#[derive(Encode, Decode, TypeInfo)]
pub enum BridgingPaymentEvents {
TeleportVaraToEth {
nonce: U256,
sender: ActorId,
amount: U256,
receiver: H160,
eth_token_id: H160,
},
DepositVaraToTreasury {
sender: ActorId,
amount: U256,
receiver: H160,
},
}
12 changes: 12 additions & 0 deletions gear-programs/bridging-payment-common/src/refund.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use gstd::{exec, msg, ActorId};

pub fn process_refund(sender: ActorId, attached_value: u128, fee: u128) {
let refund = attached_value - fee;
if refund >= exec::env_vars().existential_deposit {
handle_refund(sender, refund);
}
}

fn handle_refund(actor_id: ActorId, amount: u128) {
msg::send_with_gas(actor_id, "", 0, amount).expect("Error in refund");
}
62 changes: 62 additions & 0 deletions gear-programs/bridging-payment-common/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use gstd::{vec::Vec, ActorId, MessageId};

use crate::error::Error;

#[macro_export]
macro_rules! maybe_event_or_panic_async {
($self:expr, $expr:expr) => {{
let result: Result<Option<BridgingPaymentEvents>, Error> = $expr().await;
match result {
Ok(Some(value)) => {
if let Err(e) = $self.notify_on(value) {
panic!("Error in depositing events: {:?}", e);
}
}
Ok(None) => {}
Err(e) => {
panic!("Message processing failed with error: {:?}", e);
}
}
}};
}

pub use maybe_event_or_panic_async;

#[macro_export]
macro_rules! event_or_panic_async {
($self:expr, $expr:expr) => {{
let result: Result<BridgingPaymentEvents, Error> = $expr().await;
match result {
Ok(value) => {
if let Err(e) = $self.notify_on(value) {
panic!("Error in depositing events: {:?}", e);
}
}
Err(e) => {
panic!("Message processing failed with error: {:?}", e);
}
}
}};
}

pub use event_or_panic_async;

pub async fn send_message_with_gas_for_reply(
handle_reply_hook: fn(msg_id: MessageId),
destination: ActorId,
message: Vec<u8>,
gas_to_send: u64,
gas_deposit: u64,
reply_timeout: u32,
msg_id: MessageId,
) -> Result<(), Error> {
gstd::msg::send_bytes_with_gas_for_reply(destination, message, gas_to_send, 0, gas_deposit)
.map_err(|_| Error::SendFailure)?
.up_to(Some(reply_timeout))
.map_err(|_| Error::ReplyTimeout)?
.handle_reply(move || handle_reply_hook(msg_id))
.map_err(|_| Error::ReplyHook)?
.await
.map_err(|_| Error::ReplyFailure)?;
Ok(())
}
1 change: 1 addition & 0 deletions gear-programs/bridging-payment-vara-supply/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ sails-rs.workspace = true
parity-scale-codec.workspace = true
scale-info.workspace = true
gstd.workspace = true
bridging_payment_common.workspace = true

[build-dependencies]
git-download.workspace = true
Expand Down
14 changes: 0 additions & 14 deletions gear-programs/bridging-payment-vara-supply/src/services/error.rs

This file was deleted.

Loading

0 comments on commit 19fb48b

Please sign in to comment.