Browse Source

really nice scientific gasPricer

cl-refactor
CJentzsch 10 years ago
parent
commit
e566a4f5c2
  1. 42
      libethereum/Client.cpp
  2. 153
      test/libethereum/BlockTestsFiller/bcGasPricerTestFiller.json
  3. 48
      test/libethereum/gaspricer.cpp

42
libethereum/Client.cpp

@ -24,6 +24,10 @@
#include <chrono>
#include <thread>
#include <boost/filesystem.hpp>
#include <boost/math/distributions/normal.hpp>
#include <boost/multiprecision/number.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <libdevcore/Log.h>
#include <libdevcore/StructuredLogger.h>
#include <libp2p/Host.h>
@ -83,6 +87,8 @@ void BasicGasPricer::update(BlockChain const& _bc)
map<u256, unsigned> dist;
unsigned total = 0;
// make gasPrice versus gasUsed distribution for the last 1000 blocks
while (c < 1000 && p)
{
BlockInfo bi = _bc.info(p);
@ -91,28 +97,44 @@ void BasicGasPricer::update(BlockChain const& _bc)
auto bb = _bc.block(p);
RLP r(bb);
BlockReceipts brs(_bc.receipts(bi.hash()));
for (unsigned i = 0; i < r[1].size(); ++i)
size_t i = 0;
for (auto const& tr: r[1])
{
Transaction tx(tr.data(), CheckTransaction::None);
auto gu = brs.receipts[i].gasUsed();
dist[Transaction(r[1][i].data(), CheckTransaction::None).gasPrice()] += (unsigned)brs.receipts[i].gasUsed();
dist[tx.gasPrice()] += (unsigned)gu;
total += (unsigned)gu;
i++;
}
}
p = bi.parentHash;
++c;
}
// fill m_octiles with weighted gasPrices
if (total > 0)
{
unsigned t = 0;
unsigned q = 1;
m_octiles[0] = dist.begin()->first;
// calc mean
u256 mean = 0;
for (auto const& i: dist)
{
for (; t <= total * q / 8 && t + i.second > total * q / 8; ++q)
m_octiles[q] = i.first;
if (q > 7)
break;
}
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;
double sd = sqrt(sdSquared.convert_to<double>());
double normalizedSd = 4.0 * sd / mean.convert_to<double>();
// calc octiles normalized to gaussian distribution
boost::math::normal gauss(4, normalizedSd ? normalizedSd : 1);
for (int i=1; i < 8; i++)
m_octiles[i] = mean / 4000 * int(boost::math::quantile(gauss, (double)i / 8) * 1000);
m_octiles[8] = dist.rbegin()->first;
}
}

153
test/libethereum/BlockTestsFiller/bcGasPricerTestFiller.json

@ -5,7 +5,7 @@
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "131072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasLimit" : "31415920",
"gasUsed" : "0",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
@ -24,7 +24,7 @@
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000",
"balance" : "9000000000000000000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
@ -40,9 +40,9 @@
{
"transactions" : [
{
"data" : "0xffffffffffffffffffffffff",
"gasLimit" : "85000",
"gasPrice" : "0",
"data" : "0xffffffffffff",
"gasLimit" : "850000",
"gasPrice" : "10000000000000",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
@ -55,10 +55,145 @@
{
"transactions" : [
{
"data" : "0xffffffffffff",
"gasLimit" : "85000",
"gasPrice" : "0",
"nonce" : "0",
"data" : "0xfffffffffffff",
"gasLimit" : "850000",
"gasPrice" : "12000000000000",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "0xffffffffffffff",
"gasLimit" : "850000",
"gasPrice" : "14000000000000",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "0xfffffffffffffff",
"gasLimit" : "850000",
"gasPrice" : "16000000000000",
"nonce" : "3",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "0xfffffffffffffffffffffffffffffff",
"gasLimit" : "850000",
"gasPrice" : "18000000000000",
"nonce" : "4",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "0xffffffffffffffffffffffffffffffff",
"gasLimit" : "850000",
"gasPrice" : "20000000000000",
"nonce" : "5",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "0xffffffffffffffffffffffffffffffff",
"gasLimit" : "850000",
"gasPrice" : "22000000000000",
"nonce" : "6",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "0xffffffffffffffffffffffffffffffff",
"gasLimit" : "850000",
"gasPrice" : "24000000000000",
"nonce" : "7",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "0xffffffffffffffffffffffffffffffff",
"gasLimit" : "850000",
"gasPrice" : "26000000000000",
"nonce" : "8",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "0xffffffffffffffffffffffffffffffff",
"gasLimit" : "850000",
"gasPrice" : "28000000000000",
"nonce" : "9",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "0xffffffffffffffffffffffffffffffff",
"gasLimit" : "850000",
"gasPrice" : "30000000000000",
"nonce" : "10",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"

48
test/libethereum/gaspricer.cpp

@ -33,7 +33,7 @@ using namespace dev::eth;
namespace dev { namespace test {
void executeGasPricerTest(const string name, double _etherPrice, double _blockFee, const string bcTestPath, u256 _expectedAsk, u256 _expectedBid)
void executeGasPricerTest(const string name, double _etherPrice, double _blockFee, const string bcTestPath, TransactionPriority _txPrio, u256 _expectedAsk, u256 _expectedBid)
{
cnote << name;
BasicGasPricer gp(u256(double(ether / 1000) / _etherPrice), u256(_blockFee * 1000));
@ -44,7 +44,7 @@ void executeGasPricerTest(const string name, double _etherPrice, double _blockFe
gp.update(bc);
BOOST_CHECK_EQUAL(gp.ask(State()), _expectedAsk);
BOOST_CHECK_EQUAL(gp.bid(), _expectedBid);
BOOST_CHECK_EQUAL(gp.bid(_txPrio), _expectedBid);
}
@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(trivialGasPricer)
std::shared_ptr<dev::eth::GasPricer> gp(new TrivialGasPricer);
BOOST_CHECK_EQUAL(gp->ask(State()), 10 * szabo);
BOOST_CHECK_EQUAL(gp->bid(), 10 * szabo);
gp->update(BlockChain(bytes(), string(), WithExisting::Kill));
gp->update(BlockChain(bytes(), TransientDirectory().path(), WithExisting::Kill));
BOOST_CHECK_EQUAL(gp->ask(State()), 10 * szabo);
BOOST_CHECK_EQUAL(gp->bid(), 10 * szabo);
}
@ -93,27 +93,53 @@ BOOST_AUTO_TEST_CASE(basicGasPricerNoUpdate)
BOOST_AUTO_TEST_CASE(basicGasPricer_RPC_API_Test)
{
dev::test::executeGasPricerTest("RPC_API_Test", 30.679, 15.0, "/BlockTests/bcRPC_API_Test.json", 155632494086, 155632494086);
dev::test::executeGasPricerTest("RPC_API_Test", 30.679, 15.0, "/BlockTests/bcRPC_API_Test.json", TransactionPriority::Medium, 155632494086, 155632494086);
}
BOOST_AUTO_TEST_CASE(basicGasPricer_bcValidBlockTest)
{
dev::test::executeGasPricerTest("SimpleTx", 30.679, 15.0, "/BlockTests/bcValidBlockTest.json", 155632494086, 155632494086);
dev::test::executeGasPricerTest("SimpleTx", 30.679, 15.0, "/BlockTests/bcValidBlockTest.json", TransactionPriority::Medium, 155632494086, 155632494086);
}
BOOST_AUTO_TEST_CASE(basicGasPricer_bcInvalidHeaderTest)
BOOST_AUTO_TEST_CASE(basicGasPricer_bcUncleTest)
{
dev::test::executeGasPricerTest("wrongUncleHash", 30.679, 15.0, "/BlockTests/bcInvalidHeaderTest.json", 155632494086, 155632494086);
dev::test::executeGasPricerTest("twoUncle", 30.679, 15.0, "/BlockTests/bcUncleTest.json", TransactionPriority::Medium, 155632494086, 155632494086);
}
BOOST_AUTO_TEST_CASE(basicGasPricer_bcUncleTest)
BOOST_AUTO_TEST_CASE(basicGasPricer_bcUncleHeaderValiditiy)
{
dev::test::executeGasPricerTest("twoUncle", 30.679, 15.0, "/BlockTests/bcUncleTest.json", 155632494086, 155632494086);
dev::test::executeGasPricerTest("correct", 30.679, 15.0, "/BlockTests/bcUncleHeaderValiditiy.json", TransactionPriority::Medium, 155632494086, 155632494086);
}
BOOST_AUTO_TEST_CASE(basicGasPricer_bcUncleHeaderValiditiy)
BOOST_AUTO_TEST_CASE(basicGasPricer_notxs)
{
dev::test::executeGasPricerTest("notxs", 30.679, 15.0, "/BlockTests/bcGasPricerTest.json", TransactionPriority::Medium, 155632494086, 155632494086);
}
BOOST_AUTO_TEST_CASE(basicGasPricer_highGasUsage_LowestPrio)
{
dev::test::executeGasPricerTest("highGasUsage", 30.679, 15.0, "/BlockTests/bcGasPricerTest.json", TransactionPriority::Lowest, 15731290119, 10000000000000);
}
BOOST_AUTO_TEST_CASE(basicGasPricer_highGasUsage_LowPrio)
{
dev::test::executeGasPricerTest("correct", 30.679, 15.0, "/BlockTests/bcUncleHeaderValiditiy.json", 155632494086, 155632494086);
dev::test::executeGasPricerTest("highGasUsage", 30.679, 15.0, "/BlockTests/bcGasPricerTest.json", TransactionPriority::Low, 15731290119, 15812460025839);
}
BOOST_AUTO_TEST_CASE(basicGasPricer_highGasUsage_MediumPrio)
{
dev::test::executeGasPricerTest("highGasUsage", 30.679, 15.0, "/BlockTests/bcGasPricerTest.json", TransactionPriority::Medium, 15731290119, 20072941956000);
}
BOOST_AUTO_TEST_CASE(basicGasPricer_highGasUsage_HighPrio)
{
dev::test::executeGasPricerTest("highGasUsage", 30.679, 15.0, "/BlockTests/bcGasPricerTest.json", TransactionPriority::High, 15731290119, 24328405650672);
}
BOOST_AUTO_TEST_CASE(basicGasPricer_highGasUsage_HighestPrio)
{
dev::test::executeGasPricerTest("highGasUsage", 30.679, 15.0, "/BlockTests/bcGasPricerTest.json", TransactionPriority::Highest, 15731290119, 30000000000000);
}
BOOST_AUTO_TEST_SUITE_END()

Loading…
Cancel
Save