Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Adding source to burnTransaction type #888

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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();
sameh-farouk marked this conversation as resolved.
Show resolved Hide resolved
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<
sameh-farouk marked this conversation as resolved.
Show resolved Hide resolved
_,
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;
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