Skip to content

Commit

Permalink
update transfers to initiate and then confirm once XDM is confirmed.
Browse files Browse the repository at this point in the history
  • Loading branch information
vedhavyas committed Feb 15, 2024
1 parent 93957e1 commit 799b68c
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 77 deletions.
66 changes: 50 additions & 16 deletions crates/pallet-domains/src/block_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ use scale_info::TypeInfo;
use sp_core::Get;
use sp_domains::merkle_tree::MerkleTree;
use sp_domains::{
ConfirmedDomainBlock, DomainId, DomainsTransfersTracker, ExecutionReceipt, OperatorId,
ChainId, ConfirmedDomainBlock, DomainId, DomainsTransfersTracker, ExecutionReceipt, OperatorId,
Transfers,
};
use sp_runtime::traits::{BlockNumberProvider, CheckedAdd, CheckedSub, One, Saturating, Zero};
use sp_runtime::traits::{BlockNumberProvider, CheckedSub, One, Saturating, Zero};
use sp_std::cmp::Ordering;
use sp_std::collections::btree_map::BTreeMap;
use sp_std::vec::Vec;
Expand Down Expand Up @@ -348,26 +349,14 @@ pub(crate) fn process_execution_receipt<T: Config>(
execution_receipt.consensus_block_number,
);

// tracking the transfer
// 1. Block fees are burned on domain, so it is considered transferred out
// 2. XDM transfers from the Domain
// 3. XDM transfers into the domain
let transfer_out_balance = execution_receipt
let block_fees = execution_receipt
.block_fees
.total_fees()
.and_then(|total| total.checked_add(&execution_receipt.transfers.transfers_out))
.ok_or(Error::BalanceOverflow)?;

// track the transfers out and then track transfers in
T::DomainsTransfersTracker::transfer_out(domain_id, transfer_out_balance)
update_domain_transfers::<T>(domain_id, &execution_receipt.transfers, block_fees)
.map_err(|_| Error::DomainTransfersTracking)?;

T::DomainsTransfersTracker::transfer_in(
domain_id,
execution_receipt.transfers.transfers_in,
)
.map_err(|_| Error::DomainTransfersTracking)?;

LatestConfirmedDomainBlock::<T>::insert(
domain_id,
ConfirmedDomainBlock {
Expand Down Expand Up @@ -404,6 +393,51 @@ pub(crate) fn process_execution_receipt<T: Config>(
Ok(None)
}

type TransferTrackerError<T> =
<<T as Config>::DomainsTransfersTracker as DomainsTransfersTracker<BalanceOf<T>>>::Error;

/// Updates domain transfers for following scenarios
/// 1. Block fees are burned on domain
/// 2. Confirming incoming XDM transfers to the Domain
/// 3. Noting outgoing transfers from the domain
/// 4. Cancelling outgoing transfers from the domain.
fn update_domain_transfers<T: Config>(
domain_id: DomainId,
transfers: &Transfers<BalanceOf<T>>,
block_fees: BalanceOf<T>,
) -> Result<(), TransferTrackerError<T>> {
let Transfers {
transfers_in,
transfers_out,
transfers_reverted,
} = transfers;

// confirm incoming transfers
let er_chain_id = ChainId::Domain(domain_id);
transfers_in
.iter()
.try_for_each(|(from_chain_id, amount)| {
T::DomainsTransfersTracker::confirm_transfer(*from_chain_id, er_chain_id, *amount)
})?;

// note outgoing transfers
transfers_out.iter().try_for_each(|(to_chain_id, amount)| {
T::DomainsTransfersTracker::note_transfer(er_chain_id, *to_chain_id, *amount)
})?;

// cancel existing transfers
transfers_reverted
.iter()
.try_for_each(|(to_chain_id, amount)| {
T::DomainsTransfersTracker::cancel_transfer(er_chain_id, *to_chain_id, *amount)
})?;

// deduct execution fees from domain
T::DomainsTransfersTracker::reduce_domain_balance(domain_id, block_fees)?;

Ok(())
}

fn add_new_receipt_to_block_tree<T: Config>(
domain_id: DomainId,
submitter: OperatorId,
Expand Down
2 changes: 1 addition & 1 deletion crates/pallet-domains/src/domain_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ pub(crate) fn do_instantiate_domain<T: Config>(
)
.map_err(|_| Error::InsufficientFund)?;

T::DomainsTransfersTracker::transfer_in(domain_id, total_issuance)
T::DomainsTransfersTracker::initialize_domain_balance(domain_id, total_issuance)
.map_err(|_| Error::TransfersTracker)?;

let genesis_receipt = {
Expand Down
33 changes: 28 additions & 5 deletions crates/pallet-domains/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use sp_domains::merkle_tree::MerkleTree;
use sp_domains::proof_provider_and_verifier::StorageProofProvider;
use sp_domains::storage::RawGenesis;
use sp_domains::{
BundleHeader, DomainId, DomainsHoldIdentifier, ExecutionReceipt, ExtrinsicDigest,
BundleHeader, ChainId, DomainId, DomainsHoldIdentifier, ExecutionReceipt, ExtrinsicDigest,
InboxedBundle, InvalidBundleType, OpaqueBundle, OperatorAllowList, OperatorId, OperatorPair,
ProofOfElection, RuntimeType, SealedBundleHeader, StakingHoldIdentifier,
};
Expand Down Expand Up @@ -230,15 +230,38 @@ pub struct MockDomainsTransfersTracker;
impl sp_domains::DomainsTransfersTracker<Balance> for MockDomainsTransfersTracker {
type Error = ();

fn balance_on_domain(_domain_id: DomainId) -> Result<Balance, Self::Error> {
Ok(Default::default())
fn initialize_domain_balance(
_domain_id: DomainId,
_amount: Balance,
) -> Result<(), Self::Error> {
Ok(())
}

fn note_transfer(
_from_chain_id: ChainId,
_to_chain_id: ChainId,
_amount: Balance,
) -> Result<(), Self::Error> {
Ok(())
}

fn confirm_transfer(
_from_chain_id: ChainId,
_to_chain_id: ChainId,
_amount: Balance,
) -> Result<(), Self::Error> {
Ok(())
}

fn transfer_in(_domain_id: DomainId, _amount: Balance) -> Result<(), Self::Error> {
fn cancel_transfer(
_from_chain_id: ChainId,
_to_chain_id: ChainId,
_amount: Balance,
) -> Result<(), Self::Error> {
Ok(())
}

fn transfer_out(_domain_id: DomainId, _amount: Balance) -> Result<(), Self::Error> {
fn reduce_domain_balance(_domain_id: DomainId, _amount: Balance) -> Result<(), Self::Error> {
Ok(())
}
}
Expand Down
49 changes: 39 additions & 10 deletions crates/sp-domains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,14 @@ impl ChainId {
ChainId::Domain(_) => false,
}
}

#[inline]
pub fn maybe_domain_chain(&self) -> Option<DomainId> {
match self {
ChainId::Consensus => None,
ChainId::Domain(domain_id) => Some(*domain_id),
}
}
}

impl From<u32> for ChainId {
Expand Down Expand Up @@ -280,9 +288,11 @@ where
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone, Default)]
pub struct Transfers<Balance> {
/// Total transfers that came into the domain.
pub transfers_in: Balance,
pub transfers_in: BTreeMap<ChainId, Balance>,
/// Total transfers that went out of the domain.
pub transfers_out: Balance,
pub transfers_out: BTreeMap<ChainId, Balance>,
/// Total transfers from this domain that were reverted.
pub transfers_reverted: BTreeMap<ChainId, Balance>,
}

#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
Expand Down Expand Up @@ -1100,14 +1110,33 @@ impl ExtrinsicDigest {
pub trait DomainsTransfersTracker<Balance> {
type Error;

/// Marks transfer into domain.
fn transfer_in(domain_id: DomainId, amount: Balance) -> Result<(), Self::Error>;

/// Marks a transfer from domain.
fn transfer_out(domain_id: DomainId, amount: Balance) -> Result<(), Self::Error>;

/// Returns the total balance on domain.
fn balance_on_domain(domain_id: DomainId) -> Result<Balance, Self::Error>;
/// Initializes the domain balance
fn initialize_domain_balance(domain_id: DomainId, amount: Balance) -> Result<(), Self::Error>;

/// Notes a transfer between chains.
/// Balance on from_chain_id is reduced if it is a domain chain
fn note_transfer(
from_chain_id: ChainId,
to_chain_id: ChainId,
amount: Balance,
) -> Result<(), Self::Error>;

/// Confirms a transfer between chains.
fn confirm_transfer(
from_chain_id: ChainId,
to_chain_id: ChainId,
amount: Balance,
) -> Result<(), Self::Error>;

/// Cancels an initiated transfer between chains.
fn cancel_transfer(
from_chain_id: ChainId,
to_chain_id: ChainId,
amount: Balance,
) -> Result<(), Self::Error>;

/// Reduces a given amount from the domain balance
fn reduce_domain_balance(domain_id: DomainId, amount: Balance) -> Result<(), Self::Error>;
}

pub type ExecutionReceiptFor<DomainHeader, CBlock, Balance> = ExecutionReceipt<
Expand Down
10 changes: 6 additions & 4 deletions domains/client/domain-operator/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use sp_domain_digests::AsPredigest;
use sp_domains::core_api::DomainCoreApi;
use sp_domains::merkle_tree::MerkleTree;
use sp_domains::{
Bundle, BundleValidity, DomainsApi, HeaderHashingFor, InboxedBundle, InvalidBundleType,
Transfers,
Bundle, BundleValidity, ChainId, DomainsApi, HeaderHashingFor, InboxedBundle,
InvalidBundleType, Transfers,
};
use sp_domains_fraud_proof::fraud_proof::{
ApplyExtrinsicMismatch, ExecutionPhase, FinalizeBlockMismatch, FraudProof,
Expand All @@ -41,6 +41,7 @@ use sp_runtime::traits::{BlakeTwo256, Block as BlockT, Hash as HashT, Header as
use sp_runtime::transaction_validity::InvalidTransaction;
use sp_runtime::OpaqueExtrinsic;
use sp_state_machine::backend::AsTrieBackend;
use std::collections::BTreeMap;
use std::sync::Arc;
use subspace_core_primitives::PotOutput;
use subspace_runtime_primitives::opaque::Block as CBlock;
Expand Down Expand Up @@ -2017,8 +2018,9 @@ async fn test_invalid_transfers_fraud_proof() {
let mut opaque_bundle = bundle.unwrap();
let receipt = &mut opaque_bundle.sealed_header.header.receipt;
receipt.transfers = Transfers {
transfers_in: 10 * SSC,
transfers_out: 20 * SSC,
transfers_in: BTreeMap::from([(ChainId::Consensus, 10 * SSC)]),
transfers_out: BTreeMap::from([(ChainId::Consensus, 10 * SSC)]),
transfers_reverted: Default::default(),
};
opaque_bundle.sealed_header.signature = Sr25519Keyring::Alice
.pair()
Expand Down
Loading

0 comments on commit 799b68c

Please sign in to comment.