@@ -784,19 +784,19 @@ bool CWallet::IsSpentKey(const uint256& hash, unsigned int n) const
784
784
return false ;
785
785
}
786
786
787
- bool CWallet::AddToWallet (const CWalletTx& wtxIn , bool fFlushOnClose )
787
+ CWalletTx* CWallet::AddToWallet (CTransactionRef tx, const CWalletTx::Confirmation& confirm, const UpdateWalletTxFn& update_wtx , bool fFlushOnClose )
788
788
{
789
789
LOCK (cs_wallet);
790
790
791
791
WalletBatch batch (*database, " r+" , fFlushOnClose );
792
792
793
- uint256 hash = wtxIn. GetHash ();
793
+ uint256 hash = tx-> GetHash ();
794
794
795
795
if (IsWalletFlagSet (WALLET_FLAG_AVOID_REUSE)) {
796
796
// Mark used destinations
797
797
std::set<CTxDestination> tx_destinations;
798
798
799
- for (const CTxIn& txin : wtxIn. tx ->vin ) {
799
+ for (const CTxIn& txin : tx->vin ) {
800
800
const COutPoint& op = txin.prevout ;
801
801
SetSpentKeyState (batch, op.hash , op.n , true , tx_destinations);
802
802
}
@@ -805,55 +805,50 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
805
805
}
806
806
807
807
// Inserts only if not already there, returns tx inserted or tx found
808
- std::pair<std::map<uint256, CWalletTx>::iterator, bool > ret = mapWallet.insert (std::make_pair (hash, wtxIn ));
808
+ auto ret = mapWallet.emplace (std::piecewise_construct, std::forward_as_tuple (hash), std::forward_as_tuple ( this , tx ));
809
809
CWalletTx& wtx = (*ret.first ).second ;
810
- wtx.BindWallet (this );
811
810
bool fInsertedNew = ret.second ;
811
+ bool fUpdated = update_wtx && update_wtx (wtx, fInsertedNew );
812
812
if (fInsertedNew ) {
813
+ wtx.m_confirm = confirm;
813
814
wtx.nTimeReceived = chain ().getAdjustedTime ();
814
815
wtx.nOrderPos = IncOrderPosNext (&batch);
815
816
wtx.m_it_wtxOrdered = wtxOrdered.insert (std::make_pair (wtx.nOrderPos , &wtx));
816
817
wtx.nTimeSmart = ComputeTimeSmart (wtx);
817
818
AddToSpends (hash);
818
819
}
819
820
820
- bool fUpdated = false ;
821
821
if (!fInsertedNew )
822
822
{
823
- if (wtxIn. m_confirm .status != wtx.m_confirm .status ) {
824
- wtx.m_confirm .status = wtxIn. m_confirm .status ;
825
- wtx.m_confirm .nIndex = wtxIn. m_confirm .nIndex ;
826
- wtx.m_confirm .hashBlock = wtxIn. m_confirm .hashBlock ;
827
- wtx.m_confirm .block_height = wtxIn. m_confirm .block_height ;
823
+ if (confirm .status != wtx.m_confirm .status ) {
824
+ wtx.m_confirm .status = confirm .status ;
825
+ wtx.m_confirm .nIndex = confirm .nIndex ;
826
+ wtx.m_confirm .hashBlock = confirm .hashBlock ;
827
+ wtx.m_confirm .block_height = confirm .block_height ;
828
828
fUpdated = true ;
829
829
} else {
830
- assert (wtx.m_confirm .nIndex == wtxIn.m_confirm .nIndex );
831
- assert (wtx.m_confirm .hashBlock == wtxIn.m_confirm .hashBlock );
832
- assert (wtx.m_confirm .block_height == wtxIn.m_confirm .block_height );
833
- }
834
- if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe )
835
- {
836
- wtx.fFromMe = wtxIn.fFromMe ;
837
- fUpdated = true ;
830
+ assert (wtx.m_confirm .nIndex == confirm.nIndex );
831
+ assert (wtx.m_confirm .hashBlock == confirm.hashBlock );
832
+ assert (wtx.m_confirm .block_height == confirm.block_height );
838
833
}
839
834
// If we have a witness-stripped version of this transaction, and we
840
835
// see a new version with a witness, then we must be upgrading a pre-segwit
841
836
// wallet. Store the new version of the transaction with the witness,
842
837
// as the stripped-version must be invalid.
843
838
// TODO: Store all versions of the transaction, instead of just one.
844
- if (wtxIn. tx ->HasWitness () && !wtx.tx ->HasWitness ()) {
845
- wtx.SetTx (wtxIn. tx );
839
+ if (tx->HasWitness () && !wtx.tx ->HasWitness ()) {
840
+ wtx.SetTx (tx);
846
841
fUpdated = true ;
847
842
}
848
843
}
849
844
850
845
// // debug print
851
- WalletLogPrintf (" AddToWallet %s %s%s\n " , wtxIn. GetHash () .ToString (), (fInsertedNew ? " new" : " " ), (fUpdated ? " update" : " " ));
846
+ WalletLogPrintf (" AddToWallet %s %s%s\n " , hash .ToString (), (fInsertedNew ? " new" : " " ), (fUpdated ? " update" : " " ));
852
847
853
848
// Write to disk
854
849
if (fInsertedNew || fUpdated )
855
850
if (!batch.WriteTx (wtx))
856
- return false ;
851
+ return nullptr ;
857
852
858
853
// Break debit/credit balance caches:
859
854
wtx.MarkDirty ();
@@ -867,7 +862,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
867
862
868
863
if (!strCmd.empty ())
869
864
{
870
- boost::replace_all (strCmd, " %s" , wtxIn. GetHash () .GetHex ());
865
+ boost::replace_all (strCmd, " %s" , hash .GetHex ());
871
866
#ifndef WIN32
872
867
// Substituting the wallet name isn't currently supported on windows
873
868
// because windows shell escaping has not been implemented yet:
@@ -881,35 +876,36 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
881
876
}
882
877
#endif
883
878
884
- return true ;
879
+ return &wtx ;
885
880
}
886
881
887
- void CWallet::LoadToWallet (CWalletTx& wtxIn )
882
+ bool CWallet::LoadToWallet (const uint256& hash, const UpdateWalletTxFn& fill_wtx )
888
883
{
884
+ const auto & ins = mapWallet.emplace (std::piecewise_construct, std::forward_as_tuple (hash), std::forward_as_tuple (this , nullptr ));
885
+ CWalletTx& wtx = ins.first ->second ;
886
+ if (!fill_wtx (wtx, ins.second )) {
887
+ return false ;
888
+ }
889
889
// If wallet doesn't have a chain (e.g wallet-tool), don't bother to update txn.
890
890
if (HaveChain ()) {
891
- Optional<int > block_height = chain ().getBlockHeight (wtxIn .m_confirm .hashBlock );
891
+ Optional<int > block_height = chain ().getBlockHeight (wtx .m_confirm .hashBlock );
892
892
if (block_height) {
893
893
// Update cached block height variable since it not stored in the
894
894
// serialized transaction.
895
- wtxIn .m_confirm .block_height = *block_height;
896
- } else if (wtxIn .isConflicted () || wtxIn .isConfirmed ()) {
895
+ wtx .m_confirm .block_height = *block_height;
896
+ } else if (wtx .isConflicted () || wtx .isConfirmed ()) {
897
897
// If tx block (or conflicting block) was reorged out of chain
898
898
// while the wallet was shutdown, change tx status to UNCONFIRMED
899
899
// and reset block height, hash, and index. ABANDONED tx don't have
900
900
// associated blocks and don't need to be updated. The case where a
901
901
// transaction was reorged out while online and then reconfirmed
902
902
// while offline is covered by the rescan logic.
903
- wtxIn .setUnconfirmed ();
904
- wtxIn .m_confirm .hashBlock = uint256 ();
905
- wtxIn .m_confirm .block_height = 0 ;
906
- wtxIn .m_confirm .nIndex = 0 ;
903
+ wtx .setUnconfirmed ();
904
+ wtx .m_confirm .hashBlock = uint256 ();
905
+ wtx .m_confirm .block_height = 0 ;
906
+ wtx .m_confirm .nIndex = 0 ;
907
907
}
908
908
}
909
- uint256 hash = wtxIn.GetHash ();
910
- const auto & ins = mapWallet.emplace (hash, wtxIn);
911
- CWalletTx& wtx = ins.first ->second ;
912
- wtx.BindWallet (this );
913
909
if (/* insertion took place */ ins.second ) {
914
910
wtx.m_it_wtxOrdered = wtxOrdered.insert (std::make_pair (wtx.nOrderPos , &wtx));
915
911
}
@@ -923,6 +919,7 @@ void CWallet::LoadToWallet(CWalletTx& wtxIn)
923
919
}
924
920
}
925
921
}
922
+ return true ;
926
923
}
927
924
928
925
bool CWallet::AddToWalletIfInvolvingMe (const CTransactionRef& ptx, CWalletTx::Confirmation confirm, bool fUpdate )
@@ -961,13 +958,9 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, CWalletTx::Co
961
958
}
962
959
}
963
960
964
- CWalletTx wtx (this , ptx);
965
-
966
961
// Block disconnection override an abandoned tx as unconfirmed
967
962
// which means user may have to call abandontransaction again
968
- wtx.m_confirm = confirm;
969
-
970
- return AddToWallet (wtx, false );
963
+ return AddToWallet (MakeTransactionRef (tx), confirm, /* update_wtx= */ nullptr , /* fFlushOnClose= */ false );
971
964
}
972
965
}
973
966
return false ;
@@ -3008,29 +3001,30 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
3008
3001
void CWallet::CommitTransaction (CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm)
3009
3002
{
3010
3003
LOCK (cs_wallet);
3011
-
3012
- CWalletTx wtxNew (this , std::move (tx));
3013
- wtxNew.mapValue = std::move (mapValue);
3014
- wtxNew.vOrderForm = std::move (orderForm);
3015
- wtxNew.fTimeReceivedIsTxTime = true ;
3016
- wtxNew.fFromMe = true ;
3017
-
3018
- WalletLogPrintf (" CommitTransaction:\n %s" , wtxNew.tx ->ToString ()); /* Continued */
3004
+ WalletLogPrintf (" CommitTransaction:\n %s" , tx->ToString ()); /* Continued */
3019
3005
3020
3006
// Add tx to wallet, because if it has change it's also ours,
3021
3007
// otherwise just for transaction history.
3022
- AddToWallet (wtxNew);
3008
+ AddToWallet (tx, {}, [&](CWalletTx& wtx, bool new_tx) {
3009
+ CHECK_NONFATAL (wtx.mapValue .empty ());
3010
+ CHECK_NONFATAL (wtx.vOrderForm .empty ());
3011
+ wtx.mapValue = std::move (mapValue);
3012
+ wtx.vOrderForm = std::move (orderForm);
3013
+ wtx.fTimeReceivedIsTxTime = true ;
3014
+ wtx.fFromMe = true ;
3015
+ return true ;
3016
+ });
3023
3017
3024
3018
// Notify that old coins are spent
3025
- for (const CTxIn& txin : wtxNew. tx ->vin ) {
3019
+ for (const CTxIn& txin : tx->vin ) {
3026
3020
CWalletTx &coin = mapWallet.at (txin.prevout .hash );
3027
- coin.BindWallet ( this );
3021
+ coin.MarkDirty ( );
3028
3022
NotifyTransactionChanged (this , coin.GetHash (), CT_UPDATED);
3029
3023
}
3030
3024
3031
3025
// Get the inserted-CWalletTx from mapWallet so that the
3032
3026
// fInMempool flag is cached properly
3033
- CWalletTx& wtx = mapWallet.at (wtxNew. GetHash ());
3027
+ CWalletTx& wtx = mapWallet.at (tx-> GetHash ());
3034
3028
3035
3029
if (!fBroadcastTransactions ) {
3036
3030
// Don't submit tx to the mempool
@@ -3102,7 +3096,7 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
3102
3096
return DBErrors::LOAD_OK;
3103
3097
}
3104
3098
3105
- DBErrors CWallet::ZapWalletTx (std::vector <CWalletTx>& vWtx)
3099
+ DBErrors CWallet::ZapWalletTx (std::list <CWalletTx>& vWtx)
3106
3100
{
3107
3101
DBErrors nZapWalletTxRet = WalletBatch (*database," cr+" ).ZapWalletTx (vWtx);
3108
3102
if (nZapWalletTxRet == DBErrors::NEED_REWRITE)
@@ -3714,7 +3708,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
3714
3708
const std::string walletFile = WalletDataFilePath (location.GetPath ()).string ();
3715
3709
3716
3710
// needed to restore wallet transaction meta data after -zapwallettxes
3717
- std::vector <CWalletTx> vWtx;
3711
+ std::list <CWalletTx> vWtx;
3718
3712
3719
3713
if (gArgs .GetBoolArg (" -zapwallettxes" , false )) {
3720
3714
chain.initMessage (_ (" Zapping all transactions from wallet..." ).translated );
0 commit comments