Gav Wood
10 years ago
16 changed files with 489 additions and 320 deletions
@ -0,0 +1,95 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file BasicGasPricer.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <boost/math/distributions/normal.hpp> |
|||
#include "BasicGasPricer.h" |
|||
#include "BlockChain.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
void BasicGasPricer::update(BlockChain const& _bc) |
|||
{ |
|||
unsigned c = 0; |
|||
h256 p = _bc.currentHash(); |
|||
m_gasPerBlock = _bc.info(p).gasLimit; |
|||
|
|||
map<u256, u256> dist; |
|||
u256 total = 0; |
|||
|
|||
// make gasPrice versus gasUsed distribution for the last 1000 blocks
|
|||
while (c < 1000 && p) |
|||
{ |
|||
BlockInfo bi = _bc.info(p); |
|||
if (bi.transactionsRoot != EmptyTrie) |
|||
{ |
|||
auto bb = _bc.block(p); |
|||
RLP r(bb); |
|||
BlockReceipts brs(_bc.receipts(bi.hash())); |
|||
size_t i = 0; |
|||
for (auto const& tr: r[1]) |
|||
{ |
|||
Transaction tx(tr.data(), CheckTransaction::None); |
|||
u256 gu = brs.receipts[i].gasUsed(); |
|||
dist[tx.gasPrice()] += gu; |
|||
total += gu; |
|||
i++; |
|||
} |
|||
} |
|||
p = bi.parentHash; |
|||
++c; |
|||
} |
|||
|
|||
// fill m_octiles with weighted gasPrices
|
|||
if (total > 0) |
|||
{ |
|||
m_octiles[0] = dist.begin()->first; |
|||
|
|||
// calc mean
|
|||
u256 mean = 0; |
|||
for (auto const& i: dist) |
|||
mean += i.first * i.second; |
|||
mean /= total; |
|||
|
|||
// calc standard deviation
|
|||
u256 sdSquared = 0; |
|||
for (auto const& i: dist) |
|||
sdSquared += i.second * (i.first - mean) * (i.first - mean); |
|||
sdSquared /= total; |
|||
|
|||
if (sdSquared) |
|||
{ |
|||
long double sd = sqrt(sdSquared.convert_to<long double>()); |
|||
long double normalizedSd = sd / mean.convert_to<long double>(); |
|||
|
|||
// calc octiles normalized to gaussian distribution
|
|||
boost::math::normal gauss(1.0, (normalizedSd > 0.01) ? normalizedSd : 0.01); |
|||
for (size_t i = 1; i < 8; i++) |
|||
m_octiles[i] = u256(mean.convert_to<long double>() * boost::math::quantile(gauss, i / 8.0)); |
|||
m_octiles[8] = dist.rbegin()->first; |
|||
} |
|||
else |
|||
{ |
|||
for (size_t i = 0; i < 9; i++) |
|||
m_octiles[i] = (i + 1) * mean / 5; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,53 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file BasicGasPricer.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include "GasPricer.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
|
|||
class BasicGasPricer: public GasPricer |
|||
{ |
|||
public: |
|||
explicit BasicGasPricer(u256 _weiPerRef, u256 _refsPerBlock): m_weiPerRef(_weiPerRef), m_refsPerBlock(_refsPerBlock) {} |
|||
|
|||
void setRefPrice(u256 _weiPerRef) { if ((bigint)m_refsPerBlock * _weiPerRef > std::numeric_limits<u256>::max() ) BOOST_THROW_EXCEPTION(Overflow() << errinfo_comment("ether price * block fees is larger than 2**256-1, choose a smaller number.") ); else m_weiPerRef = _weiPerRef; } |
|||
void setRefBlockFees(u256 _refsPerBlock) { if ((bigint)m_weiPerRef * _refsPerBlock > std::numeric_limits<u256>::max() ) BOOST_THROW_EXCEPTION(Overflow() << errinfo_comment("ether price * block fees is larger than 2**256-1, choose a smaller number.") ); else m_refsPerBlock = _refsPerBlock; } |
|||
|
|||
u256 ask(State const&) const override { return m_weiPerRef * m_refsPerBlock / m_gasPerBlock; } |
|||
u256 bid(TransactionPriority _p = TransactionPriority::Medium) const override { return m_octiles[(int)_p] > 0 ? m_octiles[(int)_p] : (m_weiPerRef * m_refsPerBlock / m_gasPerBlock); } |
|||
|
|||
void update(BlockChain const& _bc) override; |
|||
|
|||
private: |
|||
u256 m_weiPerRef; |
|||
u256 m_refsPerBlock; |
|||
u256 m_gasPerBlock = 3141592; |
|||
std::array<u256, 9> m_octiles; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -0,0 +1,26 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file GasPricer.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "GasPricer.h" |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
@ -0,0 +1,74 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file GasPricer.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <libethcore/Common.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
|
|||
class State; |
|||
class BlockChain; |
|||
|
|||
enum class TransactionPriority |
|||
{ |
|||
Lowest = 0, |
|||
Low = 2, |
|||
Medium = 4, |
|||
High = 6, |
|||
Highest = 8 |
|||
}; |
|||
|
|||
class GasPricer |
|||
{ |
|||
public: |
|||
GasPricer() = default; |
|||
virtual ~GasPricer() = default; |
|||
|
|||
virtual u256 ask(State const&) const = 0; |
|||
virtual u256 bid(TransactionPriority _p = TransactionPriority::Medium) const = 0; |
|||
|
|||
virtual void update(BlockChain const&) {} |
|||
}; |
|||
|
|||
class TrivialGasPricer: public GasPricer |
|||
{ |
|||
public: |
|||
TrivialGasPricer() = default; |
|||
TrivialGasPricer(u256 const& _ask, u256 const& _bid): m_ask(_ask), m_bid(_bid) {} |
|||
|
|||
void setAsk(u256 const& _ask) { m_ask = _ask; } |
|||
void setBid(u256 const& _bid) { m_bid = _bid; } |
|||
|
|||
u256 ask() const { return m_ask; } |
|||
u256 ask(State const&) const override { return m_ask; } |
|||
u256 bid(TransactionPriority = TransactionPriority::Medium) const override { return m_bid; } |
|||
|
|||
private: |
|||
u256 m_ask = 10 * szabo; |
|||
u256 m_bid = 10 * szabo; |
|||
}; |
|||
|
|||
} |
|||
} |
Loading…
Reference in new issue