| 404 | } |
| 405 | |
| 406 | void TxConfirmStats::Read(CAutoFile& filein, int nFileVersion, size_t numBuckets) |
| 407 | { |
| 408 | // Read data file and do some very basic sanity checking |
| 409 | // buckets and bucketMap are not updated yet, so don't access them |
| 410 | // If there is a read failure, we'll just discard this entire object anyway |
| 411 | size_t maxConfirms, maxPeriods; |
| 412 | |
| 413 | // The current version will store the decay with each individual TxConfirmStats and also keep a scale factor |
| 414 | filein >> decay; |
| 415 | if (decay <= 0 || decay >= 1) { |
| 416 | throw std::runtime_error("Corrupt estimates file. Decay must be between 0 and 1 (non-inclusive)"); |
| 417 | } |
| 418 | filein >> scale; |
| 419 | if (scale == 0) { |
| 420 | throw std::runtime_error("Corrupt estimates file. Scale must be non-zero"); |
| 421 | } |
| 422 | |
| 423 | filein >> avg; |
| 424 | if (avg.size() != numBuckets) { |
| 425 | throw std::runtime_error("Corrupt estimates file. Mismatch in feerate average bucket count"); |
| 426 | } |
| 427 | filein >> txCtAvg; |
| 428 | if (txCtAvg.size() != numBuckets) { |
| 429 | throw std::runtime_error("Corrupt estimates file. Mismatch in tx count bucket count"); |
| 430 | } |
| 431 | filein >> confAvg; |
| 432 | maxPeriods = confAvg.size(); |
| 433 | maxConfirms = scale * maxPeriods; |
| 434 | |
| 435 | if (maxConfirms <= 0 || maxConfirms > 6 * 24 * 7) { // one week |
| 436 | throw std::runtime_error("Corrupt estimates file. Must maintain estimates for between 1 and 1008 (one week) confirms"); |
| 437 | } |
| 438 | for (unsigned int i = 0; i < maxPeriods; i++) { |
| 439 | if (confAvg[i].size() != numBuckets) { |
| 440 | throw std::runtime_error("Corrupt estimates file. Mismatch in feerate conf average bucket count"); |
| 441 | } |
| 442 | } |
| 443 | |
| 444 | filein >> failAvg; |
| 445 | if (maxPeriods != failAvg.size()) { |
| 446 | throw std::runtime_error("Corrupt estimates file. Mismatch in confirms tracked for failures"); |
| 447 | } |
| 448 | for (unsigned int i = 0; i < maxPeriods; i++) { |
| 449 | if (failAvg[i].size() != numBuckets) { |
| 450 | throw std::runtime_error("Corrupt estimates file. Mismatch in one of failure average bucket counts"); |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | // Resize the current block variables which aren't stored in the data file |
| 455 | // to match the number of confirms and buckets |
| 456 | resizeInMemoryCounters(numBuckets); |
| 457 | |
| 458 | LogPrint(BCLog::ESTIMATEFEE, "Reading estimates: %u buckets counting confirms up to %u blocks\n", |
| 459 | numBuckets, maxConfirms); |
| 460 | } |
| 461 | |
| 462 | unsigned int TxConfirmStats::NewTx(unsigned int nBlockHeight, double val) |
| 463 | { |