Skip to content

Commit

Permalink
activeswap design and mock updates
Browse files Browse the repository at this point in the history
  • Loading branch information
cde8 committed Jun 14, 2024
1 parent a6333e9 commit da0a58c
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 48 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions protocol-units/bridge/shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ rust-version.workspace = true

[dependencies]
async-trait = "0.1.80"
delegate = "0.12.0"
derive_more = { workspace = true, features = ["deref"] }
futures.workspace = true
thiserror.workspace = true
Expand Down
5 changes: 3 additions & 2 deletions protocol-units/bridge/shared/src/blockchain_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
BridgeContractCounterpartyEvent, BridgeContractCounterpartyMonitoring,
BridgeContractInitiatorEvent, BridgeContractInitiatorMonitoring,
},
types::{BridgeAddressType, BridgeHashType},
};

#[derive(Debug, PartialEq, Eq)]
Expand All @@ -19,8 +20,8 @@ pub enum BlockchainEvent<A, H> {
pub trait BlockchainService:
Stream<Item = BlockchainEvent<Self::Address, Self::Hash>> + Unpin
{
type Address: std::fmt::Debug;
type Hash: std::fmt::Debug;
type Address: BridgeAddressType;
type Hash: BridgeHashType;

type InitiatorContract: BridgeContractInitiator;
type InitiatorMonitoring: BridgeContractInitiatorMonitoring<Address = Self::Address, Hash = Self::Hash>
Expand Down
4 changes: 2 additions & 2 deletions protocol-units/bridge/shared/src/bridge_contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub enum BridgeContractError {
pub type BridgeContractResult<T> = Result<T, BridgeContractError>;

#[async_trait::async_trait]
pub trait BridgeContractInitiator {
pub trait BridgeContractInitiator: Clone + Unpin {
type Address;
type Hash;

Expand Down Expand Up @@ -50,7 +50,7 @@ pub trait BridgeContractInitiator {
}

#[async_trait::async_trait]
pub trait BridgeContractCounterparty {
pub trait BridgeContractCounterparty: Clone + Unpin {
type Address;
type Hash;

Expand Down
69 changes: 55 additions & 14 deletions protocol-units/bridge/shared/src/bridge_service.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
use futures::{Stream, StreamExt};
use std::pin::Pin;
use std::task::{Context, Poll};
use tracing::{trace, warn};

use crate::blockchain_service::{BlockchainEvent, BlockchainService};
use tracing::debug;
use crate::{
blockchain_service::{BlockchainEvent, BlockchainService},
bridge_monitoring::BridgeContractInitiatorEvent,
};

pub mod active_swap;

use self::active_swap::ActiveSwapMap;

pub struct BridgeService<B1, B2>
where
Expand All @@ -12,6 +19,11 @@ where
{
pub blockchain_1: B1,
pub blockchain_2: B2,

pub active_swaps_b1_to_b2:
ActiveSwapMap<B1::Address, B1::Hash, B1::InitiatorContract, B2::CounterpartyContract>,
pub active_swaps_b2_to_b1:
ActiveSwapMap<B2::Address, B2::Hash, B2::InitiatorContract, B1::CounterpartyContract>,
}

impl<B1, B2> BridgeService<B1, B2>
Expand All @@ -20,7 +32,18 @@ where
B2: BlockchainService,
{
pub fn new(blockchain_1: B1, blockchain_2: B2) -> Self {
Self { blockchain_1, blockchain_2 }
Self {
active_swaps_b1_to_b2: ActiveSwapMap::build(
blockchain_1.initiator_contract().clone(),
blockchain_2.counterparty_contract().clone(),
),
active_swaps_b2_to_b1: ActiveSwapMap::build(
blockchain_2.initiator_contract().clone(),
blockchain_1.counterparty_contract().clone(),
),
blockchain_1,
blockchain_2,
}
}
}

Expand All @@ -36,41 +59,59 @@ where

match this.blockchain_1.poll_next_unpin(cx) {
Poll::Ready(Some(event)) => {
debug!("BridgeService: Received event from blockchain service 1: {:?}", event);
trace!("BridgeService: Received event from blockchain service 1: {:?}", event);
match event {
BlockchainEvent::InitiatorEvent(_) => {
debug!("BridgeService: Initiator event from blockchain service 1");
BlockchainEvent::InitiatorEvent(event) => {
trace!("BridgeService: Initiator event from blockchain service 1");
match event {
BridgeContractInitiatorEvent::BridgeTransferInitiated(details) => {
// bridge transfer initiated, now as the counterparty we should lock
// the appropriate tokens using the same secret
if this
.active_swaps_b1_to_b2
.already_executing(&details.bridge_transfer_id)
{
warn!("BridgeService: Bridge transfer {:?} already initiated, monitoring should only return once", details.bridge_transfer_id);
return Poll::Pending;
}

// start the active swap
this.active_swaps_b1_to_b2.start(details);
}
BridgeContractInitiatorEvent::BridgeTransferCompleted(_) => todo!(),
BridgeContractInitiatorEvent::BridgeTransferRefunded(_) => todo!(),
}
}
BlockchainEvent::CounterpartyEvent(_) => {
debug!("BridgeService: Counterparty event from blockchain service 1");
trace!("BridgeService: Counterparty event from blockchain service 1");
}
}
}
Poll::Ready(None) => {
debug!("BridgeService: Blockchain service 1 has no more events");
trace!("BridgeService: Blockchain service 1 has no more events");
}
Poll::Pending => {
debug!("BridgeService: Blockchain service 1 has no events at this time");
trace!("BridgeService: Blockchain service 1 has no events at this time");
}
}

match this.blockchain_2.poll_next_unpin(cx) {
Poll::Ready(Some(event)) => {
debug!("BridgeService: Received event from blockchain service 2: {:?}", event);
trace!("BridgeService: Received event from blockchain service 2: {:?}", event);
match event {
BlockchainEvent::InitiatorEvent(_) => {
debug!("BridgeService: Initiator event from blockchain service 2");
trace!("BridgeService: Initiator event from blockchain service 2");
}
BlockchainEvent::CounterpartyEvent(_) => {
debug!("BridgeService: Counterparty event from blockchain service 2");
trace!("BridgeService: Counterparty event from blockchain service 2");
}
}
}
Poll::Ready(None) => {
debug!("BridgeService: Blockchain service 2 has no more events");
trace!("BridgeService: Blockchain service 2 has no more events");
}
Poll::Pending => {
debug!("BridgeService: Blockchain service 2 has no events at this time");
trace!("BridgeService: Blockchain service 2 has no events at this time");
}
}

Expand Down
53 changes: 53 additions & 0 deletions protocol-units/bridge/shared/src/bridge_service/active_swap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use std::{collections::HashMap, pin::Pin};

use futures::Future;

use crate::types::{BridgeAddressType, BridgeHashType, BridgeTransferDetails, BridgeTransferId};

pub type BoxedBridgeServiceFuture = Pin<Box<dyn Future<Output = ()> + Send>>;

/// Bridge state in the sense of tracking the active swaps from the bridge
pub enum ActiveSwap<BFromA, BFromH> {
/// Bridge is locking lockens on the counterpart chain
LockingTokens(BridgeTransferDetails<BFromA, BFromH>, BoxedBridgeServiceFuture),
/// Bridge is waiting for the initiator to complete her transfer
/// revealing her secret.
WaitingForCompletedEvent(BridgeTransferId<BFromH>),
/// We are in possession of the secret and are now completing the bridge tranfer on our side
CompletingBridging(BoxedBridgeServiceFuture),
/// We have completed the atomic bdridge transfer
Completed,
}

pub struct ActiveSwapMap<BFromA, BFromH, BFromCI, BToCC> {
pub initiator_contract: BFromCI,
pub counterparty_contract: BToCC,
swaps: HashMap<BridgeTransferId<BFromH>, ActiveSwap<BFromA, BFromH>>,
}

impl<BFromA, BFromH, BFromCI, BToCC> ActiveSwapMap<BFromA, BFromH, BFromCI, BToCC>
where
BFromH: BridgeHashType,
BFromA: BridgeAddressType,
{
pub fn build(initiator_contract: BFromCI, counterparty_contract: BToCC) -> Self {
Self { initiator_contract, counterparty_contract, swaps: HashMap::new() }
}

pub fn get(&self, key: &BridgeTransferId<BFromH>) -> Option<&ActiveSwap<BFromA, BFromH>> {
self.swaps.get(key)
}

pub fn already_executing(&self, key: &BridgeTransferId<BFromH>) -> bool {
self.swaps.contains_key(key)
}

pub fn start(&mut self, details: BridgeTransferDetails<BFromA, BFromH>) {
assert!(self.swaps.get(&details.bridge_transfer_id).is_none());

self.swaps.insert(
details.bridge_transfer_id.clone(),
ActiveSwap::LockingTokens(details, Box::pin(async move {})),
);
}
}
Loading

0 comments on commit da0a58c

Please sign in to comment.