From ab138c8bc20a2e652a071fade4adaf56a45aeb7f Mon Sep 17 00:00:00 2001 From: Sameh Abouel-saad Date: Tue, 14 Nov 2023 21:22:00 +0200 Subject: [PATCH] Fix: Adding source to burnTransaction type (#888) --- bridge/tfchain_bridge/pkg/bridge/refund.go | 2 +- bridge/tfchain_bridge/pkg/bridge/withdraw.go | 19 +-- bridge/tfchain_bridge/pkg/substrate/events.go | 2 + clients/tfchain-client-go/burning.go | 11 +- .../tfchain-client-go/tft_bridge_events.go | 7 +- ...nsaction-BurnTransactionExpired-changed.md | 15 +++ .../pallet-tft-bridge/src/benchmarking.rs | 6 +- .../pallets/pallet-tft-bridge/src/lib.rs | 32 +++-- .../pallet-tft-bridge/src/migrations/mod.rs | 2 + .../pallet-tft-bridge/src/migrations/types.rs | 70 +++++++++++ .../pallet-tft-bridge/src/migrations/v2.rs | 117 ++++++++++++++++++ .../pallets/pallet-tft-bridge/src/tests.rs | 14 +-- .../pallet-tft-bridge/src/tft_bridge.rs | 16 ++- .../pallets/pallet-tft-bridge/src/types.rs | 16 ++- substrate-node/runtime/src/lib.rs | 2 +- 15 files changed, 290 insertions(+), 41 deletions(-) create mode 100644 docs/architecture/0016-BurnTransaction-BurnTransactionExpired-changed.md create mode 100644 substrate-node/pallets/pallet-tft-bridge/src/migrations/mod.rs create mode 100644 substrate-node/pallets/pallet-tft-bridge/src/migrations/types.rs create mode 100644 substrate-node/pallets/pallet-tft-bridge/src/migrations/v2.rs diff --git a/bridge/tfchain_bridge/pkg/bridge/refund.go b/bridge/tfchain_bridge/pkg/bridge/refund.go index 7f69f882d..ffa2e055a 100644 --- a/bridge/tfchain_bridge/pkg/bridge/refund.go +++ b/bridge/tfchain_bridge/pkg/bridge/refund.go @@ -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 diff --git a/bridge/tfchain_bridge/pkg/bridge/withdraw.go b/bridge/tfchain_bridge/pkg/bridge/withdraw.go index 7706ab892..0dc82961b 100644 --- a/bridge/tfchain_bridge/pkg/bridge/withdraw.go +++ b/bridge/tfchain_bridge/pkg/bridge/withdraw.go @@ -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 { diff --git a/bridge/tfchain_bridge/pkg/substrate/events.go b/bridge/tfchain_bridge/pkg/substrate/events.go index 069efa872..44be57afd 100644 --- a/bridge/tfchain_bridge/pkg/substrate/events.go +++ b/bridge/tfchain_bridge/pkg/substrate/events.go @@ -37,6 +37,7 @@ type WithdrawReadyEvent struct { type WithdrawExpiredEvent struct { ID uint64 + Source types.OptionAccountID Target string Amount uint64 } @@ -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), }) diff --git a/clients/tfchain-client-go/burning.go b/clients/tfchain-client-go/burning.go index 8d575fd16..03489df4f 100644 --- a/clients/tfchain-client-go/burning.go +++ b/clients/tfchain-client-go/burning.go @@ -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 { diff --git a/clients/tfchain-client-go/tft_bridge_events.go b/clients/tfchain-client-go/tft_bridge_events.go index d8bfacd8e..12b7b8d07 100644 --- a/clients/tfchain-client-go/tft_bridge_events.go +++ b/clients/tfchain-client-go/tft_bridge_events.go @@ -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 } diff --git a/docs/architecture/0016-BurnTransaction-BurnTransactionExpired-changed.md b/docs/architecture/0016-BurnTransaction-BurnTransactionExpired-changed.md new file mode 100644 index 000000000..f1a441016 --- /dev/null +++ b/docs/architecture/0016-BurnTransaction-BurnTransactionExpired-changed.md @@ -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 diff --git a/substrate-node/pallets/pallet-tft-bridge/src/benchmarking.rs b/substrate-node/pallets/pallet-tft-bridge/src/benchmarking.rs index 938b4a1a4..6420d5205 100644 --- a/substrate-node/pallets/pallet-tft-bridge/src/benchmarking.rs +++ b/substrate-node/pallets/pallet-tft-bridge/src/benchmarking.rs @@ -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; @@ -75,7 +75,7 @@ benchmarks! { }: _(RawOrigin::Signed(caller.clone()), target_stellar_address.clone(), amount) verify { let burn_id = 1; - let tx = TFTBridgeModule::::burn_transactions(burn_id); + let tx = TFTBridgeModule::::burn_transactions(burn_id).unwrap(); assert_last_event::(Event::BurnTransactionCreated( burn_id, caller, @@ -195,7 +195,7 @@ benchmarks! { )); let tx_id = 1; - let tx = TFTBridgeModule::::burn_transactions(tx_id); + let tx = TFTBridgeModule::::burn_transactions(tx_id).unwrap(); let validator: T::AccountId = account("Alice", 0, 0); }: _(RawOrigin::Signed(validator), tx_id) diff --git a/substrate-node/pallets/pallet-tft-bridge/src/lib.rs b/substrate-node/pallets/pallet-tft-bridge/src/lib.rs index c4533b4d1..410c5d0a8 100644 --- a/substrate-node/pallets/pallet-tft-bridge/src/lib.rs +++ b/substrate-node/pallets/pallet-tft-bridge/src/lib.rs @@ -15,6 +15,7 @@ mod tests; #[cfg(feature = "runtime-benchmarks")] pub mod benchmarking; +pub mod migrations; mod tft_bridge; mod types; pub mod weights; @@ -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, @@ -75,13 +77,23 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn burn_transactions)] - pub type BurnTransactions = - StorageMap<_, Blake2_128Concat, u64, BurnTransaction, ValueQuery>; + pub type BurnTransactions = StorageMap< + _, + Blake2_128Concat, + u64, + BurnTransaction, + OptionQuery, + >; #[pallet::storage] #[pallet::getter(fn executed_burn_transactions)] - pub type ExecutedBurnTransactions = - StorageMap<_, Blake2_128Concat, u64, BurnTransaction, ValueQuery>; + pub type ExecutedBurnTransactions = StorageMap< + _, + Blake2_128Concat, + u64, + BurnTransaction, + OptionQuery, + >; #[pallet::storage] #[pallet::getter(fn refund_transactions)] @@ -105,6 +117,10 @@ pub mod pallet { #[pallet::getter(fn deposit_fee)] pub type DepositFee = StorageValue<_, u64, ValueQuery>; + #[pallet::storage] + #[pallet::getter(fn pallet_version)] + pub type PalletVersion = StorageValue<_, types::StorageVersion, ValueQuery>; + #[pallet::config] pub trait Config: frame_system::Config + pallet_balances::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; @@ -138,8 +154,8 @@ pub mod pallet { BurnTransactionProposed(u64, Vec, u64), BurnTransactionSignatureAdded(u64, StellarSignature), BurnTransactionReady(u64), - BurnTransactionProcessed(BurnTransaction), - BurnTransactionExpired(u64, Vec, u64), + BurnTransactionProcessed(BurnTransaction), + BurnTransactionExpired(u64, Option, Vec, u64), // Refund events RefundTransactionCreated(Vec, Vec, u64), RefundTransactionsignatureAdded(Vec, StellarSignature), @@ -229,7 +245,9 @@ pub mod pallet { BurnTransactions::::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, + )); } } diff --git a/substrate-node/pallets/pallet-tft-bridge/src/migrations/mod.rs b/substrate-node/pallets/pallet-tft-bridge/src/migrations/mod.rs new file mode 100644 index 000000000..e781566a1 --- /dev/null +++ b/substrate-node/pallets/pallet-tft-bridge/src/migrations/mod.rs @@ -0,0 +1,2 @@ +pub mod types; +pub mod v2; diff --git a/substrate-node/pallets/pallet-tft-bridge/src/migrations/types.rs b/substrate-node/pallets/pallet-tft-bridge/src/migrations/types.rs new file mode 100644 index 000000000..ad24ae41b --- /dev/null +++ b/substrate-node/pallets/pallet-tft-bridge/src/migrations/types.rs @@ -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 { + pub block: BlockNumber, + pub amount: u64, + pub target: Vec, + pub signatures: Vec, + pub sequence_number: u64, + } + + #[storage_alias] + pub type BurnTransactions = StorageMap< + Pallet, + Blake2_128Concat, + u64, + BurnTransaction<::BlockNumber>, + ValueQuery, + >; + + #[storage_alias] + pub type ExecutedBurnTransactions = StorageMap< + Pallet, + Blake2_128Concat, + u64, + BurnTransaction<::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 { + pub block: BlockNumber, + pub amount: u64, + pub source: Option, + pub target: Vec, + pub signatures: Vec, + pub sequence_number: u64, + } + + #[storage_alias] + pub type BurnTransactions = StorageMap< + Pallet, + Blake2_128Concat, + u64, + BurnTransaction<::AccountId, ::BlockNumber>, + OptionQuery, + >; + + #[storage_alias] + pub type ExecutedBurnTransactions = StorageMap< + Pallet, + Blake2_128Concat, + u64, + BurnTransaction<::AccountId, ::BlockNumber>, + OptionQuery, + >; +} diff --git a/substrate-node/pallets/pallet-tft-bridge/src/migrations/v2.rs b/substrate-node/pallets/pallet-tft-bridge/src/migrations/v2.rs new file mode 100644 index 000000000..bceb91343 --- /dev/null +++ b/substrate-node/pallets/pallet-tft-bridge/src/migrations/v2.rs @@ -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(PhantomData); + +impl OnRuntimeUpgrade for MigrateBurnTransactionsV2 { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + if PalletVersion::::get() != types::StorageVersion::V1 { + return Ok(Vec::::new()); + }; + + let burn_transactions_count: u64 = + migrations::types::v1::BurnTransactions::::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::::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::::new()); + } + + fn on_runtime_upgrade() -> Weight { + if PalletVersion::::get() == types::StorageVersion::V1 { + migrate_burn_transactions::() + } else { + info!(" >>> Unused TFT-BRIDGE pallet V2 migration"); + Weight::zero() + } + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_pre_burn_transactions_count: Vec) -> Result<(), &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + if PalletVersion::::get() != types::StorageVersion::V2 { + return Ok(()); + } + let burn_transactions_count: u64 = migrations::types::v2::BurnTransactions::::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::::iter().count() as u64; + info!( + "🔎 MigrateBurnTransactionsV2 post migration: Number of existing executed burn transactions {:?}", + executed_burn_transactions_count + ); + + Ok(()) + } +} + +pub fn migrate_burn_transactions() -> frame_support::weights::Weight { + info!(" >>> Migrating burn transactions storage..."); + + let mut read_writes = 0; + + migrations::types::v2::BurnTransactions::::translate::, _>( + |k, burn_transaction| { + debug!("migrated burn transaction: {:?}", k); + + let new_burn_transaction = migrations::types::v2::BurnTransaction:: { + 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::::translate::, _>( + |k, executed_burn_transaction| { + debug!("migrated executed burn transaction: {:?}", k); + + let new_executed_burn_transaction = + migrations::types::v2::BurnTransaction:: { + 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::::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) +} diff --git a/substrate-node/pallets/pallet-tft-bridge/src/tests.rs b/substrate-node/pallets/pallet-tft-bridge/src/tests.rs index 75087d69d..1642b96e0 100644 --- a/substrate-node/pallets/pallet-tft-bridge/src/tests.rs +++ b/substrate-node/pallets/pallet-tft-bridge/src/tests.rs @@ -155,7 +155,7 @@ fn burn_approval_retries_works() { b"bob_stellar_pubkey".to_vec(), 1 )); - let burn_tx = TFTBridgeModule::burn_transactions(1); + let burn_tx = TFTBridgeModule::burn_transactions(1).unwrap(); assert_eq!(burn_tx.signatures.len(), 2); assert_ok!(TFTBridgeModule::propose_burn_transaction_or_add_sig( @@ -167,7 +167,7 @@ fn burn_approval_retries_works() { b"eve_stellar_pubkey".to_vec(), 1 )); - let executed_burn_tx = TFTBridgeModule::burn_transactions(1); + let executed_burn_tx = TFTBridgeModule::burn_transactions(1).unwrap(); assert_eq!(executed_burn_tx.signatures.len(), 3); // // Test that the expected events were emitted @@ -377,7 +377,7 @@ fn burn_flow() { b"bob_stellar_pubkey".to_vec(), 1 )); - let burn_tx = TFTBridgeModule::burn_transactions(1); + let burn_tx = TFTBridgeModule::burn_transactions(1).unwrap(); assert_eq!(burn_tx.signatures.len(), 2); assert_ok!(TFTBridgeModule::propose_burn_transaction_or_add_sig( @@ -389,7 +389,7 @@ fn burn_flow() { b"eve_stellar_pubkey".to_vec(), 1 )); - let executed_burn_tx = TFTBridgeModule::burn_transactions(1); + let executed_burn_tx = TFTBridgeModule::burn_transactions(1).unwrap(); assert_eq!(executed_burn_tx.signatures.len(), 3); let b = TFTBridgeModule::get_usable_balance(&bob()); @@ -443,11 +443,11 @@ fn burn_flow_expired() { b"bob_stellar_pubkey".to_vec(), 1 )); - let burn_tx = TFTBridgeModule::burn_transactions(1); + let burn_tx = TFTBridgeModule::burn_transactions(1).unwrap(); assert_eq!(burn_tx.signatures.len(), 2); run_to_block(102); - let burn_tx = TFTBridgeModule::burn_transactions(1); + let burn_tx = TFTBridgeModule::burn_transactions(1).unwrap(); assert_eq!(burn_tx.signatures.len(), 0); // let expired_burn_tx = TFTBridgeModule::expired_burn_transactions(1); @@ -474,7 +474,7 @@ fn burn_flow_expired() { // )]; // assert_eq!(our_events[4], expected_events[0]); - let burn_tx = TFTBridgeModule::burn_transactions(1); + let burn_tx = TFTBridgeModule::burn_transactions(1).unwrap(); assert_eq!(burn_tx.signatures.len(), 0); assert_eq!(burn_tx.sequence_number, 0); }); diff --git a/substrate-node/pallets/pallet-tft-bridge/src/tft_bridge.rs b/substrate-node/pallets/pallet-tft-bridge/src/tft_bridge.rs index 3112f0a23..5b74b3a49 100644 --- a/substrate-node/pallets/pallet-tft-bridge/src/tft_bridge.rs +++ b/substrate-node/pallets/pallet-tft-bridge/src/tft_bridge.rs @@ -89,7 +89,7 @@ impl Pallet { let burn_amount_as_u64 = amount.saturated_into::() - withdraw_fee; Self::deposit_event(Event::BurnTransactionCreated( burn_id, - source, + source.clone(), target_stellar_address.clone(), burn_amount_as_u64, )); @@ -99,6 +99,7 @@ impl Pallet { let tx = BurnTransaction { block: now, amount: burn_amount_as_u64, + source: Some(source), target: target_stellar_address, signatures: Vec::new(), sequence_number: 0, @@ -239,7 +240,10 @@ impl Pallet { Error::::BurnTransactionAlreadyExecuted ); - let mut burn_tx = BurnTransactions::::get(tx_id); + let Some(mut burn_tx) = BurnTransactions::::get(tx_id) else {return Err(DispatchErrorWithPostInfo::from( + Error::::BurnTransactionNotExists, + ));}; + ensure!( BurnTransactions::::contains_key(tx_id), Error::::BurnTransactionNotExists @@ -282,7 +286,9 @@ impl Pallet { stellar_pub_key: Vec, sequence_number: u64, ) -> DispatchResultWithPostInfo { - let mut tx = BurnTransactions::::get(&tx_id); + let Some(mut tx) = BurnTransactions::::get(&tx_id) else {return Err(DispatchErrorWithPostInfo::from( + Error::::BurnTransactionNotExists, + ));}; let validators = Validators::::get(); if tx.signatures.len() == (validators.len() / 2) + 1 { @@ -340,7 +346,9 @@ impl Pallet { Error::::BurnTransactionNotExists ); - let tx = BurnTransactions::::get(tx_id); + let Some(tx) = BurnTransactions::::get(tx_id) else {return Err(DispatchErrorWithPostInfo::from( + Error::::BurnTransactionNotExists, + ));}; BurnTransactions::::remove(tx_id); ExecutedBurnTransactions::::insert(tx_id, &tx); diff --git a/substrate-node/pallets/pallet-tft-bridge/src/types.rs b/substrate-node/pallets/pallet-tft-bridge/src/types.rs index 57a80f756..78781190c 100644 --- a/substrate-node/pallets/pallet-tft-bridge/src/types.rs +++ b/substrate-node/pallets/pallet-tft-bridge/src/types.rs @@ -2,6 +2,19 @@ use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_std::vec::Vec; +/// Utility type for managing upgrades/migrations. +#[derive(Encode, Decode, Clone, Debug, PartialEq, PartialOrd, TypeInfo)] +pub enum StorageVersion { + V1, + V2, // add source to both BurnTransaction type and ExpiredBurnTransaction event +} + +impl Default for StorageVersion { + fn default() -> StorageVersion { + StorageVersion::V1 + } +} + // MintTransaction contains all the information about // Stellar -> TF Chain minting transaction. // if the votes field is larger then (number of validators / 2) + 1 , the transaction will be minted @@ -17,9 +30,10 @@ pub struct MintTransaction { // TF Chain -> Stellar burn transaction // Transaction is ready when (number of validators / 2) + 1 signatures are present #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] -pub struct BurnTransaction { +pub struct BurnTransaction { pub block: BlockNumber, pub amount: u64, + pub source: Option, pub target: Vec, pub signatures: Vec, pub sequence_number: u64, diff --git a/substrate-node/runtime/src/lib.rs b/substrate-node/runtime/src/lib.rs index 6e14fa91b..679bd3c86 100644 --- a/substrate-node/runtime/src/lib.rs +++ b/substrate-node/runtime/src/lib.rs @@ -770,7 +770,7 @@ pub type Executive = frame_executive::Executive< // All migrations executed on runtime upgrade as a nested tuple of types implementing // `OnRuntimeUpgrade`. -type Migrations = (pallet_tfgrid::migrations::v17::FixFarmPublicIps,); +type Migrations = (pallet_tfgrid::migrations::v17::FixFarmPublicIps, pallet_tft_bridge::migrations::v2::MigrateBurnTransactionsV2); // follows Substrate's non destructive way of eliminating otherwise required // repetion: https://github.com/paritytech/substrate/pull/10592