| 728 | } |
| 729 | |
| 730 | DBErrors CWallet::ReorderTransactions() |
| 731 | { |
| 732 | LOCK(cs_wallet); |
| 733 | WalletBatch batch(*database); |
| 734 | |
| 735 | // Old wallets didn't have any defined order for transactions |
| 736 | // Probably a bad idea to change the output of this |
| 737 | |
| 738 | // First: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap. |
| 739 | typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair; |
| 740 | typedef std::multimap<int64_t, TxPair > TxItems; |
| 741 | TxItems txByTime; |
| 742 | |
| 743 | for (auto& entry : mapWallet) |
| 744 | { |
| 745 | CWalletTx* wtx = &entry.second; |
| 746 | txByTime.insert(std::make_pair(wtx->nTimeReceived, TxPair(wtx, nullptr))); |
| 747 | } |
| 748 | std::list<CAccountingEntry> acentries; |
| 749 | batch.ListAccountCreditDebit("", acentries); |
| 750 | for (CAccountingEntry& entry : acentries) |
| 751 | { |
| 752 | txByTime.insert(std::make_pair(entry.nTime, TxPair(nullptr, &entry))); |
| 753 | } |
| 754 | |
| 755 | nOrderPosNext = 0; |
| 756 | std::vector<int64_t> nOrderPosOffsets; |
| 757 | for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it) |
| 758 | { |
| 759 | CWalletTx *const pwtx = (*it).second.first; |
| 760 | CAccountingEntry *const pacentry = (*it).second.second; |
| 761 | int64_t& nOrderPos = (pwtx != nullptr) ? pwtx->nOrderPos : pacentry->nOrderPos; |
| 762 | |
| 763 | if (nOrderPos == -1) |
| 764 | { |
| 765 | nOrderPos = nOrderPosNext++; |
| 766 | nOrderPosOffsets.push_back(nOrderPos); |
| 767 | |
| 768 | if (pwtx) |
| 769 | { |
| 770 | if (!batch.WriteTx(*pwtx)) |
| 771 | return DBErrors::LOAD_FAIL; |
| 772 | } |
| 773 | else |
| 774 | if (!batch.WriteAccountingEntry(pacentry->nEntryNo, *pacentry)) |
| 775 | return DBErrors::LOAD_FAIL; |
| 776 | } |
| 777 | else |
| 778 | { |
| 779 | int64_t nOrderPosOff = 0; |
| 780 | for (const int64_t& nOffsetStart : nOrderPosOffsets) |
| 781 | { |
| 782 | if (nOrderPos >= nOffsetStart) |
| 783 | ++nOrderPosOff; |
| 784 | } |
| 785 | nOrderPos += nOrderPosOff; |
| 786 | nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1); |
| 787 | |