Skip to content

Commit

Permalink
Fix: Adding source to burnTransaction type (#888)
Browse files Browse the repository at this point in the history
  • Loading branch information
sameh-farouk authored Nov 14, 2023
1 parent faaf0c9 commit ab138c8
Show file tree
Hide file tree
Showing 15 changed files with 290 additions and 41 deletions.
2 changes: 1 addition & 1 deletion bridge/tfchain_bridge/pkg/bridge/refund.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (bridge *Bridge) refund(ctx context.Context, destination string, amount int
cursor := tx.PagingToken()
log.Info().Msgf("saving cursor now %s", cursor)
if err = bridge.blockPersistency.SaveStellarCursor(cursor); err != nil {
log.Error().Msgf("error while saving cursor:", err.Error())
log.Error().Msgf("error while saving cursor: %s", err.Error())
return err
}
return nil
Expand Down
19 changes: 10 additions & 9 deletions bridge/tfchain_bridge/pkg/bridge/withdraw.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,19 @@ func (bridge *Bridge) handleWithdrawCreated(ctx context.Context, withdraw subpkg
}

func (bridge *Bridge) handleWithdrawExpired(ctx context.Context, withdrawExpired subpkg.WithdrawExpiredEvent) error {
if err := bridge.wallet.CheckAccount(withdrawExpired.Target); err != nil {
log.Info().Uint64("ID", uint64(withdrawExpired.ID)).Msg("tx is an invalid burn transaction, setting burn as executed since we have no way to recover...")
return bridge.subClient.RetrySetWithdrawExecuted(ctx, withdrawExpired.ID)
}
ok, source := withdrawExpired.Source.Unwrap()

signature, sequenceNumber, err := bridge.wallet.CreatePaymentAndReturnSignature(ctx, withdrawExpired.Target, withdrawExpired.Amount, withdrawExpired.ID)
if err != nil {
return err
if !ok {
// log and skip
return nil
}
log.Debug().Msgf("stellar account sequence number: %d", sequenceNumber)

return bridge.subClient.RetryProposeWithdrawOrAddSig(ctx, withdrawExpired.ID, withdrawExpired.Target, big.NewInt(int64(withdrawExpired.Amount)), signature, bridge.wallet.GetKeypair().Address(), sequenceNumber)
return bridge.handleWithdrawCreated(ctx, subpkg.WithdrawCreatedEvent{
ID: withdrawExpired.ID,
Source: source,
Target: withdrawExpired.Target,
Amount: withdrawExpired.Amount,
})
}

func (bridge *Bridge) handleWithdrawReady(ctx context.Context, withdrawReady subpkg.WithdrawReadyEvent) error {
Expand Down
2 changes: 2 additions & 0 deletions bridge/tfchain_bridge/pkg/substrate/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type WithdrawReadyEvent struct {

type WithdrawExpiredEvent struct {
ID uint64
Source types.OptionAccountID
Target string
Amount uint64
}
Expand Down Expand Up @@ -156,6 +157,7 @@ func (client *SubstrateClient) processEventRecords(events *substrate.EventRecord
log.Info().Uint64("ID", uint64(e.BurnTransactionID)).Msg("found burn transaction expired event")
withdrawExpiredEvents = append(withdrawExpiredEvents, WithdrawExpiredEvent{
ID: uint64(e.BurnTransactionID),
Source: e.Source,
Target: string(e.Target),
Amount: uint64(e.Amount),
})
Expand Down
11 changes: 6 additions & 5 deletions clients/tfchain-client-go/burning.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ var (
)

type BurnTransaction struct {
Block types.U32 `json:"block"`
Amount types.U64 `json:"amount"`
Target string `json:"target"`
Signatures []StellarSignature `json:"signatures"`
SequenceNumber types.U64 `json:"sequence_number"`
Block types.U32 `json:"block"`
Amount types.U64 `json:"amount"`
Source types.OptionAccountID `json:"source"`
Target string `json:"target"`
Signatures []StellarSignature `json:"signatures"`
SequenceNumber types.U64 `json:"sequence_number"`
}

func (s *Substrate) ProposeBurnTransactionOrAddSig(identity Identity, txID uint64, target string, amount *big.Int, signature string, stellarAddress string, sequence_number uint64) error {
Expand Down
7 changes: 4 additions & 3 deletions clients/tfchain-client-go/tft_bridge_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ type BridgeBurnTransactionCreated struct {
// BridgeBurnTransactionExpired
type BridgeBurnTransactionExpired struct {
Phase types.Phase
BurnTransactionID types.U64 `json:"burn_transaction_id"`
Target []byte `json:"target"`
Amount types.U64 `json:"amount"`
BurnTransactionID types.U64 `json:"burn_transaction_id"`
Source types.OptionAccountID `json:"source"`
Target []byte `json:"target"`
Amount types.U64 `json:"amount"`
Topics []types.Hash
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 16. Add Source account ID to BurnTransaction storage type and BurnTransactionExpired event

Date: 2023-11-14

## Status

Accepted

## Context

See [here](https://github.com/threefoldtech/tfchain/issues/883) for more details.

## Decision

Add `Source` account ID to `BurnTransaction` storage type and `BurnTransactionExpired` event and migrate previous `BurnTransactions` and `ExecutedBurnTransactions` storages
6 changes: 3 additions & 3 deletions substrate-node/pallets/pallet-tft-bridge/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![cfg(feature = "runtime-benchmarks")]

use super::{*, types::*};
use super::{types::*, *};
use crate::Pallet as TFTBridgeModule;
use frame_benchmarking::{account, benchmarks, whitelisted_caller};
use frame_support::assert_ok;
Expand Down Expand Up @@ -75,7 +75,7 @@ benchmarks! {
}: _(RawOrigin::Signed(caller.clone()), target_stellar_address.clone(), amount)
verify {
let burn_id = 1;
let tx = TFTBridgeModule::<T>::burn_transactions(burn_id);
let tx = TFTBridgeModule::<T>::burn_transactions(burn_id).unwrap();
assert_last_event::<T>(Event::BurnTransactionCreated(
burn_id,
caller,
Expand Down Expand Up @@ -195,7 +195,7 @@ benchmarks! {
));

let tx_id = 1;
let tx = TFTBridgeModule::<T>::burn_transactions(tx_id);
let tx = TFTBridgeModule::<T>::burn_transactions(tx_id).unwrap();

let validator: T::AccountId = account("Alice", 0, 0);
}: _(RawOrigin::Signed(validator), tx_id)
Expand Down
32 changes: 25 additions & 7 deletions substrate-node/pallets/pallet-tft-bridge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod tests;
#[cfg(feature = "runtime-benchmarks")]
pub mod benchmarking;

pub mod migrations;
mod tft_bridge;
mod types;
pub mod weights;
Expand All @@ -23,6 +24,7 @@ pub mod weights;
// through `construct_runtime`.
#[frame_support::pallet]
pub mod pallet {
use super::*;
use super::{
types::{BurnTransaction, MintTransaction, RefundTransaction, StellarSignature},
weights::WeightInfo,
Expand Down Expand Up @@ -75,13 +77,23 @@ pub mod pallet {

#[pallet::storage]
#[pallet::getter(fn burn_transactions)]
pub type BurnTransactions<T: Config> =
StorageMap<_, Blake2_128Concat, u64, BurnTransaction<T::BlockNumber>, ValueQuery>;
pub type BurnTransactions<T: Config> = StorageMap<
_,
Blake2_128Concat,
u64,
BurnTransaction<T::AccountId, T::BlockNumber>,
OptionQuery,
>;

#[pallet::storage]
#[pallet::getter(fn executed_burn_transactions)]
pub type ExecutedBurnTransactions<T: Config> =
StorageMap<_, Blake2_128Concat, u64, BurnTransaction<T::BlockNumber>, ValueQuery>;
pub type ExecutedBurnTransactions<T: Config> = StorageMap<
_,
Blake2_128Concat,
u64,
BurnTransaction<T::AccountId, T::BlockNumber>,
OptionQuery,
>;

#[pallet::storage]
#[pallet::getter(fn refund_transactions)]
Expand All @@ -105,6 +117,10 @@ pub mod pallet {
#[pallet::getter(fn deposit_fee)]
pub type DepositFee<T: Config> = StorageValue<_, u64, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn pallet_version)]
pub type PalletVersion<T> = StorageValue<_, types::StorageVersion, ValueQuery>;

#[pallet::config]
pub trait Config: frame_system::Config + pallet_balances::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
Expand Down Expand Up @@ -138,8 +154,8 @@ pub mod pallet {
BurnTransactionProposed(u64, Vec<u8>, u64),
BurnTransactionSignatureAdded(u64, StellarSignature),
BurnTransactionReady(u64),
BurnTransactionProcessed(BurnTransaction<T::BlockNumber>),
BurnTransactionExpired(u64, Vec<u8>, u64),
BurnTransactionProcessed(BurnTransaction<T::AccountId, T::BlockNumber>),
BurnTransactionExpired(u64, Option<T::AccountId>, Vec<u8>, u64),
// Refund events
RefundTransactionCreated(Vec<u8>, Vec<u8>, u64),
RefundTransactionsignatureAdded(Vec<u8>, StellarSignature),
Expand Down Expand Up @@ -229,7 +245,9 @@ pub mod pallet {
BurnTransactions::<T>::insert(&tx_id, &tx);

// Emit event
Self::deposit_event(Event::BurnTransactionExpired(tx_id, tx.target, tx.amount));
Self::deposit_event(Event::BurnTransactionExpired(
tx_id, tx.source, tx.target, tx.amount,
));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod types;
pub mod v2;
70 changes: 70 additions & 0 deletions substrate-node/pallets/pallet-tft-bridge/src/migrations/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
pub mod v1 {
use frame_support::{pallet_prelude::ValueQuery, storage_alias, Blake2_128Concat};
use parity_scale_codec::{Decode, Encode};
use scale_info::{prelude::vec::Vec, TypeInfo};

use crate::{types::StellarSignature, Config, Pallet};

#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)]
pub struct BurnTransaction<BlockNumber> {
pub block: BlockNumber,
pub amount: u64,
pub target: Vec<u8>,
pub signatures: Vec<StellarSignature>,
pub sequence_number: u64,
}

#[storage_alias]
pub type BurnTransactions<T: Config> = StorageMap<
Pallet<T>,
Blake2_128Concat,
u64,
BurnTransaction<<T as frame_system::Config>::BlockNumber>,
ValueQuery,
>;

#[storage_alias]
pub type ExecutedBurnTransactions<T: Config> = StorageMap<
Pallet<T>,
Blake2_128Concat,
u64,
BurnTransaction<<T as frame_system::Config>::BlockNumber>,
ValueQuery,
>;
}

pub mod v2 {
use frame_support::{pallet_prelude::OptionQuery, storage_alias, Blake2_128Concat};
use parity_scale_codec::{Decode, Encode};
use scale_info::{prelude::vec::Vec, TypeInfo};

use crate::{types::StellarSignature, Config, Pallet};

#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)]
pub struct BurnTransaction<AccountId, BlockNumber> {
pub block: BlockNumber,
pub amount: u64,
pub source: Option<AccountId>,
pub target: Vec<u8>,
pub signatures: Vec<StellarSignature>,
pub sequence_number: u64,
}

#[storage_alias]
pub type BurnTransactions<T: Config> = StorageMap<
Pallet<T>,
Blake2_128Concat,
u64,
BurnTransaction<<T as frame_system::Config>::AccountId, <T as frame_system::Config>::BlockNumber>,
OptionQuery,
>;

#[storage_alias]
pub type ExecutedBurnTransactions<T: Config> = StorageMap<
Pallet<T>,
Blake2_128Concat,
u64,
BurnTransaction<<T as frame_system::Config>::AccountId, <T as frame_system::Config>::BlockNumber>,
OptionQuery,
>;
}
117 changes: 117 additions & 0 deletions substrate-node/pallets/pallet-tft-bridge/src/migrations/v2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use crate::*;
use frame_support::log::{debug, info};
use frame_support::{traits::Get, traits::OnRuntimeUpgrade, weights::Weight};
use sp_std::marker::PhantomData;

#[cfg(feature = "try-runtime")]
use sp_std::vec::Vec;

pub struct MigrateBurnTransactionsV2<T: Config>(PhantomData<T>);

impl<T: Config> OnRuntimeUpgrade for MigrateBurnTransactionsV2<T> {
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, &'static str> {
info!("current pallet version: {:?}", PalletVersion::<T>::get());
if PalletVersion::<T>::get() != types::StorageVersion::V1 {
return Ok(Vec::<u8>::new());
};

let burn_transactions_count: u64 =
migrations::types::v1::BurnTransactions::<T>::iter().count() as u64;
info!(
"🔎 MigrateBurnTransactionsV2 pre migration: Number of existing burn transactions {:?}",
burn_transactions_count
);

let executed_burn_transactions_count: u64 =
migrations::types::v1::ExecutedBurnTransactions::<T>::iter().count() as u64;
info!(
"🔎 MigrateBurnTransactionsV2 pre migration: Number of existing executed burn transactions {:?}",
executed_burn_transactions_count
);

info!("👥 TFT-BRIDGE pallet to V1 passes PRE migrate checks ✅",);
return Ok(Vec::<u8>::new());
}

fn on_runtime_upgrade() -> Weight {
if PalletVersion::<T>::get() == types::StorageVersion::V1 {
migrate_burn_transactions::<T>()
} else {
info!(" >>> Unused TFT-BRIDGE pallet V2 migration");
Weight::zero()
}
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(_pre_burn_transactions_count: Vec<u8>) -> Result<(), &'static str> {
info!("current pallet version: {:?}", PalletVersion::<T>::get());
if PalletVersion::<T>::get() != types::StorageVersion::V2 {
return Ok(());
}
let burn_transactions_count: u64 = migrations::types::v2::BurnTransactions::<T>::iter().count() as u64;
info!(
"🔎 MigrateBurnTransactionsV2 post migration: Number of existing burn transactions {:?}",
burn_transactions_count
);

let executed_burn_transactions_count: u64 =
migrations::types::v2::ExecutedBurnTransactions::<T>::iter().count() as u64;
info!(
"🔎 MigrateBurnTransactionsV2 post migration: Number of existing executed burn transactions {:?}",
executed_burn_transactions_count
);

Ok(())
}
}

pub fn migrate_burn_transactions<T: Config>() -> frame_support::weights::Weight {
info!(" >>> Migrating burn transactions storage...");

let mut read_writes = 0;

migrations::types::v2::BurnTransactions::<T>::translate::<super::types::v1::BurnTransaction<T::BlockNumber>, _>(
|k, burn_transaction| {
debug!("migrated burn transaction: {:?}", k);

let new_burn_transaction = migrations::types::v2::BurnTransaction::<T::AccountId, T::BlockNumber> {
block: burn_transaction.block,
amount: burn_transaction.amount,
source: None,
target: burn_transaction.target,
signatures: burn_transaction.signatures,
sequence_number: burn_transaction.sequence_number,
};

read_writes += 1;
Some(new_burn_transaction)
},
);

migrations::types::v2::ExecutedBurnTransactions::<T>::translate::<super::types::v1::BurnTransaction<T::BlockNumber>, _>(
|k, executed_burn_transaction| {
debug!("migrated executed burn transaction: {:?}", k);

let new_executed_burn_transaction =
migrations::types::v2::BurnTransaction::<T::AccountId, T::BlockNumber> {
block: executed_burn_transaction.block,
amount: executed_burn_transaction.amount,
source: None,
target: executed_burn_transaction.target,
signatures: executed_burn_transaction.signatures,
sequence_number: executed_burn_transaction.sequence_number,
};

read_writes += 1;
Some(new_executed_burn_transaction)
},
);

// Update pallet storage version
PalletVersion::<T>::set(types::StorageVersion::V2);
info!(" <<< burnTransactions migration success, storage version upgraded");

// Return the weight consumed by the migration.
T::DbWeight::get().reads_writes(read_writes, read_writes + 1)
}
Loading

0 comments on commit ab138c8

Please sign in to comment.