Skip to content

Commit e9c494b

Browse files
sameh-faroukclaude
andcommitted
fix(bridge): reset expiry timer on first signature after burn/refund expiry
After on_finalize expires a burn or refund transaction, re-proposals add signatures via add_stellar_sig_burn_transaction / add_stellar_sig_refund_transaction but tx.block was never updated. This caused on_finalize to immediately re-expire the transaction in the same block the new signature was added (since current_block - old_block >= RetryInterval was still true). Also removes dead code in propose_stellar_burn_transaction_or_add_sig where a redundant contains_key check made the block-update branch unreachable. Closes #1080 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 526158f commit e9c494b

1 file changed

Lines changed: 22 additions & 30 deletions

File tree

substrate-node/pallets/pallet-tft-bridge/src/tft_bridge.rs

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -240,16 +240,9 @@ impl<T: Config> Pallet<T> {
240240
Error::<T>::BurnTransactionAlreadyExecuted
241241
);
242242

243-
let Some(mut burn_tx) = BurnTransactions::<T>::get(tx_id) else {
244-
return Err(DispatchErrorWithPostInfo::from(
245-
Error::<T>::BurnTransactionNotExists,
246-
));
247-
};
248-
249-
ensure!(
250-
BurnTransactions::<T>::contains_key(tx_id),
251-
Error::<T>::BurnTransactionNotExists
252-
);
243+
let burn_tx = BurnTransactions::<T>::get(tx_id).ok_or(
244+
DispatchErrorWithPostInfo::from(Error::<T>::BurnTransactionNotExists),
245+
)?;
253246

254247
ensure!(
255248
burn_tx.amount == amount,
@@ -260,26 +253,12 @@ impl<T: Config> Pallet<T> {
260253
Error::<T>::WrongParametersProvided
261254
);
262255

263-
if BurnTransactions::<T>::contains_key(tx_id) {
264-
return Self::add_stellar_sig_burn_transaction(
265-
tx_id,
266-
signature,
267-
stellar_pub_key,
268-
sequence_number,
269-
);
270-
}
271-
272-
let now = <frame_system::Pallet<T>>::block_number();
273-
274-
burn_tx.block = now;
275-
burn_tx.sequence_number = sequence_number;
276-
BurnTransactions::<T>::insert(tx_id.clone(), &burn_tx);
277-
278-
Self::add_stellar_sig_burn_transaction(tx_id, signature, stellar_pub_key, sequence_number)?;
279-
280-
Self::deposit_event(Event::BurnTransactionProposed(tx_id, target, amount));
281-
282-
Ok(().into())
256+
Self::add_stellar_sig_burn_transaction(
257+
tx_id,
258+
signature,
259+
stellar_pub_key,
260+
sequence_number,
261+
)
283262
}
284263

285264
pub fn add_stellar_sig_burn_transaction(
@@ -319,6 +298,14 @@ impl<T: Config> Pallet<T> {
319298
stellar_pub_key,
320299
};
321300

301+
// Reset the expiry timer when this is the first signature after an expiry.
302+
// on_finalize clears signatures and sets block to the expiry block. Without
303+
// this reset, the old block value causes on_finalize to immediately re-expire
304+
// the burn in the same block the new signature is added.
305+
if tx.signatures.is_empty() {
306+
tx.block = <frame_system::Pallet<T>>::block_number();
307+
}
308+
322309
tx.sequence_number = sequence_number;
323310
tx.signatures.push(stellar_signature.clone());
324311
BurnTransactions::<T>::insert(tx_id, &tx);
@@ -397,6 +384,11 @@ impl<T: Config> Pallet<T> {
397384
stellar_pub_key,
398385
};
399386

387+
// Reset the expiry timer when this is the first signature after an expiry.
388+
if tx.signatures.is_empty() {
389+
tx.block = <frame_system::Pallet<T>>::block_number();
390+
}
391+
400392
tx.sequence_number = sequence_number;
401393
tx.signatures.push(stellar_signature.clone());
402394
RefundTransactions::<T>::insert(&tx_hash, &tx);

0 commit comments

Comments
 (0)