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