diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gui.cpp | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/gui.cpp b/src/gui.cpp index 28f5ffa..53cb6db 100644 --- a/src/gui.cpp +++ b/src/gui.cpp | |||
| @@ -124,15 +124,32 @@ static void RefreshWallet() | |||
| 124 | g_txRows.clear(); | 124 | g_txRows.clear(); |
| 125 | TRY_CRITICAL_BLOCK(cs_mapWallet) | 125 | TRY_CRITICAL_BLOCK(cs_mapWallet) |
| 126 | { | 126 | { |
| 127 | // Sort: unconfirmed first (depth 0), then by depth ascending (least | 127 | // Sort: pending first, then confirmed by depth ascending (least deep = |
| 128 | // deep = most recent). We can't use nTimeReceived because a node | 128 | // most recent), then orphaned coinbases at the very bottom. |
| 129 | // resync re-stamps all txs with the same time. Depth is always correct. | 129 | // |
| 130 | std::vector<std::pair<int,uint256>> vs; | 130 | // Orphans have to be pushed down explicitly. They are depth 0, exactly |
| 131 | for (auto& kv : mapWallet) | 131 | // like a genuinely pending transaction, so sorting on depth alone put |
| 132 | vs.push_back({kv.second.GetDepthInMainChain(), kv.second.GetHash()}); | 132 | // every orphan the node had ever produced at the top of the list -- and |
| 133 | // they never age out, because depth 0 is where they stay forever. A | ||
| 134 | // miner with a week of ordinary orphaned races opened the wallet and | ||
| 135 | // saw nothing but failures stacked above every block it had actually | ||
| 136 | // won. The balance was right; the list was telling a different story. | ||
| 137 | // | ||
| 138 | // We can't sort on nTimeReceived because a resync re-stamps every | ||
| 139 | // transaction with the same time. Depth is always correct. | ||
| 140 | // | ||
| 141 | // 0 = pending, 1 = confirmed, 2 = orphaned. | ||
| 142 | std::vector<std::pair<std::pair<int,int>,uint256>> vs; | ||
| 143 | for (auto& kv : mapWallet) { | ||
| 144 | int d = kv.second.GetDepthInMainChain(); | ||
| 145 | bool orphaned = kv.second.IsCoinBase() && kv.second.hashBlock != 0 && d == 0; | ||
| 146 | int rank = orphaned ? 2 : (d == 0 ? 0 : 1); | ||
| 147 | vs.push_back({{rank, d}, kv.second.GetHash()}); | ||
| 148 | } | ||
| 133 | std::sort(vs.begin(), vs.end(), | 149 | std::sort(vs.begin(), vs.end(), |
| 134 | [](const std::pair<int,uint256>& a, const std::pair<int,uint256>& b) { | 150 | [](const std::pair<std::pair<int,int>,uint256>& a, |
| 135 | return a.first < b.first; // 0 (unconfirmed) first, then shallowest | 151 | const std::pair<std::pair<int,int>,uint256>& b) { |
| 152 | return a.first < b.first; | ||
| 136 | }); | 153 | }); |
| 137 | for (auto& sv : vs) { | 154 | for (auto& sv : vs) { |
| 138 | auto mi = mapWallet.find(sv.second); | 155 | auto mi = mapWallet.find(sv.second); |