Skip to content

Commit

Permalink
Tendermint htlc implementation on IRIS #1432 (#1454)
Browse files Browse the repository at this point in the history
* create iris coin instance and execute `my_balance`

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* save development state

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* implement htlc for iris network

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* implement `hash_lock` generation in p.o.c test

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* save htlc claiming P.O.C state

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* update target address for htlc transactions

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* save htlc p.o.c(on IBC asset) work state

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* add doc-comments to iris/htlc.rs

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* save development state

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* save development state

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* save development state

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* update structs privacy of iris/htlc module

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* apply some beauty

Signed-off-by: ozkanonur <work@onurozkan.dev>

* Exclude p.o.c derive attributes that are no longer required

Signed-off-by: ozkanonur <work@onurozkan.dev>

* update annotation style

Signed-off-by: ozkanonur <work@onurozkan.dev>

* fix code formatting

Signed-off-by: ozkanonur <work@onurozkan.dev>

* fix review notes

Signed-off-by: ozkanonur <work@onurozkan.dev>

* make `any_to_signed_raw_tx` sync

Signed-off-by: ozkanonur <work@onurozkan.dev>

* drop mutability of `hash_lock_hash`

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* fix review note

Signed-off-by: Onur Özkan <work@onurozkan.dev>

Signed-off-by: Onur Özkan <work@onurozkan.dev>
Signed-off-by: ozkanonur <work@onurozkan.dev>
  • Loading branch information
onur-ozkan authored and borngraced committed Sep 11, 2022
1 parent b7ec1c1 commit bc6d9e8
Show file tree
Hide file tree
Showing 4 changed files with 443 additions and 19 deletions.
175 changes: 175 additions & 0 deletions mm2src/coins/tendermint/iris/htlc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
// IRIS HTLC implementation in Rust on top of Cosmos SDK(cosmrs) for AtomicDEX.
//
// This module includes HTLC creating & claiming representation structstures
// and their trait implementations.
//
// ** Acquiring testnet assets **
//
// Since there is no sdk exists for Rust on Iris Network, we should
// either implement some of the Iris Network funcionality on Rust or
// simply use their unit tests.
//
// Because we had limited time for the HTLC implementation, for now
// we can use their unit tests in order to acquire IBC assets.
// For that, clone https://github.com/ozkanonur/irishub-sdk-js repository and check
// dummy.test.ts file(change the asset, amount, target address if needed)
// and then run the following commands:
// - yarn
// - npm run test
//
// If the sender address doesn't have enough nyan tokens to complete unit tests,
// check this page https://www.irisnet.org/docs/get-started/testnet.html#faucet

use super::htlc_proto::{ClaimHtlcProtoRep, CreateHtlcProtoRep};
use cosmrs::{tx::{Fee, Msg, MsgProto},
AccountId, Coin, ErrorReport};
use std::convert::TryFrom;

const CREATE_HTLC_TYPE_URL: &str = "/irismod.htlc.MsgCreateHTLC";
const CLAIM_HTLC_TYPE_URL: &str = "/irismod.htlc.MsgClaimHTLC";

#[allow(dead_code)]
pub(crate) struct IrisHtlc {
/// Generated HTLC's ID.
pub(crate) id: String,

/// Transaction fee
pub(crate) fee: Fee,

/// Message payload to be sent
pub(crate) msg_payload: cosmrs::Any,
}

#[derive(Clone)]
pub(crate) struct MsgCreateHtlc {
/// Sender's address.
pub(crate) to: AccountId,

/// Recipient's address.
pub(crate) sender: AccountId,

/// The claim receiving address on the other chain.
pub(crate) receiver_on_other_chain: String,

/// The counterparty creator address on the other chain.
pub(crate) sender_on_other_chain: String,

/// Amount to send.
pub(crate) amount: Vec<Coin>,

/// The sha256 hash generated from secret and timestamp.
pub(crate) hash_lock: String,

/// The number of blocks to wait before the asset may be returned to.
pub(crate) time_lock: u64,

/// The timestamp in seconds for generating hash lock if provided.
pub(crate) timestamp: u64,

/// Whether it is an HTLT transaction.
pub(crate) transfer: bool,
}

impl Msg for MsgCreateHtlc {
type Proto = CreateHtlcProtoRep;
}

impl TryFrom<CreateHtlcProtoRep> for MsgCreateHtlc {
type Error = ErrorReport;

fn try_from(proto: CreateHtlcProtoRep) -> Result<MsgCreateHtlc, Self::Error> { MsgCreateHtlc::try_from(&proto) }
}

impl TryFrom<&CreateHtlcProtoRep> for MsgCreateHtlc {
type Error = ErrorReport;

fn try_from(proto: &CreateHtlcProtoRep) -> Result<MsgCreateHtlc, Self::Error> {
Ok(MsgCreateHtlc {
sender: proto.sender.parse()?,
to: proto.to.parse()?,
amount: proto.amount.iter().map(TryFrom::try_from).collect::<Result<_, _>>()?,
receiver_on_other_chain: proto.receiver_on_other_chain.clone(),
sender_on_other_chain: proto.sender_on_other_chain.clone(),
hash_lock: proto.hash_lock.clone(),
timestamp: proto.timestamp,
time_lock: proto.time_lock,
transfer: proto.transfer,
})
}
}

impl From<MsgCreateHtlc> for CreateHtlcProtoRep {
fn from(coin: MsgCreateHtlc) -> CreateHtlcProtoRep { CreateHtlcProtoRep::from(&coin) }
}

impl From<&MsgCreateHtlc> for CreateHtlcProtoRep {
fn from(msg: &MsgCreateHtlc) -> CreateHtlcProtoRep {
CreateHtlcProtoRep {
sender: msg.sender.to_string(),
to: msg.to.to_string(),
amount: msg.amount.iter().map(Into::into).collect(),
receiver_on_other_chain: msg.receiver_on_other_chain.clone(),
sender_on_other_chain: msg.sender_on_other_chain.clone(),
hash_lock: msg.hash_lock.clone(),
timestamp: msg.timestamp,
time_lock: msg.time_lock,
transfer: msg.transfer,
}
}
}

impl MsgProto for CreateHtlcProtoRep {
const TYPE_URL: &'static str = CREATE_HTLC_TYPE_URL;
}

#[derive(Clone)]
pub(crate) struct MsgClaimHtlc {
/// Sender's address.
pub(crate) sender: AccountId,

/// Generated HTLC ID
pub(crate) id: String,

/// Secret that has been used for generating hash_lock
pub(crate) secret: String,
}

impl Msg for MsgClaimHtlc {
type Proto = ClaimHtlcProtoRep;
}

impl TryFrom<ClaimHtlcProtoRep> for MsgClaimHtlc {
type Error = ErrorReport;

fn try_from(proto: ClaimHtlcProtoRep) -> Result<MsgClaimHtlc, Self::Error> { MsgClaimHtlc::try_from(&proto) }
}

impl TryFrom<&ClaimHtlcProtoRep> for MsgClaimHtlc {
type Error = ErrorReport;

fn try_from(proto: &ClaimHtlcProtoRep) -> Result<MsgClaimHtlc, Self::Error> {
Ok(MsgClaimHtlc {
sender: proto.sender.parse()?,
id: proto.id.clone(),
secret: proto.secret.clone(),
})
}
}

impl From<MsgClaimHtlc> for ClaimHtlcProtoRep {
fn from(coin: MsgClaimHtlc) -> ClaimHtlcProtoRep { ClaimHtlcProtoRep::from(&coin) }
}

impl From<&MsgClaimHtlc> for ClaimHtlcProtoRep {
fn from(msg: &MsgClaimHtlc) -> ClaimHtlcProtoRep {
ClaimHtlcProtoRep {
sender: msg.sender.to_string(),
id: msg.id.clone(),
secret: msg.secret.clone(),
}
}
}

impl MsgProto for ClaimHtlcProtoRep {
const TYPE_URL: &'static str = CLAIM_HTLC_TYPE_URL;
}
31 changes: 31 additions & 0 deletions mm2src/coins/tendermint/iris/htlc_proto.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#[derive(prost::Message)]
pub(crate) struct CreateHtlcProtoRep {
#[prost(string, tag = "1")]
pub(crate) sender: prost::alloc::string::String,
#[prost(string, tag = "2")]
pub(crate) to: prost::alloc::string::String,
#[prost(string, tag = "3")]
pub(crate) receiver_on_other_chain: prost::alloc::string::String,
#[prost(string, tag = "4")]
pub(crate) sender_on_other_chain: prost::alloc::string::String,
#[prost(message, repeated, tag = "5")]
pub(crate) amount: prost::alloc::vec::Vec<cosmrs::proto::cosmos::base::v1beta1::Coin>,
#[prost(string, tag = "6")]
pub(crate) hash_lock: prost::alloc::string::String,
#[prost(uint64, tag = "7")]
pub(crate) timestamp: u64,
#[prost(uint64, tag = "8")]
pub(crate) time_lock: u64,
#[prost(bool, tag = "9")]
pub(crate) transfer: bool,
}

#[derive(prost::Message)]
pub(crate) struct ClaimHtlcProtoRep {
#[prost(string, tag = "1")]
pub(crate) sender: prost::alloc::string::String,
#[prost(string, tag = "2")]
pub(crate) id: prost::alloc::string::String,
#[prost(string, tag = "3")]
pub(crate) secret: prost::alloc::string::String,
}
9 changes: 6 additions & 3 deletions mm2src/coins/tendermint/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/// Module implementing Tendermint (Cosmos) integration
/// Useful resources
/// https://docs.cosmos.network/
// Module implementing Tendermint (Cosmos) integration
// Useful resources
// https://docs.cosmos.network/

#[path = "iris/htlc.rs"] mod htlc;
#[path = "iris/htlc_proto.rs"] mod htlc_proto;
mod tendermint_coin;
#[cfg(not(target_arch = "wasm32"))] mod tendermint_native_rpc;
#[cfg(target_arch = "wasm32")] mod tendermint_wasm_rpc;
Expand Down
Loading

0 comments on commit bc6d9e8

Please sign in to comment.