diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/rpc.cpp | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/src/rpc.cpp b/src/rpc.cpp index ae94289..8a0d112 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp | |||
| @@ -143,17 +143,40 @@ static bool RebuildJob() | |||
| 143 | return false; | 143 | return false; |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | // Don't issue jobs until the chain is synced: mining against a stale | 146 | // Don't issue jobs while we are behind the network: mining against a |
| 147 | // tip produces blocks the network will orphan, and payout entries | 147 | // stale tip produces blocks the network will orphan, and payout |
| 148 | // that can never be paid (their coinbases never exist on the main | 148 | // entries that can never be paid (their coinbases never exist on the |
| 149 | // chain). Require at least one peer and a fresh tip. | 149 | // main chain). Require at least one peer, and require that no peer |
| 150 | // claims a longer chain than ours. | ||
| 150 | if (vNodes.empty()) { | 151 | if (vNodes.empty()) { |
| 151 | LogPrint("pool", "RebuildJob: no peers yet -- not issuing jobs\n"); | 152 | LogPrint("pool", "RebuildJob: no peers yet -- not issuing jobs\n"); |
| 152 | return false; | 153 | return false; |
| 153 | } | 154 | } |
| 154 | if (GetAdjustedTime() - (int64)pindexBest->nTime > 30*60) { | 155 | // This used to compare the tip's timestamp against 30 minutes, which |
| 155 | LogPrint("pool", "RebuildJob: tip is %llds old -- still syncing, not issuing jobs\n", | 156 | // was wrong in both directions and cost real money. |
| 156 | (long long)(GetAdjustedTime() - (int64)pindexBest->nTime)); | 157 | // |
| 158 | // It cannot tell "we are not synced" from "the network is slow". A | ||
| 159 | // pool mining its own fork keeps its tip timestamp fresh forever, so | ||
| 160 | // the check passed for the whole of heights 3966-4085 -- 120 | ||
| 161 | // consecutive blocks, every one of them orphaned, 5890.50 BTF of | ||
| 162 | // payouts voided. Then, once the pool stopped finding blocks, the | ||
| 163 | // same check refused to issue jobs against a tip that was perfectly | ||
| 164 | // valid and was the network's own best, and the pool -- roughly 90% | ||
| 165 | // of the hashrate -- could not restart the chain it was the majority | ||
| 166 | // of. Stale tip, so no jobs; no jobs, so the tip stays stale. | ||
| 167 | // | ||
| 168 | // The height peers announce in their version message answers the | ||
| 169 | // question the age check was only guessing at. Median, so one peer | ||
| 170 | // claiming an absurd height cannot stall us, and one block of slack | ||
| 171 | // to match WarnIfBehind, because somebody is always mid-relay. A | ||
| 172 | // peer that predates the announcement reports -1 and is ignored; if | ||
| 173 | // nobody has told us anything we mine our best chain, which is what | ||
| 174 | // the node would do without a pool attached. | ||
| 175 | int nPeerHeight = GetPeerMedianHeight(); | ||
| 176 | if (nPeerHeight >= 0 && nBestHeight < nPeerHeight - 1) { | ||
| 177 | LogPrint("pool", "RebuildJob: %d blocks behind the network " | ||
| 178 | "(height %d, peers report %d) -- not issuing jobs\n", | ||
| 179 | nPeerHeight - nBestHeight, nBestHeight, nPeerHeight); | ||
| 157 | return false; | 180 | return false; |
| 158 | } | 181 | } |
| 159 | 182 | ||