BasicGasPricer.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file BasicGasPricer.cpp
  15. * @author Gav Wood <i@gavwood.com>
  16. * @date 2015
  17. */
  18. #pragma warning(push)
  19. #pragma GCC diagnostic push
  20. #pragma GCC diagnostic ignored "-Wunused-parameter"
  21. #include <boost/math/distributions/normal.hpp>
  22. #pragma warning(pop)
  23. #pragma GCC diagnostic pop
  24. #include "BasicGasPricer.h"
  25. #include "BlockChain.h"
  26. using namespace std;
  27. using namespace dev;
  28. using namespace dev::eth;
  29. void BasicGasPricer::update(BlockChain const& _bc)
  30. {
  31. unsigned c = 0;
  32. h256 p = _bc.currentHash();
  33. m_gasPerBlock = _bc.info(p).gasLimit();
  34. map<u256, u256> dist;
  35. u256 total = 0;
  36. // make gasPrice versus gasUsed distribution for the last 1000 blocks
  37. while (c < 1000 && p)
  38. {
  39. BlockHeader bi = _bc.info(p);
  40. if (bi.transactionsRoot() != EmptyTrie)
  41. {
  42. auto bb = _bc.block(p);
  43. RLP r(bb);
  44. BlockReceipts brs(_bc.receipts(bi.hash()));
  45. size_t i = 0;
  46. for (auto const& tr: r[1])
  47. {
  48. Transaction tx(tr.data(), CheckTransaction::None);
  49. u256 gu = brs.receipts[i].gasUsed();
  50. dist[tx.gasPrice()] += gu;
  51. total += gu;
  52. i++;
  53. }
  54. }
  55. p = bi.parentHash();
  56. ++c;
  57. }
  58. // fill m_octiles with weighted gasPrices
  59. if (total > 0)
  60. {
  61. m_octiles[0] = dist.begin()->first;
  62. // calc mean
  63. u256 mean = 0;
  64. for (auto const& i: dist)
  65. mean += i.first * i.second;
  66. mean /= total;
  67. // calc standard deviation
  68. u256 sdSquared = 0;
  69. for (auto const& i: dist)
  70. sdSquared += i.second * (i.first - mean) * (i.first - mean);
  71. sdSquared /= total;
  72. if (sdSquared)
  73. {
  74. long double sd = sqrt(sdSquared.convert_to<long double>());
  75. long double normalizedSd = sd / mean.convert_to<long double>();
  76. // calc octiles normalized to gaussian distribution
  77. boost::math::normal gauss(1.0, (normalizedSd > 0.01) ? normalizedSd : 0.01);
  78. for (size_t i = 1; i < 8; i++)
  79. m_octiles[i] = u256(mean.convert_to<long double>() * boost::math::quantile(gauss, i / 8.0));
  80. m_octiles[8] = dist.rbegin()->first;
  81. }
  82. else
  83. {
  84. for (size_t i = 0; i < 9; i++)
  85. m_octiles[i] = (i + 1) * mean / 5;
  86. }
  87. }
  88. }