@@ -689,60 +689,66 @@ impl OutputCache {
689
689
confirmed_tx : & Transaction ,
690
690
block_id : Id < GenBlock > ,
691
691
) -> WalletResult < Vec < Id < Transaction > > > {
692
- let mut frozen_token_id: Option < TokenId > = None ;
693
- let mut confirmed_account_nonce: Option < ( AccountType , AccountNonce ) > = None ;
692
+ struct Conflict {
693
+ frozen_token_id : Option < TokenId > ,
694
+ confirmed_account_nonce : Option < ( AccountType , AccountNonce ) > ,
695
+ }
694
696
695
- for input in confirmed_tx. inputs ( ) {
697
+ let conflict = confirmed_tx. inputs ( ) . iter ( ) . find_map ( |input| {
696
698
match input {
697
699
TxInput :: Utxo ( _) => {
698
700
//TODO: check conflicting utxo spends
701
+ None
699
702
}
700
- TxInput :: Account ( outpoint) => {
701
- confirmed_account_nonce = Some ( ( outpoint. account ( ) . into ( ) , outpoint. nonce ( ) ) ) ;
702
- }
703
- TxInput :: AccountCommand ( nonce, cmd) => {
704
- confirmed_account_nonce = Some ( ( cmd. into ( ) , * nonce) ) ;
705
- match cmd {
706
- AccountCommand :: MintTokens ( _, _)
707
- | AccountCommand :: UnmintTokens ( _)
708
- | AccountCommand :: LockTokenSupply ( _)
709
- | AccountCommand :: ChangeTokenMetadataUri ( _, _)
710
- | AccountCommand :: ChangeTokenAuthority ( _, _)
711
- | AccountCommand :: UnfreezeToken ( _)
712
- | AccountCommand :: ConcludeOrder ( _)
713
- | AccountCommand :: FillOrder ( _, _, _) => { /* do nothing */ }
714
- | AccountCommand :: FreezeToken ( token_id, _) => {
715
- frozen_token_id = Some ( * token_id) ;
716
- }
717
- }
718
- }
703
+ TxInput :: Account ( outpoint) => Some ( Conflict {
704
+ frozen_token_id : None ,
705
+ confirmed_account_nonce : Some ( ( outpoint. account ( ) . into ( ) , outpoint. nonce ( ) ) ) ,
706
+ } ) ,
707
+ TxInput :: AccountCommand ( nonce, cmd) => match cmd {
708
+ AccountCommand :: MintTokens ( _, _)
709
+ | AccountCommand :: UnmintTokens ( _)
710
+ | AccountCommand :: LockTokenSupply ( _)
711
+ | AccountCommand :: ChangeTokenMetadataUri ( _, _)
712
+ | AccountCommand :: ChangeTokenAuthority ( _, _)
713
+ | AccountCommand :: UnfreezeToken ( _)
714
+ | AccountCommand :: ConcludeOrder ( _)
715
+ | AccountCommand :: FillOrder ( _, _, _) => Some ( Conflict {
716
+ frozen_token_id : None ,
717
+ confirmed_account_nonce : Some ( ( cmd. into ( ) , * nonce) ) ,
718
+ } ) ,
719
+ | AccountCommand :: FreezeToken ( token_id, _) => Some ( Conflict {
720
+ frozen_token_id : Some ( * token_id) ,
721
+ confirmed_account_nonce : Some ( ( cmd. into ( ) , * nonce) ) ,
722
+ } ) ,
723
+ } ,
719
724
}
720
- }
725
+ } ) ;
721
726
722
727
// Collect all conflicting txs
723
- let mut conflicting_txs = vec ! [ ] ;
728
+ let mut conflicting_txs = BTreeSet :: new ( ) ;
724
729
725
- if frozen_token_id . is_some ( ) || confirmed_account_nonce . is_some ( ) {
730
+ if let Some ( conflict ) = conflict {
726
731
for unconfirmed in self . unconfirmed_descendants . keys ( ) {
727
- if let Some ( frozen_token_id) = frozen_token_id {
728
- let unconfirmed_tx = self . txs . get ( unconfirmed) . expect ( "must be present" ) ;
732
+ let unconfirmed_tx = self . txs . get ( unconfirmed) . expect ( "must be present" ) ;
733
+
734
+ if let Some ( frozen_token_id) = conflict. frozen_token_id {
729
735
if self . uses_token ( unconfirmed_tx, & frozen_token_id) {
730
736
if let WalletTx :: Tx ( tx) = unconfirmed_tx {
731
- conflicting_txs. push ( tx. get_transaction ( ) . get_id ( ) ) ;
737
+ conflicting_txs. insert ( tx. get_transaction ( ) . get_id ( ) ) ;
732
738
}
733
739
}
734
740
}
735
741
736
- if let Some ( ( confirmed_account, confirmed_account_nonce) ) = confirmed_account_nonce
742
+ if let Some ( ( confirmed_account, confirmed_account_nonce) ) =
743
+ conflict. confirmed_account_nonce
737
744
{
738
- let unconfirmed_tx = self . txs . get ( unconfirmed) . expect ( "must be present" ) ;
739
745
if uses_conflicting_nonce (
740
746
unconfirmed_tx,
741
747
confirmed_account,
742
748
confirmed_account_nonce,
743
749
) {
744
750
if let WalletTx :: Tx ( tx) = unconfirmed_tx {
745
- conflicting_txs. push ( tx. get_transaction ( ) . get_id ( ) ) ;
751
+ conflicting_txs. insert ( tx. get_transaction ( ) . get_id ( ) ) ;
746
752
}
747
753
}
748
754
}
@@ -832,7 +838,7 @@ impl OutputCache {
832
838
833
839
if is_unconfirmed && !already_present {
834
840
self . unconfirmed_descendants . insert ( tx_id. clone ( ) , BTreeSet :: new ( ) ) ;
835
- } else {
841
+ } else if !is_unconfirmed {
836
842
self . unconfirmed_descendants . remove ( & tx_id) ;
837
843
}
838
844
@@ -951,11 +957,11 @@ impl OutputCache {
951
957
if let Some ( descendants) =
952
958
self . unconfirmed_descendants . get_mut ( & outpoint. source_id ( ) )
953
959
{
954
- if is_unconfirmed {
955
- descendants . insert ( tx_id . clone ( ) ) ;
956
- } else {
957
- descendants . remove ( tx_id ) ;
958
- }
960
+ ensure ! (
961
+ is_unconfirmed ,
962
+ WalletError :: ConfirmedTxAmongUnconfirmedDescendants ( tx_id . clone ( ) )
963
+ ) ;
964
+ descendants . insert ( tx_id . clone ( ) ) ;
959
965
}
960
966
}
961
967
TxInput :: Account ( outpoint) => match outpoint. account ( ) {
0 commit comments